//*-------------------------------------------------------------------
//*-------------------------------------------------------------------
//* Ref		Date		Developer		Comments
//* ------------------------------------------------------------------
//* CR337	14/09/10	Shaun Dennett 	Removed Hitbox code 
//*

// It is assumed that AJAX is supported in the web browser being used
var httpRequestSupported = true;

// The indicates to the server that the request is an AJAX one
var ajaxParameter = '&rt=ajax';

// The indicates to the server that the request is an AJAX one
var currentViewTemplate = '';

// Error message variables
var validationError = false;
var validationErrorMsg = "";

var TL = new TemplateLoader();
    TL.add("/templates/tcatFacetsTemplate.ajp");
    TL.add("/templates/facetsTemplate.ajp");
    TL.add("/templates/itemsTemplate.ajp");
    TL.add("/templates/gspItemsTemplate.ajp");
    TL.add("/templates/breadCrumbsTemplate.ajp"); 
    TL.add("/templates/paginationTemplate.ajp"); 
    TL.add("/templates/searchAndSortTemplate.ajp"); 
    TL.add("/templates/productViewTemplate.ajp"); 
    TL.add("/templates/pspSkeletonTemplate.ajp"); 
    TL.add("/templates/pplSkeletonTemplate.ajp"); 
    TL.add("/templates/pspSkeletonNoProductsTemplate.ajp"); 
    TL.add("/templates/tcatSkeletonTemplate.ajp"); 
    TL.add("/templates/gspSkeletonTemplate.ajp"); 
    TL.add("/templates/pageTitleTemplate.ajp"); 
    TL.add("/templates/gspPageTitleTemplate.ajp"); 
    TL.add("/templates/tcatPageTitleTemplate.ajp"); 
    TL.add("/templates/zoneContentNavTextTemplate.ajp"); 
    TL.add("/templates/zoneContentNavTextLinkTemplate.ajp"); 
    TL.add("/templates/zoneContentNavImageTemplate.ajp"); 
    TL.add("/templates/zoneContentNavImageLinkTemplate.ajp"); 
    TL.add("/templates/zoneContentNavHtmlTemplate.ajp"); 
    TL.add("/templates/zoneContentGspHeroContentTemplate.ajp"); 
    TL.add("/templates/zoneContentGspCustomTextPaneTemplate.ajp"); 
    TL.add("/templates/pplItemsTemplate.ajp"); 
    TL.add("/templates/zoneContentTcatContentTemplate.ajp"); 
    TL.add("/templates/moreOverlayTemplate.ajp"); 
    //TL.add("/templates/seeOffersLink.ajp");     TODO: Remove once confirmed see offers supported by Facets
    TL.add("/templates/errorMessageTemplate.ajp");     
    TL.add("/templates/productPromotions.ajp");
    TL.add("/templates/productSetItemsTemplate.ajp");
    TL.load();

// Navigation history handling
var navDestinationUrl;
var navUrlPath = '/webapp/wcs/stores/servlet/Navigate';
var navParams = ['lid','pn','ps','sid','sin','fid','rhi','rlo','rin','val','vid','st','storeId','catalogId','listId','mfv','txt','sfv','dfv','sfn','sinl','psl','pns','aspsp'];

//Move this to prevent JS load order issues during ajax deeplinking
var facetContext = new Object();

//HBX
var ev1;

 

$(function(){
    
    // on first page load close all the facets that aren't marked as selected by FH
    // except the category facet
   //$('#navigation_top_level #categories').removeClass('notExpanded');
  	$('#navigation_top_level .notExpanded').removeClass('open');
    
    //Hook the hashchange event - this event is generated by the jquery.ba-bbq plugin
    $(window).bind( 'hashchange', function(e)
    {
        //If the fragment has changed then attempt to navigate
        navigateToLocation(true);
    });
    
});
   

///////////////////////////////////////////////////////////
// Returns true if AJAX requests are supported by the 
// clients web browser.  Else false.
// On a true result, the object returned is an 
// Active-X XMLHTTP object.
//
// In Internet Explorer, you create an http object using 
// new ActiveXObject("Msxml2.XMLHTTP") or 
// new ActiveXObject("Microsoft.XMLHTTP") 
// depending on the version of MSXML installed. 
//
// In Mozilla and Safari (Gecko engine) you use 
// new XMLHttpRequest()
//
// IceBrowser is not supported in this code
//
// @return boolean
///////////////////////////////////////////////////////////
function isHttpRequestSupported() {

	if (window.XMLHttpRequest) {   
		// Test if the Gecko engine is running.  Gecko supports AJAX
		httpRequest = new XMLHttpRequest(); 
		if (httpRequest.overrideMimeType) { 
			httpRequest.overrideMimeType('application/json'); 
		} 
	} else if (window.ActiveXObject) { 
		// Test if an IE engine is running
		try { 
			httpRequest = new ActiveXObject("Msxml2.XMLHTTP"); 
		} catch (e) { 
			try { 
				httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); 
			} catch (e) {} 
		} 
	} 
	
	if (!httpRequest) { 
		httpRequestSupported = false;
	} 
	
	return httpRequest;
} // end function


