var NAVSTATE = {
	selection:{},
	sliders: {},
    //If exists remove it, else add it!
    toggleInSet: function(set, value){
        this._createWidget(set, "set");

        //XOR "value" in the list. If called twice with the same "value" the original state is restored 
        var index= jQuery.inArray(value,this.selection[set].values);
        if(index == -1) {
	        //add "value" to the list
	        this.selection[set].values.push(value);
        } else {
        	//remove "value" from the list
        	this.selection[set].values.splice(index,1);
        }
    },
    toggleValue: function(set, value){
        delete this.selection[set];
        this._createWidget(set, "set");
        this.selection[set].values = [value];
    },
    toggleMin: function(set, value){
        this._createWidget(set, "range");
        this.selection[set].min = value;
    },
    toggleMax: function(set, value){
        this._createWidget(set, "range");
        this.selection[set].max = value;
    },
    
    _createWidget: function(set, wType){
        //Default to set type, if the widget is not specified
        if (!this.selection[set]) {
            this.selection[set] = {
                type: wType || "set",
                values : []
            };
        }
    },
    /* takes a list and chunks into a list of (lists of size n) */ 
    _batch: function(a,n) {
    	var tot=a.length, i=0, ret=[], btch=[];
	 	while(i<tot) {
			btch.push(a[i]); i++;
			if(i%n == 0) { ret.push(btch); btch=[] }
		}
		if(btch.length>0) { ret.push(btch) }
		return ret;
    },

    getNavState: function(x){
        var params = [];
        
        function getState(widgets){
            for (w in widgets) {
				var widgetType = widgets[w].type || "";
				
				if (widgetType == "set") {
				    for(var i=0;i<widgets[w].values.length;i++) {
				    	params.push(w + "=" + widgets[w].values[i]);
				    }
				} else {
				    if (widgetType == "range") {
				        if (widgets[w].min !=undefined) {
				            params.push(w + ".min=" + widgets[w].min);
				        }
				        if (widgets[w].max !=undefined) {
				            params.push(w + ".max=" + widgets[w].max);
				        }
				    }
				}
            }
        }
        getState(this.selection);
        
        //Frustration!! Strange but true: Array.join(params,'&') bombed in our beloved IE!!
        //Workaround 1: use the prototype method. pass in 'this' though it plays no role -Array.prototype.join.apply(this,params,'&')
        //Workaround 2: params.join('&') - I like this one!
        return params.join('&');
    },
    
	inArrayCaseIgnore: function( b, widget) {
		var bLower=b;
		/* cache the array into a hash table so subsequent lookups are cheaper */
		/* stuff this cache into another variable called ci_values_hash,
		   which is a case insensitive version of the 'values list' in the form of a hash table 
		*/
		if(typeof(widget.ci_values_hash)=="undefined") {
			var hash={};
			var a=widget.values;
			for(var i=0, al=a.length; i< al; i++ ) {
				hash[a[i].toLowerCase()]=true;	
			}
			widget.ci_values_hash=hash;

		}
		/* at this point ci_values_hash should be created on widget if it does not exist */
		/* so use it and do a lookup */
		return widget.ci_values_hash[bLower.toLowerCase()] ? true: false;
	},
    updateUI : function(wActive,wSelected) {
		var me=this;
		wSelected = wSelected || this.selection;
    	//Activate/Disable and select/Deselect, for all the multiselect controls
		$('ul.multiselect').each(function(){
			var widgetName = $(this).parent().attr('id'); //Parent divs id is the widgetname!
			/* chunk into smaller batches */
			var batches=me._batch($('li',this),50);
			
			/* process the 1st batch in sync and yield the other for later */
			(function(i) {
				if(i>=batches.length) return;
				
				$.each(batches[i],function() {
					var listItem = $(this);
					var data = listItem.metadata();
					
					if (data && data.value) {
						//Activate/Disable
						if( wActive[widgetName] && me.inArrayCaseIgnore(data.value, wActive[widgetName] ) ) {
							//enable it!
							listItem.removeClass('disabled');
						} else {
							listItem.addClass('disabled');
						}
		
						if( wSelected[widgetName] && me.inArrayCaseIgnore(data.value, wSelected[widgetName] ) ) {
							listItem.addClass('selected');
						} else {
							listItem.removeClass('selected');
						}
					}
				});
	
				var f=arguments.callee; //this points to our anonymous function

				setTimeout(function(){
					f(i+1)
				},10);
				
			})(0);
	
		});
  		
		//There should be only one x in state[i] if it is a single select
		//Single select has 2 cases = 1.combo and 2. list 

		//1. one where it is a combo box
		$('select.singleselect').each(function(){
			var sel =$(this);
			var widgetName = sel.parent().attr('id'); //Parent divs id is the widgetname!
			if( wSelected[widgetName] && wSelected[widgetName].values[0]) {
				sel.val(wSelected[widgetName].values[0]);			
			}
		});
	
		//2. when it is a list.
		$('ul.singleselect').each(function(){
			var sel =$(this);
			var widgetName = sel.parent().attr('id'); //Parent divs id is the widgetname
	
			$('li',this).each(function() {
				var listItem = $(this);
				var data = listItem.metadata();
				if (data && data.value) {
					//Activate/Disable
					if( wSelected[widgetName] && me.inArrayCaseIgnore(data.value, wSelected[widgetName] ) ) {
					//enable it!
						listItem.addClass('selected');
					} else {
						listItem.removeClass('selected');
					}
				}
			});
		});

		for (s in this.sliders) {
			if(wActive[s] !=undefined && wActive[s].min!=undefined && wActive[s].max !=undefined) {
				//NOTE: Set Selection is buggy (it causes the wrong value to be displayed) 
				// but calling setRange after setSelection sets it right.
				this.sliders[s].setSelection([this.selection[s].min,this.selection[s].max])
							   .setRange(wActive[s].min,wActive[s].max);
				setTimeout((function(s) {
					return function() {
					    s.refreshUI();
					}
				})(this.sliders[s]),100);
			}
		}
    }
};

