//-----------------------------------------------------------------
// Licensed Materials - Property of IBM
//
// WebSphere Commerce
//
// (C) Copyright IBM Corp. 2007, 2009 All Rights Reserved.
//
// US Government Users Restricted Rights - Use, duplication or
// disclosure restricted by GSA ADP Schedule Contract with
// IBM Corp.
//-----------------------------------------------------------------

//
//

/**
* @fileOverview This file holds methods to perform client side operations in relation to catalog browsing, usually at the category level.<b> 
* 			For example, this file holds methods to add items to the shopping cart, wish list and compare zone and to resolve SKUs.<b> 
*			This file is referenced in a collection of JSPs including all of the catalog entry display JSPs such as
*			CachedBundleDisplay.jsp, CachedItemDisplay.jsp , CachedPackageDisplay.jsp, CachedProductOnlyDisplay.jsp.
*			As well this file is included in CategoryOnlyResultsDisplay.jsp and in none catalog browsing pages such as 
*			CatalogSearchDisplay.jsp and MyAccountDisplay.jsp.
*
* @version 1.0
**/

/**
* @class categoryDisplayJS This class defines all the variables and functions used by the CategoryDisplay.js. Any page that will use a function in this file
*		can access that function thru this class. Pages that use categoryDisplayJS include CachedProductOnlyDisplay.jsp which is responsible for
*		displaying product details. As well CategoryOnlyResultsDisplay.jsp uses this page to facilitate the category browsing functionality such as add to cart, 
*		wish list and compare zone.
*
**/
categoryFilterJS={
	
	/** Can be used to hold a map of error messages **/
	errorMessages: new Object(),
	
	/** The language ID currently in use **/
	langId: "-1",
	
	/** The store ID currently in use **/
	storeId: "",
	
	/** The catalog ID currently in use **/
	catalogId: "",
	
	/** Holds the current user type such as guest or registered user. Allowed values are 'G' for guest and 'R' for registered.**/
	userType:"",
	
	/** Can be used to indicate whether or not there has been a context change event **/
	contextChanged:false, 
	
	/** Set to true in the goBack and goForward methods **/
	isHistory:false,
	
	categoryDisplayUrlTemplate:"",
	
	filter_form_fields: new Array(),
	
	/**
	* initHistory This function will take elementId and changeUrl as inputs and create a new history tracker object and sets the initial state.
	*			  This is used on CategoriesDisplay.jsp to initialize the page history to the CategoryDisplay URL of the category you are on.
	* @param {String} elementId  HistoryTracker elementId.
	* @param {String} changeUrl HistoryTracker URL.
	*
	**/
	initHistory:function(elementId, changeUrl){
		var historyObject = new categoryFilterJS.HistoryTracker(elementId, changeUrl);
		dojo.back.setInitialState(historyObject);	
	},
	
	/**
	* setCommonParameters This function initializes storeId, catalogId, and langId.
	*
	* @param {String} langId The language id to use.
	* @param {String} storeId The store id to use.
	* @param {String} catalogId The catalog id to use.
	* @param {String} userType The type of user. G for Guest user.
	* 
	**/
	setCommonParameters:function(langId,storeId,catalogId,userType){
		this.langId = langId;
		this.storeId = storeId;
		this.catalogId = catalogId;
		this.userType = userType;
	},
	
	setCategoryDisplayUrlTemplate:function( templateString )
	{
		this.categoryDisplayUrlTemplate = templateString;
	},
	
	
	/**
	* updateParamObject This function updates the given params object with a key to value pair mapping.
	*				    If the toArray value is true, It creates an Array for duplicate entries otherwise it overwrites the old value.
	*			        This is useful while making a service call which accepts a few parameters of type array.
	*					This function is used to prepare a a map of parameters which can be passed to XMLHttpRequests. 
	* 					The keys in this parameter map will be the name of the parameter to send and the value is the corresponding value for each parameter key.
	* @param {Object} params The parameters object to add name value pairs to.
	* @param {String} key The new key to add.
	* @param {String} value The new value to add to the specified key.
	* @param {Boolean} toArray Set to true to turn duplicate keys into an array, or false to override previous values for a specified key.
	* @param {int} index The index in an array of values for a specified key in which to place a new value.
	*
	* @return {Object} params A parameters object holding name value pairs.
	*
	**/
	updateParamObject:function(params, key, value, toArray, index){
	
	   if(params == null){
		   params = [];
	   }

	   if(params[key] != null && toArray)
	   {
			if(dojo.lang.isArrayLike(params[key]))
			{
				//3rd time onwards
			    if(index != null && index != "")
				{
					//overwrite the old value at specified index
				     params[key][index] = value;
				}
				else
				{
				    params[key].push(value);
			     }
		    }
			else
			{
			     //2nd time
			     var tmpValue = params[key];
			     params[key] = [];
			     params[key].push(tmpValue);
			     params[key].push(value);
		    }
	   }
	   else
	   {
			//1st time
		   if(index != null && index != "" && index != -1)
		   {
		      //overwrite the old value at specified index
		      params[key+"_"+index] = value;
		   }
		   else if(index == -1)
		   {
		      var i = 1;
		      while(params[key + "_" + i] != null)
			  {
			       i++;
		      }
		      params[key + "_" + i] = value;
		   }
		   else
		   {
		      params[key] = value;
		    }
	   }
	   return params;
	 },
	 
	 
	/**
	* loadContentURL Sets the URL of the page to load into CategoryDisplay_Controller which in turn is used to display categories
	* 				 on the CategoryDisplay.jsp and DepartmentDisplay.jsp. The HistoryTracker is also updated.
	*
	* @param {String} contentURL The URL to load contents from.
	*
	**/
	loadContentURL:function(contentURL){
		
		//For Handling multiple clicks
		if(!submitRequest()){
			return;
		}   		
		cursor_wait();
		CommonControllersDeclarationJS.setControllerURL('CategoryFilter_Controller',contentURL);		
		wc.render.updateContext("CategoryFilter_Context");
	},
	
	
	/**
	* goBack Called when the back button is clicked in the browser. 
	*		 Uses the changeUrl set by the HistoryTracker and calls the loadContentURL method so that the state of the page get 
	* 		 loaded from a previous state in the page history.
	**/
	goBack:function(){
		
		categoryFilterJS.loadContentURL(this.changeUrl);
		categoryFilterJS.isHistory=true;

	},


	/**
	* goForward Called when the forward button is clicked in the browser. 
	*			Uses the changeUrl set by HistoryTracker and calls the loadContentURL method so that the state of the page gets
	*           loaded from the next available point in the page history.
	**/
	goForward:function(){
		
		categoryFilterJS.loadContentURL(this.changeUrl);
		isHistory=true;
	},


	/**
	* HistoryTracker Used to track the history for the browser back and forward buttons.
	*
	* @param {String} elementId HistoryTracker id.
	* @param {String} changeUrl The change url of the current state.
	*
	**/
	HistoryTracker:function(elementId, changeUrl){
	
		this.elementId = elementId; 
		this.changeUrl =  changeUrl;

	},
	
	/**
	* processBookmarkURL Processes the bookmark using the bookmarkId which is stored in location.hash.
	**/
	processBookmarkURL : function(){
		
			var bookmarkId = location.hash;	
			if(bookmarkId){					        
				bookmarkId = bookmarkId.substring(1, bookmarkId.length);
			}   
			if(bookmarkId){
				var indexOfIdentifier = bookmarkId.indexOf("identifier", 0);
				if ( indexOfIdentifier >= 0) {
					var realUrl = bookmarkId.substring(0, indexOfIdentifier - 1);
				}
			}

			if(bookmarkId == null || bookmarkId == ""){

			}
	},
	
	submitFilter: function(_form)
	{
		var s_url = "CategoryFilterDisplayView";
		categoryFilterJS.buildConstr(_form);
		for( var i = 0; i < _form.elements.length; i++  )
		{
			var name = _form.elements[i].name;
			var value = _form.elements[i].value;
			if( ( name == "constr" && value == '' ) || name.indexOf( "C$" ) == 0  )
			{
				// don't include empty constraint or the dropdown fields in the url
			}
			else
			{
				s_url += ( i > 0 ? "&" : "?" ) + name + "=" + value;
			}
		}
		categoryFilterJS.loadContentURL( s_url );
		return false;
	},
	
	resetFilters: function(_form)
	{
		for( var i = 0; i < categoryFilterJS.filter_form_fields.length; i++ )
		{
			var field = _form.elements[categoryFilterJS.filter_form_fields[i]];
			field.selectedIndex = 0;
		}
		return this.submitFilter(_form);
	},
	
	buildConstr: function(_form)
	{
		var constr_array = new Array()
		var constr_num = 1;
		this.resetCurrentSelections();
		
		for( var i = 0; i < categoryFilterJS.filter_form_fields.length; i++ )
		{
			var field = _form.elements[categoryFilterJS.filter_form_fields[i]];
			if( field.selectedIndex > 0 )
			{
				var constr_name = jQuery(field).attr("constr_name");
				var val = field[field.selectedIndex].value;
				if( val == null || val == '' )
				{
					this.setCurrentSelection( constr_name, field.selectedIndex - 1 );
				}
				else
				{
					this.setCurrentSelection( constr_name, val );
				}
				var constr_string = jQuery(field[field.selectedIndex]).attr("constr_string");
				if( constr_string != null && constr_string != "" )
				{
					constr_array[constr_array.length] = constr_num++;
					constr_array[constr_array.length] = constr_string;
					var constr_string2 = jQuery(field[field.selectedIndex]).attr("constr_string2");
					if( constr_string2 != null && constr_string2 != "" )
					{
						constr_array[constr_array.length] = constr_num++;
						constr_array[constr_array.length] = constr_string2;
					}
				}
				else
				{
					/*
					for( var chnum = 0; chnum < field[field.selectedIndex].value.length; chnum++ )
					{
						alert( "" + chnum + ": " + field[field.selectedIndex].value.charAt( chnum ) );
					}
					*/
					constr_array[constr_array.length] = constr_num++;
					constr_array[constr_array.length] = constr_name;
					constr_array[constr_array.length] = "=";
					constr_array[constr_array.length] = field[field.selectedIndex].value;
				}
			}
		}
		var constr_val = escape(constr_array.join(";"));
		constr_val = constr_val.replace("+","%2B");
		_form.constr.value = constr_val;
	},
	
	currentSelections: new Object(),
	
	resetCurrentSelections: function()
	{
		this.currentSelections = new Object();
	},
	
	setCurrentSelection: function( _field_name, _value )
	{
		this.currentSelections[_field_name] = _value;
	},
	
	getCurrentSelection: function( _field_name )
	{
		return this.currentSelections[_field_name];
	},
	
	buildFormElements: function()
	{
		var fdField = document.getElementById( "filterData" );
		if( fdField == null ) return;
		
		var filterData = dojo.fromJson(fdField.value);
		var filter_fields = "";
		categoryFilterJS.filter_form_fields = new Array();
		for( var i = 0; i < filterData.rows.length; i++ )
		{
			if( filterData.rows[i].items.length > 0 )
			{
				var field_name = unescape( filterData.rows[i].formElementName );
				var field_desc = unescape( filterData.rows[i].items[0].metaData.displayName );
				var field_constr_name = unescape( filterData.rows[i].items[0].metaData.name );
				var filter_field_html =
					'<li class="pairing pairing-vertical pairing-${FIELDNAME} clearfix">' +
						'<label class="primary" for="${FIELDNAME}">' +
							'<span class="pairing-label">' +
								'${FIELDDESC}' +
							'</span>' +
						'</label>' +
						'<div class="pairing-content">' +
							'<div class="pairing-controls">' +
								'<select id="${FIELDNAME}" name="${FIELDNAME}" constr_name="${CONSTR_NAME}">' +
									'<option value="">' +
										'${FIELDDESC}' +
									'</option>' +
									'${OPTIONS}' +
								'</select>' +
							'</div>' +
						'</div>' +
					'</li>';
				var options = "";
				if( field_constr_name == "LISTPRICE" )
				{
					var curr_val = this.getCurrentSelection( field_constr_name );
					
					var ranges = new Array("750.00","1250.00");
					for( var r = 0; r <= ranges.length; r++ )
					{
						var selected = "";
						if( curr_val != null && curr_val == r )
						{
							selected = " selected";
						}
						if( r == 0 )
						{
							options += '<option value="" constr_string="' + field_constr_name + ';&lt;=;' + ranges[r] + '"' + selected + '>$0 - $' + ranges[r] + '</option>';
						}
						else if( r == ranges.length )
						{
							options += '<option value="" constr_string="' + field_constr_name + ';&gt;=;' + ranges[r-1] + '"' + selected + '>$' + ranges[r-1] + ' and up</option>';
						}
						else
						{
							options += '<option value="" constr_string="' + field_constr_name + ';&gt;=;' + ranges[r-1] + '" constr_string2="' + field_constr_name + ';&lt;=;' + ranges[r] + '"' + selected + '>$' + ranges[r-1] + '-$' + ranges[r] + '</option>';
						}
					}
				}
				else if( field_constr_name == "F_OVERALL$_$LENGTH" )
				{
					var curr_val = this.getCurrentSelection( field_constr_name );
					
					var ranges = new Array("7","9");
					for( var r = 0; r <= ranges.length; r++ )
					{
						var selected = "";
						if( curr_val != null && curr_val == r )
						{
							selected = " selected";
						}
						
						if( r == 0 )
						{
							options += '<option value="" constr_string="' + field_constr_name + ';&lt;=;' + ranges[r] + '"' + selected + '>&lt; ' + ranges[r] + '"</option>';
						}
						else if( r == ranges.length )
						{
							options += '<option value="" constr_string="' + field_constr_name + ';&gt;=;' + ranges[r-1] + '"' + selected + '>&gt; ' + ranges[r-1] + '"</option>';
						}
						else
						{
							options += '<option value="" constr_string="' + field_constr_name + ';&gt;=;' + ranges[r-1] + '" constr_string2="' + field_constr_name + ';&lt;=;' + ranges[r] + '"' + selected + '>' + ranges[r-1] + '"-' + ranges[r] + '"</option>';
						}
					}
				}
				else
				{
					var curr_val = this.getCurrentSelection( field_constr_name );
					for( var j = 0; j < filterData.rows[i].items.length; j++ )
					{
						var value = unescape(filterData.rows[i].items[j].dataElement.presentationString);
						var selected = "";
						var value2 = value;
						value2 = value2.replace( /;/, "#3B" );
						if( value2 == curr_val )
						{
							selected = " selected";
						}
						
						value2 = value2.replace( /&/, "&amp;" );
						value2 = value2.replace( /"/, "&quot;" );
						value = value.replace( /"/, "&quot;" );
						options += "<option value=\"" + value2 + "\"" + selected + ">"
							+ value
							+ "</option>";
					}
				}
				
				
				categoryFilterJS.filter_form_fields[categoryFilterJS.filter_form_fields.length] = field_name;
				
				filter_field_html = dojo.string.substitute(
					filter_field_html,
					{ FIELDNAME: field_name, FIELDDESC: field_desc, CONSTR_NAME: field_constr_name, OPTIONS: options }
				);
				
				filter_fields += filter_field_html;
			}
		}
		document.getElementById("filterFields").innerHTML = filter_fields;
	},
	
	filterResults: function()
	{
		var rdField = document.getElementById( "resultsData" );
		if( rdField == null ) return;
		
		var resultsData = dojo.fromJson(rdField.value);
		var filter_results = new Array();
		for( var i = 0; i < resultsData.rows.length; i++ )
		{
			if( resultsData.rows[i].items.length > 0 && resultsData.rows[i].items[0].metaData.name == 'CATENTRY_ID' )
			{
				for( var j = 0; j < resultsData.rows[i].items.length; j++ )
				{
					filter_results[filter_results.length] = resultsData.rows[i].items[j].dataElement.unformattedData;
				}
			}
		}
		//alert(filter_results.join(','));
		
		var load_url = categoryFilterJS.categoryDisplayUrlTemplate.replace( 'FILTER_RESULTS', filter_results.join(',') );
		//alert( load_url );
		categoryDisplayJS.loadContentURL(load_url);
	}
}

categoryFilterJS.HistoryTracker.prototype.back = categoryFilterJS.goBack;
categoryFilterJS.HistoryTracker.prototype.forward=categoryFilterJS.goForward;


/**
 * Declares a new render context for the Category filter
 */
wc.render.declareContext("CategoryFilter_Context",null,"");

/** 
 * Declares a new refresh controller for the Category display with pagination.
 */
wc.render.declareRefreshController({
       id: "CategoryFilter_Controller",
       renderContext: wc.render.getContextById("CategoryFilter_Context"),
       url: "",
       formId: ""

       /** 
        * Displays the previous/next page of category listings.
        * This function is called when a render context changed event is detected. 
        * 
        * @param {string} message The render context changed event message
        * @param {object} widget The registered refresh area
        */
       ,renderContextChangedHandler: function(message, widget) {
          var controller = this;
          var renderContext = this.renderContext;
          categoryFilterJS.contextChanged = true;
          widget.refresh(renderContext.properties);
       }

   /** 
    * This function handles paging and browser back/forward functionalities upon a successful refresh.
    * 
    * @param {object} widget The registered refresh area
    */
	,postRefreshHandler: function(widget)
	{
		var controller = this;
		var renderContext = this.renderContext;
		if (categoryFilterJS.contextChanged && (!categoryFilterJS.isHistory))
		{
			var identifier = "&identifier=" + (new Date()).getTime();
			var historyObject = new categoryFilterJS.HistoryTracker('CategoryFilter_Widget', controller.url + identifier);
			dojo.back.addToHistory(historyObject);       
			categoryFilterJS.contextChanged = false;
			categoryFilterJS.isHistory = false;  
		}
		// clear the request submitted flag without removing the busy image
		requestSubmitted = false;
		
		categoryFilterJS.buildFormElements();
		
		categoryFilterJS.filterResults();
	}
});