///////////////////////////////////////////////////////////
// Makes a HTTP request back to the server given a URL.
//
// callbackFunction is a string value containing the name
// of a method to call when the HTTP request is completed.
// The resulting output of the HTTP request is passed in
// as a variable to the callback function.  The callback
// function formats the response to be displayed in 
// a web browser.
//
// if returnData is specified, the response is retruned
// in xml
//
// @param url
// @param callbackFunction
// @param returnData
///////////////////////////////////////////////////////////
function makeHttpRequest(url, callbackFunction, showTheOverlay, returnData) 
{ 

	var httpRequest = false; 
	
	// Exit if this function is not supported
	if (!httpRequestSupported) {
		return;  
	}
	
	// check if supported
	httpRequest = isHttpRequestSupported();
	
	if (!httpRequest) { 
		httpRequestSupported = false;
		return false; 
	} 
	
	if (showTheOverlay) {
		showOverlay('<span><img src="/images/loading.gif" /></span>');
    }
    
	// Map the response to the callback function
	httpRequest.onreadystatechange = function() { 
		if (httpRequest.readyState == 4) {       
			if (httpRequest.status == 200) { 
				if (returnData) { 
					eval(callbackFunction + '(httpRequest.responseXML)'); 
				} else { 
					eval(callbackFunction + '(httpRequest.responseText)'); 
				} 
			} else { 
				// TODO:  Keep this line commented in production.  The user will have no idea what this means.
				//alert('AJAX request status: ' + httpRequest.status); 
				eval(callbackFunction + '("")'); 
			} 
		} 
	} 
	
	httpRequest.open('GET', url, true); 
	httpRequest.send(null); 	
} // end function

	
	// showOverlay with specified message
	function showOverlay(message) {
	
		$('#body_content').block({ message: message, 
        						   timeout: 60000, 	
								   css:{top: '250px',
								   		left: '372px',
					 					width: '0px',
        								cursor: 'wait',
					 					border: ''},
								  		centerX: 0,
								  		centerY: 0,
								   overlayCSS:{opacity: '0.6',
						   					   backgroundColor: '#fff'}
								});
	}
	
	function hideOverlay() {
	   	$('#body_content').unblock(); 	
	}
	
	// show specified message
	function showMessage(message) {
	
			$.blockUI({ message: '<h1>'+message+'</h1>', 
						timeout: 1000,
						css: {left: '30%',
							  height: '65px'}, 
						overlayCSS:{opacity: '0.6',
						   			backgroundColor: '#fff'}
						}); 
	
	}

	// show specified error message
	function showErrorMessage(message) {
	
			$('#body_content').block({ message: message, 
								   css:{top: '250px',
								   		left: '204px',
					 					height: '105px',
					 					width: '400px',
        								cursor: 'wait',
        								cColor: '#000',
        								border: '2px solid #f00', 
        								backgroundColor:'#fff'},
								  		centerX: 0,
								  		centerY: 0,
								   overlayCSS:{opacity: '0.6',
						   		backgroundColor: '#fff'}
								});
						
			$('#ok').click(function() { 
            	$('#body_content').unblock(); 
        	}); 
			
	
	}
	
	// @param sInString	- string to strip whitespace from
	function trimString(sInString) {
		sInString = sInString.replace( /^\s+/g, "" );// strip leading
		return sInString.replace( /\s+$/g, "" );// strip trailing
	}

	// build psp
	function buildPsp(context) {

		if (context.navigation.totalResults == 0)
		{
			currentViewTemplate = '';
			buildPspNoProductsSkeleton(context);
			buildBreadCrumbs(context);
			buildPageTitle(context);
			buildBanners(context);
			scroll(0,0);
		}
		else
		{
			if (currentViewTemplate != 'psp')
			{
				buildPspSkeleton(context);
				currentViewTemplate = 'psp';
				scroll(0,0);
			}
			buildPagination(context);
			buildItems(context);
			buildBreadCrumbs(context);
			buildPageTitle(context);
			buildFacets(context);
		    buildProductPromotions(context);
			buildSearchAndSort(context);
			buildProductView(context);
			buildBanners(context);
		}
	
		//We now need to update a few div tag class names and ids namely:
        //<body id="psp"> and <body_panel>
        document.getElementsByTagName("body")[0].setAttribute("id","psp");
        document.getElementById("body_panel").setAttribute("class","body_panel");
        // need to set className for IE
        document.getElementById("body_panel").setAttribute("className","body_panel");
        
		hideDisplayLhn(context);
	}
	function buildPpl(context) {

		// maybe only call the skeleton functions if we know we've moved from 
		// a tcat page?
		if (context.navigation.totalResults == 0)
		{
			currentViewTemplate = '';
			buildPspNoProductsSkeleton(context);
			buildBreadCrumbs(context);
			buildPageTitle(context);
			buildBanners(context);
			scroll(0,0);
		}
		else
		{
			if (currentViewTemplate != 'ppl')
			{
				buildPplSkeleton(context);
				currentViewTemplate = 'ppl';
				scroll(0,0);
			}
			buildPplItems(context);
			buildBreadCrumbs(context);
			buildPageTitle(context);
			buildFacets(context);
			buildBanners(context);
		}
	
		//We now need to update a few div tag class names and ids namely:
        //<body id="psp"> and <body_panel>
        document.getElementsByTagName("body")[0].setAttribute("id","psp");
        
        hideDisplayLhn(context);
        
        // WORK ON CAROUSEL
		$('.infiniteCarousel table').attr('cellspacing','0');
		$('.infiniteCarousel').each(function(){
			var height = $('table tbody tr',this).eq(0).height();	
			$(this).css({height:(height+20)+'px'});
			$('table,tbody',this).css({height:height});
		});
		$('.infiniteCarousel').infiniteCarousel();

	}
	
	// hide/display LNH as necessary
	function hideDisplayLhn(context) {
 
        if (context.navigation.lhnToBeHidden){
                document.getElementById("body_panel").setAttribute("class","body_panel nonav_fullwidth");
                // need to set className for IE
                document.getElementById("body_panel").setAttribute("className","body_panel nonav_fullwidth");
        } else {
                document.getElementById("body_panel").setAttribute("class","body_panel");
                // need to set className for IE
                document.getElementById("body_panel").setAttribute("className","body_panel");
        }
	
	}
	
	// build tcat
	function buildTcat(context) {
	
		if (currentViewTemplate != 'tcat')
		{
			buildTcatSkeleton(context);
			currentViewTemplate = 'tcat';
			scroll(0,0);
		}
		buildBreadCrumbs(context);
		buildTCATPageTitle(context);
		buildTCATFacets(context);
		buildTcatContent(context);
		buildBanners(context);
		        
        //We now need to update a few div tag class names and ids namely:
        //<body id="tcat"> and <body_panel tcat>
        document.getElementsByTagName("body")[0].setAttribute("id","tcat");
        document.getElementById("body_panel").setAttribute("class","body_panel tcat");
        // need to set className for IE
        document.getElementById("body_panel").setAttribute("className","body_panel tcat");
        FSR.enabled=true; 
		
	}

	// build gsp
	function buildGsp(context) {

		buildGspSkeleton(context);
		currentViewTemplate = 'gsp';
		scroll(0,0);
		buildGspItems(context);
		buildBreadCrumbs(context);
		buildGspPageTitle(context);
		buildGspHeroContent(context);
		buildGspCustomTextPaneContent(context);
		buildFacets(context);
		buildBanners(context);
		        
        //We now need to update a few div tag class names and ids namely:
        //<body id="gsp"> and <body_panel>
        document.getElementsByTagName("body")[0].setAttribute("id","gsp");
        
        hideDisplayLhn(context);
		
	}
	// build psp_set
	function buildProductSet(context) {
	
		if (context.navigation.totalResults == 0)
			{
				currentViewTemplate = 'psp_set';
				buildPspNoProductsSkeleton(context);
				buildBreadCrumbs(context);
				buildPageTitle(context);
				buildBanners(context);
				scroll(0,0);
			}
		else{
				buildProductSetSkeleton(context);
				scroll(0,0);
				buildProductSetItems(context);
				buildPagination(context);
				buildBreadCrumbs(context);
				buildPageTitle(context);
				buildFacets(context);
				buildSearchAndSort(context);
				buildProductView(context);
				buildBanners(context);
		}
        //We now need to update a few div tag class names and ids namely:
        //<body id="gsp"> and <body_panel>
        document.getElementsByTagName("body")[0].setAttribute("id","psp_set");
        
		hideDisplayLhn(context);
		
	}
	// build gsp skeleton
	function buildProductSetSkeleton(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("body_content");
  		
  		// replace object with the new items
  		outputArea.innerHTML = getTemplate("/templates/ProductSetSkeletonTemplate.ajp").process(context);

	}
	
	// build gsp skeleton
	function buildGspSkeleton(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("body_content");
  		
  		// replace object with the new items
  		outputArea.innerHTML = getTemplate("/templates/gspSkeletonTemplate.ajp").process(context);

	}
	
	// build psp skeleton
	function buildPspSkeleton(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("body_content");
	   	//deleteChildren(outputArea);
  		
  		// replace object with the new items
  		outputArea.innerHTML = getTemplate("/templates/pspSkeletonTemplate.ajp").process(context);

	}
	
	// build psp skeleton
	function buildPplSkeleton(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("body_content");
	   	//deleteChildren(outputArea);
  		
  		// replace object with the new items
  		outputArea.innerHTML = getTemplate("/templates/pplSkeletonTemplate.ajp").process(context);

	}
	
	// build psp skeleton
	function buildPspNoProductsSkeleton(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("body_content");

  		// replace object with the new items
  		outputArea.innerHTML = getTemplate("/templates/pspSkeletonNoProductsTemplate.ajp").process(context);

	}
	
	// build tcat skeleton
	function buildTcatSkeleton(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("body_content");
	   	//deleteChildren(outputArea);
  		
  		// replace object with the new items
  		outputArea.innerHTML = getTemplate("/templates/tcatSkeletonTemplate.ajp").process(context);

	}
	
	// build items
	function buildProductPromotions(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("product_promotions");

		if (outputArea) {
		
	  		// replace object with the new items
	 		outputArea.innerHTML = getTemplate("/templates/productPromotions.ajp").process(context);
	
			// apply event handlers to new items... taken from main.js
			$('.product_detail').mouseover(function() {
				$(this).addClass('highlight');
			});
			$('.product_detail').mouseout(function() {
				$(this).removeClass('highlight');
			});
		}
	}
	
	// build items
	function buildItems(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("product_results");

  		// replace object with the new items
 		outputArea.innerHTML = getTemplate("/templates/itemsTemplate.ajp").process(context);

		// apply event handlers to new items... taken from main.js
		$('.product_detail').mouseover(function() {
			$(this).addClass('highlight');
		});
		$('.product_detail').mouseout(function() {
			$(this).removeClass('highlight');
		});
	}
	
	// build gsp items
	function buildGspItems(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("cat_results");

  		// replace object with the new items
 		outputArea.innerHTML = getTemplate("/templates/gspItemsTemplate.ajp").process(context);

		// apply event handlers to new items... taken from main.js
		$('.cat_detail').mouseover(function() {
			$(this).addClass('highlight');
		});
		$('.cat_detail').mouseout(function() {
			$(this).removeClass('highlight');
		});
	}
	// build product set items
	function buildProductSetItems(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("cat_results");

  		// replace object with the new items
 		outputArea.innerHTML = getTemplate("/templates/productSetItemsTemplate.ajp").process(context);

		// apply event handlers to new items... taken from main.js
		$('.cat_detail').mouseover(function() {
			$(this).addClass('highlight');
		});
		$('.cat_detail').mouseout(function() {
			$(this).removeClass('highlight');
		});
	}
	// build ppl items
	function buildPplItems(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("product_results");

  		// replace object with the new items
  		outputArea.innerHTML = getTemplate("/templates/pplItemsTemplate.ajp").process(context);

		// apply event handlers to new items... taken from main.js
		$('.product_detail').mouseover(function() {
			$(this).addClass('highlight');
		});
		$('.product_detail').mouseout(function() {
			$(this).removeClass('highlight');
		});
	}
	
	// build banner
	function buildBanners(context) {
	
			buildBanner(context, "lhn_top_banner", "nav_banner");
			buildBanner(context, "event_banner", "top_banner");
			buildBanner(context, "top_pane_banner", "search_banner");
			buildBanner(context, "lhn_bottom_banner", "nav_bottom_banner");
			buildBanner(context, "bottom_pane_banner", "content_bottom_banner");
	
	}
	
	// build banner
	function buildBanner(context, zone, elementById) {
	
		var content = context.zonedContent[zone];
		
		if (content != null && content.length > 0) {
		
			// find the object to be replaced
	  	 	var outputArea = document.getElementById(elementById);
	  	 	
	  	 	if (outputArea != null) {
	  	 	
		  		// replace object with the new items	  		
		  		if (content[0].type == 'NavText')
		  		{
		  			content[0].properties['spanClass'] = 'dark'; 
			  		outputArea.innerHTML = getTemplate("/templates/zoneContentNavTextTemplate.ajp").process(content[0] );
		  		}
		  		else if (content[0].type == 'NavTextLink')
		  		{
		  			content[0].properties['spanClass'] = 'dark'; 
			  		outputArea.innerHTML = getTemplate("/templates/zoneContentNavTextLinkTemplate.ajp").process(content[0] );
		  		}
		  		else if (content[0].type == 'NavImage')
		  		{
			  		outputArea.innerHTML = getTemplate("/templates/zoneContentNavImageTemplate.ajp").process(content[0] );
		  		}
		  		else if (content[0].type == 'NavImageLink')
		  		{
			  		outputArea.innerHTML = getTemplate("/templates/zoneContentNavImageLinkTemplate.ajp").process(content[0] );
		  		}
		  		else if (content[0].type == 'NavHtml')
		  		{
			  		outputArea.innerHTML = getTemplate("/templates/zoneContentNavHtmlTemplate.ajp").process(content[0] );
		  		}
		  		
				// find the object to be replaced
		  	 	var outputArea = document.getElementById(elementById);
			   	
		  		// show the div
		  		$(outputArea).removeClass('no_display');
	  	 	}
	  	} 
	  	else
	  	{
			// find the object to be replaced
	  	 	var outputArea = document.getElementById(elementById);
		   	
	  		// show the div
	  		$(outputArea).addClass('no_display');
	  	}
	
	}
	
	// build banner
	function buildTcatContent(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("tcat_content");
	   	
  		// replace object with the new items
  		outputArea.innerHTML = getTemplate("/templates/zoneContentTcatContentTemplate.ajp").process(context);

	}
	
	// build gsp hero content
	function buildGspHeroContent(context) {
		//DSA-84 banner surround always shown need to check before we build it. 
		// find the object to be replaced
		
		if (context.zonedContent['gallery_hero']!= null) {
		   	var outputArea = document.getElementById("herobox");
		   	var heroContent = getTemplate("/templates/zoneContentGspHeroContentTemplate.ajp").process(context);
		   	//If the template content is empty or null then remove the hero div and do not output the code
			if(heroContent!=null && jQuery.trim(heroContent) !=""){
		  		// replace object with the new item
		  		outputArea.innerHTML = heroContent
			}else{
				//remove the div
				outputArea.parentNode.removeChild(outputArea);
			}
		}
	}
	
	// build gsp custom text pane content
	function buildGspCustomTextPaneContent(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("custom_text_panel");
	   	
  		// replace object with the new item
  		outputArea.innerHTML = getTemplate("/templates/zoneContentGspCustomTextPaneTemplate.ajp").process(context);

	}
	
	// build search and sort
	function buildSearchAndSort(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("product_header");
	   	
  		// replace object with the new items
  		outputArea.innerHTML = getTemplate("/templates/searchAndSortTemplate.ajp").process(context);
	}
	
	// The callback method for navigateToPage function
	function navigateToPageCallback(jsonObject) { 

		var context = eval('(' + jsonObject + ')');

		if (context.navigation.viewTemplateId == 'error')
		{
			displayErrorMessage(context);
			return;
		}
		buildBreadCrumbs(context);	
		buildPagination(context);
		if (context.navigation.viewTemplateId != 'psp_set')
		{
			buildProductPromotions(context);
		}
		if (context.navigation.viewTemplateId == 'psp_set')
		{
			buildProductSetItems(context);
		}
		else
		{
			buildItems(context);
		}
		//CR-318 WM Enhacements - page title added to update page number while pagination
		buildPageTitle(context);
		buildProductView(context);
		
		setUpHBXtags(context);

        // HIDE the overlay:
        hideOverlay();
		
		setNavLocation(navDestinationUrl);
	}

	// Goto to selected page of items
	// @param object	- the calling object 
	// @param pageUrl	- the current locationId
	function navigateToPage(object, url)
	{ 	
		//Set the destination - this is used to control url location changes triggered by 'hashchange' events
		navDestinationUrl = url;
		makeHttpRequest(url + ajaxParameter, 'navigateToPageCallback', true);	
	}
	
	// build facets
	function buildFacets(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("navigation_top_level");
	   
	    if (outputArea != null)
	    {
	    	// save any facets that are expanded
	   		var allOpenFacets = getElementsByClassName(outputArea, "open");
	   	
  			// update new facets with the old facets expanded status
  			// i.e. keeping the expanded status 'sticky'
	   		for ( var i=0;i<context.navigation.facets.length;i++ ) {
	   			var newElement = context.navigation.facets[i];
	   			if (containsId(allOpenFacets, newElement.id)) {
	   				newElement.expanded = true;
	   			} else {
	   				newElement.expanded = false;
	   			}
	   		}
	   					
  			// replace object with the new items
	  		outputArea.innerHTML = getTemplate("/templates/facetsTemplate.ajp").process(context);
	    }
	  	
	  	applyFacetEvents("");
	  	
	}
	
	// build facets
	function applyFacetEvents(facetId) {
	
	  	//See offers link is not in scope fo PSPs. So we need to remove any residue that is here
	  	//from an ajax page refresh
 		 		
		// apply event handlers to new items... taken from main.js
		// left hand navigation
		// upon click on navigation list item
		// perform switch - if child list open it
		// if no child list look for a tag and launch href
		if (facetId != "")
		{
			$('ul.navigation li#'+facetId+' a.facet_title.').click(function() {
				if($(this).parent().find('ul').length > 0) {
					$(this).parent().toggleClass('open');
					return false;
				}
			});
			$('.custom_checkbox input[type=checkbox]').addClass('no_display');
			$('.custom_checkbox li#'+facetId).click(function() {
				$(this).toggleClass('selected');
				handleSelection();
				return false;
			});
			$('.custom_checkbox li#'+facetId).keypress(function(e) {
				if(e.which == 13 || e.which == 32) { $(this).toggleClass('selected'); handleSelection(); return false; }
			});
		}
		else
		{
			$('ul.navigation li a.facet_title').click(function() {
				if($(this).parent().find('ul').length > 0) {
					$(this).parent().toggleClass('open');
					return false;
				}
			});
			$('.custom_checkbox input[type=checkbox]').addClass('no_display');
			$('.custom_checkbox li').click(function() {
				$(this).toggleClass('selected');
				handleSelection();
				return false;
			});
			$('.custom_checkbox li').keypress(function(e) {
				if(e.which == 13 || e.which == 32) { $(this).toggleClass('selected'); handleSelection(); return false; }
			});
	
		}
	}
	
	// build BreadCrumbs
	function buildBreadCrumbs(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("breadcrumb");
	   	
  		// replace object with the new items
 		outputArea.innerHTML = getTemplate("/templates/breadCrumbsTemplate.ajp").process(context);

	}
		
	// build Page Title
	function buildPageTitle(context) {
	
		// find the div that displays the page title
		outputArea = document.getElementById("page_header");
	   	
  		// replace object with the new items
  		outputArea.innerHTML = getTemplate("/templates/pageTitleTemplate.ajp").process(context);		

		/* facet selections more tooltip */
		if(/MSIE 6/i.test(navigator.userAgent)) {
                $("#products_found").hover(function(){$(this).addClass('hovered');},function(){$(this).removeClass('hovered');});
                $('#products_found_tooltip_html').bgiframe();
		}
	}

	// build GSP Page Title
	function buildGspPageTitle(context) {
	
		// find the div that displays the page title
		outputArea = document.getElementById("page_header");
	   	
  		// replace object with the new items
  		outputArea.innerHTML = getTemplate("/templates/gspPageTitleTemplate.ajp").process(context);		

		/* facet selections more tooltip */
		if(/MSIE 6/i.test(navigator.userAgent)) {
                $("#products_found").hover(function(){$(this).addClass('hovered');},function(){$(this).removeClass('hovered');});
                $('#products_found_tooltip_html').bgiframe();
		}
	}

	// build TCAT Page Title
	function buildTCATPageTitle(context) {
	
		// find the div that displays the page title
		outputArea = document.getElementById("page_header");
	   	
  		// replace object with the new items
  		outputArea.innerHTML = getTemplate("/templates/tcatPageTitleTemplate.ajp").process(context);		

	}
	
	// build Pagination
	function buildPagination(context) {
	
		// find the two objects to be replaced 
	   	var outputAreas = getElementsByClassName(document, "product_nav");
	   	
  		// replace the two objects with the new items
  		context.productViewPosition = 'TOP';
  		var paginationHTML = getTemplate("/templates/paginationTemplate.ajp").process(context);
  		outputAreas[0].innerHTML = paginationHTML;
  		context.productViewPosition = 'BOTTOM';
  		var paginationHTML = getTemplate("/templates/paginationTemplate.ajp").process(context);
  		outputAreas[1].innerHTML = paginationHTML;

		// apply event handlers to new items... taken from main.js
	}
	
	// build Product View
	function buildProductView(context) {
	
		// find the two objects to be replaced 
	   	var outputAreas = getElementsByClassName(document, "product_view");
	   	
  		// replace the two objects with the new items
  		context.productViewPosition = 'TOP';
  		var paginationHTML = getTemplate("/templates/productViewTemplate.ajp").process(context);
  		outputAreas[0].innerHTML = paginationHTML;
  		context.productViewPosition = 'BOTTOM';
  		var paginationHTML = getTemplate("/templates/productViewTemplate.ajp").process(context);
  		outputAreas[1].innerHTML = paginationHTML;

		// apply event handlers to new items... taken from main.js
	}
	
	// Build Merchandised Product Row
	function buildMerchandisedProductRow(context) {
	
		// find the two objects to be replaced 
	   	var outputAreas = getElementsByClassName(document, "product_view");
	   	
  		// replace the two objects with the new items
  		context.productViewPosition = 'TOP';
  		var paginationHTML = getTemplate("/templates/productViewTemplate.ajp").process(context);
  		outputAreas[0].innerHTML = paginationHTML;
  		context.productViewPosition = 'BOTTOM';
  		var paginationHTML = getTemplate("/templates/productViewTemplate.ajp").process(context);
  		outputAreas[1].innerHTML = paginationHTML;

		// apply event handlers to new items... taken from main.js
	}
	
	// Goto to selected facet
	// @param object	- the calling object 
	// @param url	- the current locationId
	function navigate(object, url) 
	{	
		//Set the destination - this is used to control url location changes triggered by 'hashchange' events
		navDestinationUrl = url;
		makeHttpRequest(url + ajaxParameter, 'navigateCallback', true);
	}
	
	
	// Goto to selected facet
	// @param object	- the calling object 
	// @param pageUrl	- the current locationId
	function showAll(object, url) 
	{	
		makeHttpRequest(url + ajaxParameter, 'showAllCallback', true);
	}
	
	
        //Check if the query object is empty
        function isEmpty(o1)
        {
                for (p in o1)
                {
                        if (o1.hasOwnProperty(p))
                                return false;
                }

                return true;
        }
        
        //Check if the query object is empty
        function isValid(o1)
        {
                return (o1.hasOwnProperty('lid'));
        }
        

        //Shallow compare the two query objects
        //Return true if identical
        function compareQueries(o1,o2)
        {
                var o2count = 0;
                for (p in o2)
                {
                        if (o2.hasOwnProperty(p))
                                o2count++;
                }

                var o1count = 0;
                for (p in o1)
                {
                        if (o1.hasOwnProperty(p))
                                if (o1[p] != o2[p] || o1count++ > o2count)
                                        return false;
                }

                var result = (o1count == o2count ? true : false);
                return result;
        }

        //Combine two query objects
        //Push the elements of object 2 in to object 1
        function combineQueries(o1,o2)
        {
                for (p in o2)
                {
                        o1[p] = o2[p];
                }
        }

        //Clean query objects
        function cleanQuery(o1)
        {
                for (p in o1)
                {
                        if (!(p in oc(navParams)))
                                 delete o1[p];
                }                
                return o1;
        }


        //Remove identical element from a query object to leave the difference of the two queries
        //Remove identical elements present in object 2 from object 1
        function diffQueries(o1,o2)
        {
                for (p in o2)
                {
                        if (o1[p] == o2[p])
                            delete o1[p];
                }
        }

        function oc(a)
        {
           var o = {};
           for(var i=0;i<a.length;i++)
           {
             o[a[i]]='';
           }
           return o;
        }

	
        /*
                Navigate based on the current document location and destination (set by a navigate request)

                This checks the current destination against the location and
                determines if a navigate should occur. This is triggered by any change to
                the fragment in the location URL - such as when using the browser history
        */
        function navigateToLocation(isUrlChange)
        {
                //Create a param object for the static params
                var navStaticQueryElements = cleanQuery($.deparam.querystring());

                //Create the dynamic location query
                var navDynamicQueryElements = cleanQuery($.deparam.fragment());
                
                var navTargetQueryElements;

                //If there is no query then use the base query which was the entry point to this navigation
                if (isEmpty(navDynamicQueryElements) && isEmpty(navStaticQueryElements) && isUrlChange)
                {
                        navTargetQueryElements = cleanQuery($.deparam.querystring(navBaseUrl));
                } else
                {
                		navTargetQueryElements = isEmpty(navDynamicQueryElements) ? navStaticQueryElements : navDynamicQueryElements;
                } 

                //Target location query
                var navDestinationQueryElements = cleanQuery($.deparam.querystring(navDestinationUrl));
                //cleanQuery(navCurrentQueryElements);

                var navQuery = $.param.querystring(navUrlPath,navTargetQueryElements);
                if (!compareQueries(navTargetQueryElements,navDestinationQueryElements))
                {
                        navigate(this, navQuery);
                }
        }
	
	
	// The callback method for navigate function
	function navigateCallback(jsonObject) { 
		FSR.enabled=false; 
		if(jsonObject == "")
		{	
			displayErrorMessage(null);
			return;
		}
		var context = eval('(' + jsonObject + ')');		
		if (context.navigation.redirectURL != null &&  context.navigation.redirectURL != "")
		{
		    window.location = context.navigation.redirectURL;
			return;
		}
		else if (context.navigation.viewTemplateId.indexOf('psp_set') != -1)
		{
			buildProductSet(context);
		}
		else if (context.navigation.viewTemplateId.indexOf('psp') != -1)
		{
			buildPsp(context);
		}
		else if (context.navigation.viewTemplateId == 'tcat')
		{
			buildTcat(context);
		}		
		else if (context.navigation.viewTemplateId.indexOf('_ppl') != -1)
		{
			buildPpl(context);
		}		
		else if (context.navigation.viewTemplateId.indexOf('gallery') != -1)
		{
			buildGsp(context);
		}		
		else if (context.navigation.viewTemplateId == 'error')
		{
			displayErrorMessage(context);
			return;
		}		
				
		// HIDE the overlay:
       	hideOverlay();

		//Set the window title
		document.title = context.navigation.windowTitleUnescaped;
		setUpHBXtags(context);
		facetContext.baseURL = context.navigation.baseNavUrl + '&lid=' + fixEscape(context.navigation.currentLocationId);
		facetContext.psValue = context.navigation.pageSizeParameter;
		facetContext.sidValue = context.navigation.currentSortParam;
		FSR.run(); 
		setNavLocation(navDestinationUrl);
	}
	
	// The callback method for showAll function
	function showAllCallback(jsonObject) { 

		var context = eval('(' + jsonObject + ')');	
			
		// HIDE the overlay:
       	hideOverlay();

		if (context.navigation.viewTemplateId == 'error')
		{
			displayErrorMessage(context);
			return;
		}
				
		if (!context.navigation.facet.multiSelect)
		{
			// find the object to be replaced
	   		var outputArea = document.getElementById(context.navigation.facet.id);
	   		
  			// replace object with the new items
 			outputArea.innerHTML = getTemplate("/templates/facetTemplate.ajp").process(context);
 			
 			applyFacetEvents(context.navigation.facet.id);
 			
		}
		else
		{
			var moreDIV = document.getElementById('showAllContent');
			if (moreDIV === null){		
				moreDIV = document.createElement('div');
			}	
			var moreDIVInnerHTML = getTemplate("/templates/moreOverlayTemplate.ajp").process(context);
					
			facetContext.selectedFacetId = context.navigation.facet.id;		

			moreDIV.setAttribute('id','showAllContent');
			moreDIV.setAttribute('class','showAllContent modal-colours'); //IE
			moreDIV.setAttribute('className','showAllContent modal-colours'); //IE
	//		moreDIV.setAttribute('style','display: block;');
		
			moreDIV.innerHTML = moreDIVInnerHTML;
		
			document.body.appendChild(moreDIV);
			$('.custom_checkbox li').click(function() {
				$(this).toggleClass('selected');				
				return false;
			});
		
			cmmodal = $('.showAllContent').modal({'zIndex':1600}); 

		}

	}
	
	/*
		Set the navigation location based on the target URL.		
		Any refinements to the initial location are written in the URL as a fragment.
	*/
      function setNavLocation(url)
      {
                //Create a param object for the static params
                var navStaticQueryElements = cleanQuery($.deparam.querystring());                

                //Create the current location query
                var navDynamicQueryElements = $.deparam.fragment();

                //Target location query
                var navTargetQueryElements = cleanQuery($.deparam.querystring(url));
                //cleanQuery(navTargetQueryElements);

                var newLocation;
                var navBaseQueryElements = cleanQuery($.deparam.querystring(navBaseUrl));

                if(compareQueries(navBaseQueryElements,navTargetQueryElements))
                {
                      newLocation = window.location.href.split('#')[0];
                } else
                {
                      newLocation = $.param.fragment(window.location.href,navTargetQueryElements,2);
                      window.location.href = newLocation;
                }
        }

	function getElementsByClassName(node, classname) {
	
    	var a = [];
    	if (node != null)
    	{
    		var re = new RegExp('\\b' + classname + '\\b');
    		var els = node.getElementsByTagName("*");
    		for(var i=0,j=els.length; i<j; i++)
       			if(re.test(els[i].className))
       				a.push(els[i]);
    	}
    	return a;
	}
	
	function containsId(a, obj) {
	  var index = a.length;
	  while (index--) {
	    if (a[index].id === obj) {
	      return true;
	    }
	  }
	  return false;
	}
	
	function validateSearchInSearch() {
	
		validationError = false;
    	var txt = document.getElementById("product_search_field");
    	var searchText = document.getElementById("searchText");
    	var sin = document.getElementById("category");
    	
    	var searchQuery = "";
    	
		if ((txt.value == "" || trimString(txt.value) == "") && searchText.innerHTML == "")
		{
			validationError = true;
    	}
		else if (sin.value == "separator")
		{
			validationError = true;
		}
		
		return !validationError;
	}
	
	function getSearchText() {
    	var searchQuery = "";

		if (validateSearchInSearch()) {
			var txt = document.getElementById("product_search_field");
	    	var searchText = document.getElementById("searchText");
	    	
			if(!(txt.value == "" || trimString(txt.value) == "")) {
				searchQuery = txt.value;
			}else if(searchText.innerHTML != "") {
				searchQuery = searchText.innerHTML;
			}
		}
		
		return searchQuery;
	}
	
	// used to encode '+' otherwise a space will be sent
	function fixEscape(str)
	{
		return escape(str).replace( /\+/g, "%2B" );
	}
	
	function selectContent(content, zone, types)
	{
		var results = new Array();
		if (null == content[zone])
		{
			return results;
		}
		
		var	_types = types.split(",");
		for (var i=0; i< content[zone].length; i++)
		{
			if (isType(content[zone][i],_types))
			{
				results.push(content[zone][i]);
			}
		}
		
		return results;
	}
	
	function isType(contentItem, types)
	{
		for (var i=0; i < types.length; i++)
		{
			if (types[i] == contentItem.type)
				return true;
		}
		
		return false;
	}
	