$(document).ready(function(){

	/** 
		Change the layout to 750px, if the resolution is less than 1000x. 
		This is done by changing the main div to doc/yui-t7 (See yui css grids for more details) 
	**/
	
	if(screen) {
		if(screen.width<1000) {
			$("#doc2").attr({'id':'doc', 'class':'yui-t7'});
			$("#right_col").remove();
		}
	}
	
	$('#price').show();

    /* This makes an ajax call and refreshes the display 
    
     Few things to note: We do *not* want to discard the older ajax responses as the browser will cache it
     and reuse it, if the same request is made again. 
     
     This means we do not want to abort any request/response but want to use the latest response.
     */
    var loadPage=(function createLoadPage(){
    	var currentRequestId=0;
        var resultsEl = $('#resultsPane');
        
        function updateDisplay(data,reqId){
	        //Has the last request come back ?
	    	$('#featuredproducts').show();
            if (reqId == currentRequestId) {
            	$('#loading').hide();
		        resultsEl.css('opacity',100);	
		        resultsEl.html(data);
            }
        }
		return function(_hash) {
	        var hash = _hash || NAVSTATE.getNavState();
	        if (hash == "") {
	            return "";
	        }

            currentRequestId= currentRequestId+ 1;
            var myRequestId = currentRequestId;
	
	        resultsEl.css('opacity',0);
	        $('#loading').show();
	        $.ajax({
	            url: "Search_ajax.action",
	            data: hash,
	            dataType: "html",
	            //Copy over the requestId into local scope through a closure
	            success: (function(_myRequestId){
	                return function(data){
	                    updateDisplay(data, _myRequestId);
	                }
	            })(myRequestId),
	            error: (function(_myRequestId){
	                return function(data){
		                resultsEl.css('opacity',100);
	                }
	            })(myRequestId)
	        });
        }
    })();

	// Initialize history plugin.
    // The callback is called at once by present location.hash. 
    $.historyInit(loadPage);
    
    $('ul.singleselect').not('.no_combo').each(function() {
    	var widgetName = $(this).parent().attr('id');
    	$(this).linksCombo({
	        onchange: function(a){
	        	NAVSTATE.toggleValue(widgetName, this.value);
	            $.historyLoad(NAVSTATE.getNavState());
	        },
	        attrListToCopy: ['id','class'],
	        isDefault: function(aEl){
	            return $(aEl).is('.selected');
	        }
	    });
    });

	$('ul.singleselect').hover(
    	function(e) {
    		if($(e.target).is(li)) {
				liEl.addClass('hover');
			}
		}, function(e) {
			if($(e.target).is(li)) {
				liEl.removeClass('hover');
			}
		}
	);
	
    $('div.nav').click(function(e){
		var me = $(e.target);
		if(!(me.is('a') || me.is('span'))){
			return false;
		}
		
        var liEl= me.parents('li:first');
        var ulEl= liEl.parents('ul:first');
		var data = liEl.metadata();
        var widgetName = ulEl.parents('div.nav:first').attr('id');
        
		me.blur();
		if(liEl.hasClass("disabled")) {
			return false;
		}
				
		if (data && data.value) {
			liEl.toggleClass('selected');

              	if(ulEl.hasClass('singleselect')) {
                NAVSTATE.toggleValue(widgetName, data.value);
                $('li',ulEl).removeClass('selected');
                //WARNING: Super ugly fix. Look down below you will find a click event on clearselection and added to it is "#product ul.gifts a"
                //Right now '#product ul.gifts a' is the only list out there which is singleselect. rest of them all are combos.
                //since we call historyLoad in that handler we do not want to do one more historyLoad here as it will insert 2 calls into the back button stack
                //so moved the $.historyLoad(NAVSTATE.getNavState()); to the else block (it was outside before) .
                //incase you have problems with single select with lists and the back button - this is the culprit. this code needs refactoring.   
              	} else {
                NAVSTATE.toggleInSet(widgetName, data.value);
                   $.historyLoad(NAVSTATE.getNavState());
            }
					
			return false;
		}
	});

    $('.listbox').hoverIntent({
		sensitivity: 7, // number = sensitivity threshold (must be 1 or higher)    
		interval: 500, // number = milliseconds for onMouseOver polling interval    
		over: function() {
			$(this).addClass('expand');
		},
		timeout: 2000, // number = milliseconds delay before onMouseOut
		out: function() {
			$(this).removeClass('expand');
		}
	});

	$("#clearselection").add('#product ul.gifts a').click(function(){
		var clearHash = [];
		if(NAVSTATE.selection.location && NAVSTATE.selection.location.values[0] != undefined) {
			clearHash.push("location="+NAVSTATE.selection.location.values[0]);
		}
		if(NAVSTATE.selection.product && NAVSTATE.selection.product.values[0] ) {
			clearHash.push("product="+NAVSTATE.selection.product.values[0]);
		}
		clearHash.push("store="+NAVSTATE.selection.store.values[0]);
		$.historyLoad(clearHash.join("&"));
		return false;
	});

	function addCommas(nStr)
	{
		nStr += '';
		var x = nStr.split('.');
		var x1 = x[0];
		var x2 = x.length > 1 ? '.' + x[1] : '';
		var rgx = /(\d+)(\d{3})/;
		while (rgx.test(x1)) {
			x1 = x1.replace(rgx, '$1' + ',' + '$2');
		}
		return x1 + x2;
	}
	
	/** Variables for Price Bar based on store **/
	
	var step = {
		Rakhis:[10,50,100,1000],
		Watches:[50,100,1000,5000,10000],
		Mobiles:[100,1000,5000,10000],
		Cameras:[100,1000,5000,10000],
		Apparel:[50,100,1000,5000,10000],
		Jewellery:[50,100,1000,5000,10000],
		Beauty:[50,100,1000,5000,10000],
		Gifts:[50,100,1000,5000,10000],
		Diwali_Gifts:[50,100,1000,5000,10000]
	}
	
	/** Setup Sliders */
    function setupPrice() {
		var lblMin = $('#price span.min');
		var lblMax = $('#price span.max');

		$('#price div.slider').sliderx({
			init: function (slider) {
				NAVSTATE.sliders.price = slider;
			},
			change : function ( value, selection) {
				NAVSTATE.selection.price.min = selection[0] ;
				NAVSTATE.selection.price.max = selection[1] ;
				$.historyLoad(NAVSTATE.getNavState());
			},

			slide : function ( value, selection) {
				if (value[0] >= 50000) {
					lblMin.text(addCommas(Math.round(value[0]/(100000/100))/100) + " Lakhs");
					lblMax.text(addCommas(Math.round(value[1]/(100000/100))/100)+ " Lakhs");
				} else {
					lblMin.text(addCommas(Math.round(value[0])));
					lblMax.text(addCommas(Math.round(value[1])));
				}
			},
			
			steps : step[NAVSTATE.store] || [1000,10000,50000,100000],
			rangeMin : 0,
			rangeMax : 100
		});
	}
	
	setupPrice();

	function setupOdometer() {
		var lblMax = $('#odometer span.max');
		$('#odometer div.slider').sliderx({
			init: function (slider) {
				NAVSTATE.sliders.odometer = slider;
			},
			change : function ( value, selection) {
				NAVSTATE.selection.odometer.max = selection[0] ;
				$.historyLoad(NAVSTATE.getNavState());
			},
			slide : function ( value, selection) {
				lblMax.text(value[1]+" kms");
			},
			rangeMin : 0,
			rangeMax : 100
		});
	}
	
	function setupYear() {
		var lblMin = $('#year span.min');
		var lblMax = $('#year span.max');
		$('#year div.slider').sliderx({
			init: function (slider) {
				NAVSTATE.sliders.year = slider;
			},
			change : function ( value, selection) {
				NAVSTATE.selection.year.min = selection[0] ;
				NAVSTATE.selection.year.max= selection[1] ;
				$.historyLoad(NAVSTATE.getNavState());
			},
			slide : function ( value, selection) {
				lblMin.text(value[0]);
				lblMax.text(value[1]);
			},
			steps : [1],
			rangeMin : 0,
			rangeMax : 100
		});
	}
	
	//setupPrice();
	setupOdometer();
	setupYear();
	
	initMySaveList();
	
})

