var filterNavigation = {
	
	/*
		***************
		   OVERVIEW  
		***************
		
		1. Get hovered category
		2. Get products for hovered category
		3. build filter arrays
		4. build filter links
		5. Synchronize filters
		
		Top Nav {}
			getProducts()
				-> get products for hovered category [triggered on mouseover event for navBarDivs in DomReady]
				-> trigger processFilters()
			
			processFilters()
				-> controls functions that need to run AFTER products have been returned from storefront API
								
			filterProductsBy{filter}()
				-> limit the filter dataset to only include values from selected filters > sets up dependent filters
				
			setFilterValues()
				-> gets filter values from product data
				-> creates filter arrays > removes duplicates > sorts
				
			filterNavigation.buildFilters(filterName, filterTitle)
				-> builds filter links and inserts them into the DOM
				
			synchronizeFilters()
				-> identify currently selected filters from parameter values
		Left Nav {}
			getProducts()
				-> get products for hovered category [triggered on mouseover event for navBarDivs in DomReady]
				-> trigger processFilters()
			
			processFilters()
				-> controls functions that need to run AFTER products have been returned from storefront API
				
			filterProductsBy{filter}()
				-> limit the filter dataset to only include values from selected filters > sets up dependent filters				
				
			setFilterValues()
				-> gets filter values from product data
				-> creates filter arrays > removes duplicates > sorts
				
			filterNavigation.buildFilters(filterName, filterTitle)
				-> builds filter links and inserts them into the DOM
				
			synchronizeFilters()
				-> identify currently selected filters from parameter values
				
		uniqueArrayValues()
			-> remove duplicate array values
			
		
		***************
			UPDATES  
		***************
		
		Version 1.1 [9/29/2011]
		
		New Features: 
			* Dependent filter functionality has been added -> When a filter is clicked, only filters with product results will be displayed
	*/
	maxApiResults: 1000,
	categories: {},
	debug: new Array(),
	
	
	
	/* BEGIN topNav class */
	topNav: {
		categories: {},
		
		getProducts: function(){
			
			//skip API call if category is already loaded AND we are on initial page load (loading left nav)
			if(filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory]){			
				return false;
			}
			
				
			//Build storefront API url
			var url = filterNavigation.ApiUrl + "?category=" + filterNavigation.topNav.hoveredCategory + "&echo=name&echo=active&echo=attribute1values&echo=customtext2&echo=customtext3&count=" + filterNavigation.maxApiResults;
			
			//Post URL to storefront API and get results -> store JSON data in the filterNavigation object
			$.get(
				url, 
				function(data, textStatus) {
					
					//prepare response string for JSON -> remove block comment
					responseString = data.replace(/\/\*.+\*\//g, '');
					
					// this will give us an array of objects
					//var productData = JSON.parse(responseString);
					var productData = $.parseJSON(responseString);
					
					//init class
					filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory] = {};
					
					filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].fullList = productData.echo.results;
					filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].filteredList = filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].fullList
					
					
					//need to call function after filterNavigation load -> cannot call from outside of this function
					
					filterNavigation.topNav.processFilters();
				}, 
			'text');
		
			
		},

		//acts as a constructor -> called after products are returned from storefront API
		processFilters: function(){
		
			filterNavigation.topNav.filterProductsByColor();
			filterNavigation.topNav.filterProductsBySize();
			filterNavigation.topNav.filterProductsByThreadCount();

			filterNavigation.topNav.setFilterValues();
			
			filterNavigation.topNav.buildFilters('color', 'Color');
			filterNavigation.topNav.buildFilters('size', 'Size');
			filterNavigation.topNav.buildFilters('threadCount', 'Thread Count');	
			
			filterNavigation.topNav.synchronizeFilters();
		},
		
		
		//apply color filter (attribute2value)
		filterProductsByColor: function(){
						
			//search color (attribute1values) field for specified color
			var filteredList = new Array();
			$.each(filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].filteredList, function(key, value){
			
				//iterate through each value split by commas (remove square brackets)
				var colorSplit = value.attribute1values.replace('[', '').replace(']', '').split(',');
				$.each(colorSplit, function(key){
					if($.trim(colorSplit[key].toUpperCase()) == filterNavigation.color.toUpperCase()){
						filteredList.push(value);
					}
				});
			});
			
			//correction for filter = ALL
			if(filteredList.length == 0){
				return false;
			}
			
			filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].filteredList = filteredList;
		},
		
		
		//apply size filter (customtext3)
		filterProductsBySize: function(){
			
			//search size (customtext3) field for specified size
			var filteredList = new Array();
			$.each(filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].filteredList, function(key, value){			
				if($.trim(value.customtext3.toUpperCase()) == filterNavigation.size.toUpperCase()){
					//throw new Error(value.customtext3);
					filteredList.push(value);
				}
			});
			
			//correction for filter = ALL
			if(filteredList.length == 0){
				return false;
			}

			filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].filteredList = filteredList;			
		},
		
		
		//apply threadCount filter (customtex2)
		filterProductsByThreadCount: function(){
		
			//search threadCount (customtext2) field for specified thread count
			var filteredList = new Array();
			$.each(filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].filteredList, function(key, value){			
				
				if($.trim(value.customtext2.toUpperCase()) == filterNavigation.threadCount.toUpperCase()){
					filteredList.push(value);
				}
			});
			
			//correction for filter = ALL
			if(filteredList.length == 0){
				return false;
			}
			
			filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].filteredList = filteredList;			
		},
		
		
		
		//get unique attribute values -> build arrays with unique values
		setFilterValues: function(){
			
			//BEGIN Set filterNavigation.colorList
			var colorList = new Array();
			$.each(filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].filteredList, function(key, value){				
				//iterate through each value split by commas (remove square brackets)
				var colorSplit = value.attribute1values.replace('[', '').replace(']', '').split(',');
				$.each(colorSplit, function(key, value){
					//omit blank attribute values
					if($.trim(value)){
						//add item to colorlist
						colorList.push($.trim(value));
					}
				});
			});			
			
			//get unique array values
			filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].colorList = filterNavigation.uniqueArrayValues(colorList);
			
			//sort
			filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].colorList = filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].colorList.sort();
			//END Set filterNavigation.colorList
			
			
			//BEGIN Set filterNavigation.sizeList
			var sizeList = new Array();
			$.each(filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].filteredList, function(key, value){		
				//iterate through each value -> omit blank values
				if($.trim(value.customtext3)){
					sizeList.push($.trim(value.customtext3));
				}
			});			
			
			//get unique array values
			filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].sizeList = filterNavigation.uniqueArrayValues(sizeList);
			
			//sort
			filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].sizeList = filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].sizeList.sort();
			//END Set filterNavigation.sizeList
			
			
			//BEGIN Set filterNavigation.threadCountList
			var threadCountList = new Array();
			$.each(filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].filteredList, function(key, value){				
				//iterate through each value -> omit blank values
				if($.trim(value.customtext2)){
					threadCountList.push($.trim(value.customtext2));
				}
			});	
		
			//get unique array values
			filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].threadCountList = filterNavigation.uniqueArrayValues(threadCountList);
			
			//sort (numerically)
			filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].threadCountList = filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory].threadCountList.sort(function(a,b){return a - b});
			//END Set filterNavigation.threadCountList
		},
		
		
		//builds filter links and inserts them into the DOM
		buildFilters: function(filterName, filterTitle){		
			
			
			
			//if filter list has more than 0 items && first element in array is not blank
			if(filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory][filterName + 'List'].length > 0 && filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory][filterName + 'List'][0] != ''){			
				
				//set parameters to be appended to filter links
				var filterParams = {
					category: filterNavigation.topNav.hoveredCategory,			
					color: function(){
						//return ALL if value is empty OR if not hovering the active category -> keeps filters from carrying over to new categories
						return (filterNavigation.color && filterNavigation.topNav.hoveredCategory == filterNavigation.category) ? filterNavigation.color : 'ALL'; 
					},
					size: function(){
						//return ALL if value is empty OR if not hovering the active category -> keeps filters from carrying over to new categories
						return (filterNavigation.size && filterNavigation.topNav.hoveredCategory == filterNavigation.category) ? filterNavigation.size : 'ALL'; 
					},
					threadCount: function(){
						//return ALL if value is empty OR if not hovering the active category -> keeps filters from carrying over to new categories
						return (filterNavigation.threadCount && filterNavigation.topNav.hoveredCategory == filterNavigation.category) ? filterNavigation.threadCount : 'ALL'; 
					},
					sortBy: function(){
						//return NAMD if value is empty
						return (filterNavigation.sortBy) ? filterNavigation.sortBy : 'name'; 
					},
					numberOfProductsPerPage: filterNavigation.numberOfProductsPerPage
				};						
				
				// set selector -> identifies which DOM element to populate
				//by default selector = the currently hovered element -> filterNavigation element
				var selectorFind = '.filterNavigation_' + filterName;
				var selector = $(filterNavigation.topNav.hoveredElement).find(selectorFind);			
								

				//clear filter container
				selector.html('');
						
				//filter title
				selector.append("<dt>Shop By " + filterTitle + "</dt>"); 
				
				//All button (clear filter)		
				var reset_params = jQuery.extend(true, {}, filterParams); //clone filterParams object
				reset_params[filterName] = 'ALL';
				selector.append('<dd class="shopLink"><a href="' + filterNavigation.filterListUrl + '?' + $.param(reset_params) + '">ALL</a></dd>'); 
				
				//Add filter links to DOM
				$.each(filterNavigation.topNav.categories[filterNavigation.topNav.hoveredCategory][filterName + 'List'], function(key, value){
					var params = jQuery.extend(true, {}, filterParams); //clone filterParams object
					params[filterName] = value;
					var filterHref = filterNavigation.filterListUrl + '?' + $.param(params);
					//category parent chain display in filterHref -> %3A must be unencoded to : 
					selector.append('<dd class="shopLink"><a href="' + filterHref.replace('%3A', ':') + '">' + value + '</a></dd>'); 
				});	
				
				return true;
			}
			
			//hide DOM elements that have 0 filters
			$(filterNavigation.topNav.hoveredElement).find('.filterNavigation_' + filterName).hide();		
			
		},
		
		//identify currently selected filters from parameter values
		synchronizeFilters: function(){		
			
			//only syncronize filters for active category -> otherwise exit
			if(filterNavigation.topNav.hoveredCategory != filterNavigation.category){
				return false;
			}
			
			//finds exact match within content text search - extends jquery
			$.expr[':'].contentIs = function(el, idx, meta) {
				return $(el).text() === meta[3];
			};

			if(filterNavigation.color){
				$(filterNavigation.topNav.hoveredElement).find('.filterNavigation_color a:contentIs(' + filterNavigation.color + ')').addClass('filter_on');			
			}
			if(filterNavigation.size){
				$(filterNavigation.topNav.hoveredElement).find('.filterNavigation_size a:contentIs(' + filterNavigation.size + ')').addClass('filter_on');			
			}
			if(filterNavigation.threadCount){
				$(filterNavigation.topNav.hoveredElement).find('.filterNavigation_threadCount a:contentIs(' + filterNavigation.threadCount + ')').addClass('filter_on');			
			}
		
		}
	},
	/* END topNav object */
	
	
	/* BEGIN leftNav object */
	leftNav: {
	
		categories: {},
		
		getProducts: function(){
			
			//Build storefront API url
			var url = filterNavigation.ApiUrl + "?category=" + filterNavigation.category + "&echo=name&echo=active&echo=attribute1values&echo=customtext2&echo=customtext3&count=" + filterNavigation.maxApiResults;
			
			//Post URL to storefront API and get results -> store JSON data in the filterNavigation object
			$.get(
				url, 
				function(data, textStatus) {
					
					//prepare response string for JSON -> remove block comment
					responseString = data.replace(/\/\*.+\*\//g, '');
					
					// this will give us an array of objects
					//var productData = JSON.parse(responseString);
					var productData = $.parseJSON(responseString);
					
					//init class
					filterNavigation.leftNav.categories[filterNavigation.category] = {};
					
					filterNavigation.leftNav.categories[filterNavigation.category].fullList = productData.echo.results;
					filterNavigation.leftNav.categories[filterNavigation.category].filteredList = filterNavigation.leftNav.categories[filterNavigation.category].fullList;
					
					//need to call function after filterNavigation load -> cannot call from outside of this function					
					filterNavigation.leftNav.processFilters();
				}, 
			'text');
		},
		
		//acts as a constructor -> called after products are returned from storefront API
		processFilters: function(){
			
			filterNavigation.leftNav.filterProductsByThreadCount();			
			filterNavigation.leftNav.filterProductsBySize();			
			filterNavigation.leftNav.filterProductsByColor();			
			
			filterNavigation.leftNav.setFilterValues();			
			
			filterNavigation.leftNav.buildFilters('color', 'Color');
			filterNavigation.leftNav.buildFilters('size', 'Size');
			filterNavigation.leftNav.buildFilters('threadCount', 'Thread Count');		
			
			filterNavigation.leftNav.synchronizeFilters();
		},
		
		
		//apply threadCount filter (customtex2)
		filterProductsByThreadCount: function(){
			
			if(filterNavigation.threadCount == 'ALL'){
				return false;
			}
			
			
			//search threadCount (customtext2) field for specified thread count
			var filteredList = new Array();
			
			$.each(filterNavigation.leftNav.categories[filterNavigation.category].filteredList, function(key, value){			
				
				if($.trim(value.customtext2.toUpperCase()) == filterNavigation.threadCount.toUpperCase()){
					filteredList.push(value);
				}
			});
			
			
			//correction for filter = ALL
			if(filteredList.length == 0){ 
				return false;
			}
			
			filterNavigation.leftNav.categories[filterNavigation.category].filteredList = filteredList;			
		},
		
		
		//apply size filter (customtext3)
		filterProductsBySize: function(){
			
			//search size (customtext3) field for specified size
			var filteredList = new Array();
			$.each(filterNavigation.leftNav.categories[filterNavigation.category].filteredList, function(key, value){			
				if($.trim(value.customtext3.toUpperCase()) == filterNavigation.size.toUpperCase()){
					//throw new Error(value.customtext3);
					filteredList.push(value);
				}
			});
			
			//correction for filter = ALL
			if(filteredList.length == 0){
				return false;
			}
			

			filterNavigation.leftNav.categories[filterNavigation.category].filteredList = filteredList;			
		},
		
		
		//apply color filter (attribute2value)
		filterProductsByColor: function(){
		
		
			//search color (attribute1values) field for specified color
			var filteredList = new Array();
			$.each(filterNavigation.leftNav.categories[filterNavigation.category].filteredList, function(key, value){
			
				//iterate through each value split by commas (remove square brackets)
				var colorSplit = value.attribute1values.replace('[', '').replace(']', '').split(',');
				$.each(colorSplit, function(key){
					if($.trim(colorSplit[key].toUpperCase()) == filterNavigation.color.toUpperCase()){
						filteredList.push(value);
					}
				});
			});
			
			//correction for filter = ALL
			if(filteredList.length == 0){
				return false;
			}
			
			filterNavigation.leftNav.categories[filterNavigation.category].filteredList = filteredList;
		},
		
		
		//get unique attribute values -> build arrays with unique values
		setFilterValues: function(){
		
		
			//BEGIN Set filterNavigation.colorList
			var colorList = new Array();
			$.each(filterNavigation.leftNav.categories[filterNavigation.category].filteredList, function(key, value){		
				
				//iterate through each value split by commas (remove square brackets)
				var colorSplit = value.attribute1values.replace('[', '').replace(']', '').split(',');
				$.each(colorSplit, function(key, value){
				
					//omit blank values
					if($.trim(value)){
						//add item to colorlist
						colorList.push($.trim(value));
					}
				});
			});			
			
			//get unique array values
			filterNavigation.leftNav.categories[filterNavigation.category].colorList = filterNavigation.uniqueArrayValues(colorList);
			
			//sort
			filterNavigation.leftNav.categories[filterNavigation.category].colorList = filterNavigation.leftNav.categories[filterNavigation.category].colorList.sort();
			//END Set filterNavigation.colorList
			
			
			//BEGIN Set filterNavigation.sizeList
			var sizeList = new Array();
			$.each(filterNavigation.leftNav.categories[filterNavigation.category].filteredList, function(key, value){				
				//iterate through each value -> omit blank values
				if($.trim(value.customtext3)){
					sizeList.push($.trim(value.customtext3));
				}
			});			
			
			//get unique array values
			filterNavigation.leftNav.categories[filterNavigation.category].sizeList = filterNavigation.uniqueArrayValues(sizeList);
			
			//sort
			filterNavigation.leftNav.categories[filterNavigation.category].sizeList = filterNavigation.leftNav.categories[filterNavigation.category].sizeList.sort();
			//END Set filterNavigation.sizeList
			
			
			//BEGIN Set filterNavigation.threadCountList
			var threadCountList = new Array();
			$.each(filterNavigation.leftNav.categories[filterNavigation.category].filteredList, function(key, value){				
				//iterate through each value -> omit blank values
				if($.trim(value.customtext2)){
					threadCountList.push($.trim(value.customtext2));
				}
			});	

			//get unique array values
			filterNavigation.leftNav.categories[filterNavigation.category].threadCountList = filterNavigation.uniqueArrayValues(threadCountList);
			
			//sort (numerically)
			filterNavigation.leftNav.categories[filterNavigation.category].threadCountList = filterNavigation.leftNav.categories[filterNavigation.category].threadCountList.sort(function(a,b){return a - b});
			//END Set filterNavigation.threadCountList
		},
		
		
		//builds filter links and inserts them into the DOM
		buildFilters: function(filterName, filterTitle){		
			
			//if filter list has any items
			if(filterNavigation.leftNav.categories[filterNavigation.category][filterName + 'List'].length > 0){			
				
				//set parameters to be appended to filter links
				
				var filterParams = {
					category: filterNavigation.category,			
					color: function(){
						//return ALL if value is empty OR if not hovering the active category -> keeps filters from carrying over to new categories
						return (filterNavigation.color && filterNavigation.category == filterNavigation.category) ? filterNavigation.color : 'ALL'; 
					},
					size: function(){
						//return ALL if value is empty OR if not hovering the active category -> keeps filters from carrying over to new categories
						return (filterNavigation.size && filterNavigation.category == filterNavigation.category) ? filterNavigation.size : 'ALL'; 
					},
					threadCount: function(){
						//return ALL if value is empty OR if not hovering the active category -> keeps filters from carrying over to new categories
						return (filterNavigation.threadCount && filterNavigation.category == filterNavigation.category) ? filterNavigation.threadCount : 'ALL'; 
					},
					sortBy: function(){
						//return NAMD if value is empty
						return (filterNavigation.sortBy) ? filterNavigation.sortBy : 'name'; 
					},
					numberOfProductsPerPage: filterNavigation.numberOfProductsPerPage
				};						
				
				// set selector -> identifies which DOM element to populate
				var selector = $('.leftFilterNavigation_' + filterName);	

				//clear filter container
				selector.html('');
						
				//filter title
				selector.append("<dt>Shop By " + filterTitle + "</dt>"); 
				
				//All button (clear filter)		
				var reset_params = jQuery.extend(true, {}, filterParams); //clone filterParams object
				reset_params[filterName] = 'ALL';
				selector.append('<dd class="shopLink"><a href="' + filterNavigation.filterListUrl + '?' + $.param(reset_params) + '">ALL</a></dd>'); 
				
				//Add filter links to DOM
				$.each(filterNavigation.leftNav.categories[filterNavigation.category][filterName + 'List'], function(key, value){
					var params = jQuery.extend(true, {}, filterParams); //clone filterParams object
					params[filterName] = value;
					var filterHref = filterNavigation.filterListUrl + '?' + $.param(params);
					selector.append('<dd class="shopLink"><a href="' + filterHref.replace('%3A', ':') + '">' + value + '</a></dd>'); 
				});	
				
				return true;
			}
			
			//hide DOM elements that have 0 filters
			$('#columnOneInner').find('.leftFilterNavigation_' + filterName).hide();	
			
		},
		
		//identify currently selected filters from parameter values
		synchronizeFilters: function(){		
			
			//only syncronize filters for active category -> otherwise exit
			if(filterNavigation.category != filterNavigation.category){
				return false;
			}
			
			//finds exact match within content text search - extends jquery
			$.expr[':'].contentIs = function(el, idx, meta) {
				return $(el).text() === meta[3];
			};

			if(filterNavigation.threadCount){
				$('.leftFilterNavigation_threadCount').find('a:contentIs(' + filterNavigation.threadCount + ')').addClass('filter_on');					
			}
			if(filterNavigation.size){
				$('.leftFilterNavigation_size').find('a:contentIs(' + filterNavigation.size + ')').addClass('filter_on');			
			}
			if(filterNavigation.color){
				$('.leftFilterNavigation_color').find('a:contentIs(' + filterNavigation.color + ')').addClass('filter_on');			
			}		
		}
	},
	/* END leftNav object */
	
	//removes duplicate values from array
	uniqueArrayValues: function(origArr){
		var newArr = [],  
        origLen = origArr.length,  
        found,  
        x, y;  
  
		for ( x = 0; x < origLen; x++ ) {  
			found = undefined;  
			for ( y = 0; y < newArr.length; y++ ) {  
				if ( origArr[x] === newArr[y] ) {  
				  found = true;  
				  break;  
				}  
			}  
			if ( !found) newArr.push( origArr[x] );  
		}  
	   return newArr;  
	}
}