function getTemplate(templateName)
{
  var template = TL.getPreLoaded(templateName);
  if ( template == undefined ) value = "Error. Template '"+templateName+"' is not preloaded."; 
	
  return template;
}
	
function deleteChildren(node)
{
  if(node)
  {
    for(var x = node.childNodes.length - 1; x >= 0; x--)
    {
      var childNode = node.childNodes[x];
      if(childNode.hasChildNodes())
      {
        deleteChildren(childNode);
      }
    
      node.onlick=null;
      node.removeChild(childNode);
  
      if(childNode.outerHTML)
      {
        // legal?
        childNode.outerHTML = '';
      }
      childNode=null;   
    }
    node=null;
  }
}

//Validates the price range form prior to called the navigate object
	//If the validate fails then set the error message otherwise call navigate
	function validatePriceRangeForm(object, url){
		//Set message text values
		var enterValuesMsg = "Please enter a price range to use this feature.";
		var enterValidValuesMsg = "Please enter only numerical characters in the price boxes.";
		var rangeInvalidMsg = "The 'from' price must be lower than the 'to' price.";		
		var isRangeValid = true;
		var pattern = /^\d+.?\d*$/;
				
		//Get the elements we want to validate
		var fromField = document.getElementById('from');
		var toField = document.getElementById('to');
		//Get the error area so we can write to it
		var errorArea = document.getElementById('facet-error');

		//Check to see of the user has entered values in the fields
		if (( priceTrim(fromField.value) === "") || ( priceTrim(toField.value) === "")){
			//Issue the first message
			errorArea.innerHTML = enterValuesMsg;
			isRangeValid = false;
			return false;
		}

		//Remove the £ if it is present and validate the rest as number.
		//If not then issue error to the user. 
		if (fromField.value.indexOf('£') != -1 && fromField.value.length > 1){
			fromField.value = fromField.value.substring(1);
		}		
		if (toField.value.indexOf('£') != -1 && toField.value.length > 1){
			toField.value = toField.value.substring(1);
		}
		//Now we can check if the values are valid
		if (fromField.value.match(pattern) && toField.value.match(pattern)){
			fromField.value = new Number(parseFloat(fromField.value)).toFixed(2);
			toField.value = new Number(parseFloat(toField.value)).toFixed(2);
			
			//The numbers are valid so format to 2 decimal places
			//Check to see if the to value is greater than the from value
			if (parseFloat(fromField.value) >= parseFloat(toField.value)){
				errorArea.innerHTML = rangeInvalidMsg;
				isRangeValid = false;
				return false;				
			}			
		} else {
 			errorArea.innerHTML = enterValidValuesMsg;
			isRangeValid = false;
			return false;
		}

		//If the range is valid then issue the request to the server and reset the message area
		if (isRangeValid == true){		 
			errorArea.innerHTML = "";
			//Before sending add the values to the url as they may have been converted
			url = url+'&rhi='+toField.value+'&rlo='+fromField.value;
			navigate(object,url);			
		}
	}
		//Need to check if there is another funciton already availale
	function priceTrim(stringToTrim) {
		return stringToTrim.replace(/^\s+|\s+$/g,"");
	}
	
	


  function setUpHBXtags(context)
  {
  		//Set the necessary values for other HBX tags
  		
  		var pn = context.navigation.fhHbxAdaptor.pn;
  		var mlc = eval(context.navigation.fhHbxAdaptor.mlc);
		
	    setUpTagMan(context,pn,mlc);
	    // sc_trackPageView(pn,mlc);
	    
  }
  
    function setUpTagMan(context,pn,mlc)
  {
  		//Set the necessary values for other HBX tags
  		
  		
  		writeTagData("page.name",context.navigation.fhHbxAdaptor.pn);
  		tagDataPopulateNavigation(context.navigation.fhHbxAdaptor.tagLabel);
		writeTagData("page.url",location.href);
		
		
		tmParam["page_type"] = getTagPageType();
	    tmParam["web_vortal"] = getTagWeb_Vortal(context.navigation.fhHbxAdaptor.pn);
	    tmParam["web_category"] = getTagWeb_Category(context.navigation.fhHbxAdaptor.pn);
	    tmParam["web_sub_category"] = getTagWeb_Sub_Category(context.navigation.fhHbxAdaptor.pn);
	    tmParam["web_navigation"] = getTagWeb_Navigation(context.navigation.fhHbxAdaptor.pn);
		
		//set the site catalist data directly 
		var s = s_gi(s_account);
		
  		s.prop1='Filter'; // Differentiates this 'Filter' event from a 'Search' event
 		s.prop15=s.eVar15=context.navigation.fhHbxAdaptor.searchPhrase; // Search phrase
  		s.prop14=context.navigation.fhHbxAdaptor.attr1;
  		s.prop16=context.navigation.totalResults; //No of results - zero indicates failed search
  		s.pageName=mlc.replace(/\//g,':')+':'+pn+':Filtered';
  		if(s.pageName.indexOf(':')==0) 
  		   s.pageName=s.pageName.substr(1,s.pageName.length);
  		s.t(); // calls the 'page view' function in SiteCatalyst, to send all this data through.

	   
  }
	function buildTCATFacets(context) {
	
		// find the object to be replaced
	   	var outputArea = document.getElementById("navigation_top_level");
	   
	    // save any facets that are expanded
	   	var allOpenFacets = getElementsByClassName(outputArea, "open");
	   	
  		// update new facets with the old facets expanded status
  		// i.e. keeping the expanded status 'sticky'
	   	for ( var i=0;i<context.navigation.facets.length;i++ ) {
	   		var newElement = context.navigation.facets[i];
	   		if (containsId(allOpenFacets, newElement.id)) {
	   			newElement.expanded = true;
	   		} else {
	   			newElement.expanded = false;
	   		}
	   	}
	   
		// replace object with the new items
	  	outputArea.innerHTML = getTemplate("/templates/tcatFacetsTemplate.ajp").process(context);
 		
	  	applyFacetEvents("");
	
	}
	
	//TODO: Remove once confirmed that see offers is suppported by Facets
	function buildOffersLink(context, anElement)
	{				
		var offersLI;
		if (context.navigation.showOffersUrl != null && context.navigation.showOffersUrl != '')
		{
			//If the header doesn't exist then ceate it
			if(document.getElementById('seeoffershead') == null){			
				offersLI = document.createElement('li');
				offersLI.setAttribute('id','seeoffershead');	
			}else{
				offersLI = document.getElementById('seeoffershead');
			}

			//We always reset the inner html for this
			offersLI.innerHTML = getTemplate("/templates/seeOffersLink.ajp").process(context);
			anElement.appendChild(offersLI);
												
		} 
		else {	removeSeeOffersElements();	}
	}	
	
	function removeSeeOffersElements(){
		//The link is not here so we need to remove the nodes if required... 
		if(document.getElementById('seeoffershead') != null)
		{			
			document.getElementById('seeoffershead').parentNode.removeChild(document.getElementById('seeoffershead'));
		}		
	}	
	
	function displayErrorMessage(context){
	
		var message = getTemplate("/templates/errorMessageTemplate.ajp").process(context);
		showErrorMessage(message);
	}
	
	function truncateString(aString){
		//Unescape the string for size comparison
		unescapedStr = $('<div>'+aString+'</div>').html();
		if(unescapedStr.length > 23){
			return aString.substr(0,23)+'...';
		}
		return aString;
	}
	
	function joinString(aString)
	{
	var a_array =  aString.split("/");
	if(a_array.length>0)
	{
	var aString = "\"/\"" + "+[\"";
	
    for(var i=0;i<a_array.length;i++)
		{
    		aString = aString + a_array[i];
    		if(i==(a_array.length - 1))
    		{
    		
    		aString = aString + "\"].join(\"/\")";
    		}
    		else
    		{
    		
    		aString = aString + "\",\"";
    		}
    		
		}
	}
	return aString;
	}

	// searchAndSort.js
	
	function product_search_field_clicked_event()
	{
		

		var buttonSpan=document.getElementById("searchText");
		var datafield=document.getElementById("product_search_field");
		
		// add a space on the end to seperate any new search terms
		if(buttonSpan != null && buttonSpan.innerHTML != null && buttonSpan.innerHTML != "")
			datafield.value = buttonSpan.innerHTML + " ";
		
		
		var psis_div = document.getElementById("psis");
		if(psis_div != null)
			psis_div.style.display="none";
		
		//you have to do this because IE sets the cursor to the first position by default !!
		
		setCaretTo(datafield,datafield.value.length);
		
		var findlabel=document.getElementById("findLabel");
		findlabel.style.display="inline";	
	}
	
	function checkForUnrefinedSearch()
	{

		var psis_div = document.getElementById("psis");
		psis_div.style.display="none";
		var findlabel=document.getElementById("findLabel");
		findlabel.style.display="inline";
		var buttonSpan=document.getElementById("searchText");
		buttonSpan.innerHTML = "";
		
		$('#product_search_field').val("");
		$('#product_search_field').focus();
	}

function setCaretTo(obj, pos) 
{ 
    if (window.getSelection) { }   // Firefox, Opera, Safari 
    else 
    {
        var range = obj.createTextRange(); 
        range.move("character", pos); 
        range.select(); 
    }
}
	