function initMySaveList() {

	//Click handler for remove item
	$('#save_list img').click(function() {
		var params = $(this).metadata();
		
		$.ajax({
		    url: "SaveList_remove.action",
		    type : "POST",
		    data: {listName : NAVSTATE.selection.store.values[0], itemValue : params.value, ajaxCall : true},
		    dataType: "html",
		    //Copy over the requestId into local scope through a closure
		    success: function(data){
	    		$('#save_list_content')
	    		.html(data);
		    }
		});
		
		
		
		return false;
	});
	
	$('#save_list li').hover(function() {
		$(this).addClass('hover');
	}, function() {
		$(this).removeClass('hover');
	});
	
}


function init() {
  
	$('ul.srch_result li').hover(
		function() {
			$(this).addClass('hover');
		},
		function() {
			$(this).removeClass('hover');
		}
	);
	
	$('span.paging a').click(function() {
		var pgMeta = $(this).metadata();
		var pageNum = pgMeta ? pgMeta.page || -1 : -1;
		if(pageNum != -1) {
			NAVSTATE.toggleValue('page',pageNum);
			$.historyLoad(NAVSTATE.getNavState());
			return false;
		}
	});
	
	$('#restoreOld').click(function(){
		$.historyLoad(NAVSTATE.lastHash); 
		return false;
	});
	
	$('.addtocompare').click(function() {
		var params = $(this).metadata();
		
		$.ajax({
		    url: "SaveList_add.action",
		    data: {listName : NAVSTATE.selection.store.values[0], itemValue : params.value, ajaxCall : true},
		    type : "POST",
		    dataType: "html",
		    //Copy over the requestId into local scope through a closure
		    success: function(data){
	    		var sl=$('#save_list_content');
	    		var bgCol=$('#save_list').css('background-color');
	    		sl.html(data)
	    		.animate({ backgroundColor : "#ff8c1c" }, 500)
	    		.animate({ backgroundColor : bgCol }, 500)
		    }
		});
		
		return false;
		
	});
}
