/**
 * Wrapper around Marin tracking routines
 * @return
 */
function MarinTracking(conversionType){
	this.formId="utmform";
	this.textAreaId="utmtrans";
	this.conversionType=conversionType;
	this.containerId="div#contentwrap";
	
	this.init();
}


MarinTracking.prototype.init=function(){
	this.trackingHandlers=new Object();
	this.trackingHandlers["storeAppointment"]=this.marinImageOverride;
	this.trackingHandlers["emailFriend"]=this.marinImageOverride;
	this.trackingHandlers["printPage"]=this.marinImageOverride;
	this.trackingHandlers["requestCatalog"]=this.marinImageOverride;
	
	/*
	this.trackingHandlers["phoneOrder"]=this.trackPhoneOrder; //waiting
	this.trackingHandlers["registryInfoReq"]=this.trackRegistryInfoRequest; //via google analytics
	*/
	
	//easy way to map implement marin tracking before the official conversion codes are nailed down.
	this.conversionTypes=new Object();
	this.conversionTypes["phoneOrder"]="phoneOrder";
	this.conversionTypes["viewingRoom"]="viewingRoom";
	this.conversionTypes["registryInfoReq"]="reg_req";
	
	this.conversionTypes["weddingRegistry"]="wed_reg";
	this.conversionTypes["giftRegistry"]="reg";
	this.conversionTypes["saveItem"]="add_item";
	this.conversionTypes["accountCreate"]="signup";
	this.conversionTypes["order"]="sale";
	this.conversionTypes["printPage"]="Print";
	this.conversionTypes["emailFriend"]="email";
	this.conversionTypes["storeAppointment"]="appt";
	
	this.conversionTypes["downloadDiamondGuide"]="download";
}


MarinTracking.prototype.createForm=function(){
	var form=null;
	var contentWrap=jQuery(this.containerId);
	if (contentWrap.length>0){
		form=jQuery("<form style='display:none;' name='utmform' id='"+this.formId+"'></form>").appendTo(contentWrap);
		jQuery("<textarea id='"+this.textAreaId+"'></textarea>").appendTo(form);
	}
	
	return form;
}

MarinTracking.prototype.createUTMT=function(order){
	var template="UTM:T|ID|CUSTID|TOTAL|TAX|SHIPPING|CITY|STATE|COUNTRY";
	return template.replace(/ID/,varUtils.hasValue(order.id)?order.id:"")
				.replace(/CUSTID/,varUtils.hasValue(order.custId)?order.custId:"")
				.replace(/TOTAL/,varUtils.hasValue(order.total)?order.total:"")
				.replace(/TAX/,varUtils.hasValue(order.tax)?order.tax:"")
				.replace(/SHIPPING/,varUtils.hasValue(order.shipping)?order.shipping:"")
				.replace(/CITY/,varUtils.hasValue(order.city)?order.city:"")
				.replace(/STATE/,varUtils.hasValue(order.state)?order.state:"")
				.replace(/COUNTRY/,varUtils.hasValue(order.country)?order.country:"");
}

MarinTracking.prototype.createUTMI=function(order){
	var template="UTM:I|ID|CONVTYPE|PROD|CAT|PRICE|QUANT";
	var results="";
	for (var i=0; i<order.items.length;++i){
		results=results.concat(template.replace(/ID/,varUtils.hasValue(order.id)?order.id:"")
			.replace(/CONVTYPE/,this.conversionTypes[order.conversionType])
			.replace(/PROD/,varUtils.hasValue(order.items[i].name)?order.items[i].name:"")
			.replace(/CAT/,varUtils.hasValue(order.items[i].category)?order.items[i].category:"")
			.replace(/PRICE/,varUtils.hasValue(order.items[i].price)?order.items[i].price:"")
			.replace(/QUANT/,varUtils.hasValue(order.items[i].quantity)?order.items[i].quantity:""));
	}
	
	return results;
}

/**
 * Track an event. Will defer to the declared handler for the event (order type) if one is available
 * otherwise the default utmt and utmi line creation functions are used. 
 */
MarinTracking.prototype.track=function(order){
	var handler=this.trackingHandlers[order.conversionType];
	if (varUtils.isDef(handler)){
		handler.call(this,order);
	} else {
		var form=this.createForm();
		
		if (varUtils.isDef(form)){
			var text=this.createUTMT(order).concat("\n").concat(this.createUTMI(order));
			
			jQuery("textarea#"+this.textAreaId).text(text);
			_marinTrack.processOrders();
		}	
	}
}
/**
 * Overrite Marin's image generating function so that tracking pixels can be generated 
 * as events are triggered and not when then page is rendered.
 */
MarinTracking.prototype.marinImageOverride=function(order){
	var form=this.createForm();
	var containerId=this.containerId;
	if (varUtils.isDef(form)){
		var text=this.createUTMT(order).concat("\n").concat(this.createUTMI(order));
		
		jQuery("textarea#"+this.textAreaId).text(text);
		var writeImage=_marinTrack._writeImage;
		_marinTrack["_writeImage"]=function(A){
			A = A + "&rnd=" + Math.round(Math.random() * 2147483647);
			jQuery('<img src="' + A + '" border="0" height="1" width="1" />').appendTo(containerId);
		}
		_marinTrack.processOrders();
		_marinTrack["_writeImage"]=writeImage;
	}	
}


/**
 * A map that translates between Fina's subcodes and human readable text.
 */
function MCFinaSearchUtils(){
	this.data=null;
	this.selectedValues=null;
	this.solrFacetUtils=new SolrFacetUtils();
	
	this.dropDownCollections={
		manufacturer:["price"],
		site:["designer","price","topLevelCategory"],
		standard:["designer","type","price"],
		standardFooter:["designer","type","price","pattern"],

		engagementWeddingDesigner:["type","collection"],
		engagementWeddingBand:["designer","collection","style","price"],
		engagementWeddingBandFooter:["designer","type","collection","style","price"],
		
		findYourStyle:["designer","collection","style","price"],
			
		jewelryFooter:["designer","type","metal","stone","collection","style","price"],
		jewelry:["designer","type","metal","stone","collection","price"],
		jewelryDesigner:["type","collection"],
		
		giftsFooter:["designer","type","style","occasion","recipient","price"],
		giftsDesigner:["type"],
		gifts:["designer","type","occasion","recipient","price"],
		giftsByOccasion:["designer","type","recipient","price"],
		giftsByRecipient:["designer","type","occasion","price"],
		giftsByCategory:["designer","occasion","recipient","price"],
		giftsByStyle:["designer","type","occasion","recipient","price"],
		giftsForBaby:["designer","occasion","recipient","price"],
		giftsFrame:["designer","occasion","recipient","price"],
		
		homeDecor:["designer","room","style","type","price"],
		homeDecorByDesigner:["room","style","type","price"],
		homeDecorByRoom:["designer","style","type","price"],
		homeDecorByCategory:["designer","room","style","price"],
		homeDecorByStyle:["designer","room","type","price"],

		tablewareAndEntertainingDesigner:["teDesignerCategory"],
		tablewareAndEntertaining:["designer","price"],
		vintageSilver:["price"],
			
		bath:["designer","price"],
		bathDesigner:["price"]			
	};
	
	
	var submitHandlerData=new Object();
	submitHandlerData["handler"]=this.filterSearchResults;
	submitHandlerData["thisArg"]=this;
	submitHandlerData["args"]=[jQuery("#searchFilterForm"),jQuery("#current_page_id"),0];
	
    this.submitHandler=new Object();
    this.submitHandler["name"]="change";
    this.submitHandler["handler"]=this.eventHandlerProxy;
    this.submitHandler["data"]=submitHandlerData;
    
    var updateHandlerData=new Object();
    updateHandlerData["handler"]=this.updateFilters;
    updateHandlerData["thisArg"]=this;
    updateHandlerData["args"]=[jQuery("#searchFilterForm")];
    
    this.updateHandler=new Object();
    this.updateHandler["name"]="change";
    this.updateHandler["handler"]=this.eventHandlerProxy;
    this.updateHandler["data"]=updateHandlerData;
    
    //inserts a blank selection as the first item in the list
    this.perFilterCallback=new Object();
    this.perFilterCallback["post"]=function(container,filter){
    	var item=jQuery("<option></option>").prependTo(jQuery("select[name="+filter.attributes.name+"]"));
    	item.attr("value","");
    	
    	var options={
    			filter_by_brand:"All Designers",
    			filter_by_category_id:"All Types",
    			filter_by_category:"All Categories",
    			filter_by_collection:"All Collections",
    			filter_by_metal:"All Metals",
    			filter_by_occasion:"All Occasions",
    			filter_by_pattern:"All Patterns",
    			filter_by_recipient:"All Recipients",
    			filter_by_room:"All Rooms",
    			filter_by_stone:"All Gemstones",
    			filter_by_style:"All Styles",
				filter_by_type:"All Types",
				
				filter_by_price:"Price Range"
    			};
    	
		item.text(varUtils.isDef(options[filter.attributes.name])?options[filter.attributes.name]:"All");
		
		if (!varUtils.hasValue(filter.value)){
			item.attr("selected",true);
		}
    };
    
    this.perFilterCallbackFooter=new Object();
    this.perFilterCallbackFooter["post"]=this.perFilterCallback["post"];
    this.perFilterCallbackFooter["thisArg"]=this;
    this.perFilterCallbackFooter["render"]=function(container,filter){
    	var labels={
    			filter_by_category:"Category",
    			filter_by_collection:"Collection",
    			filter_by_brand:"Designer",
    			filter_by_stone:"Gemstone",
    			filter_by_metal:"Metal",
    			filter_by_occasion:"Occasion",
    			filter_by_recipient:"Recipient",
    			filter_by_room:"Room",
    			filter_by_style:"Style",
    			filter_by_type:"Type",
    			filter_by_price:"Price"
    			};
    	
    	var listItem=jQuery("<li></li>").appendTo(container);
    	var label=jQuery("<label></label>").appendTo(listItem);
    	label.attr("for",filter.attributes.name);
    	label.attr("class","label");
    	label.text(varUtils.isDef(labels[filter.attributes.name])?labels[filter.attributes.name]:"No Label");
    	
    	this.solrFacetUtils.filterCallbacks.render.call(this.solrFacetUtils,listItem,filter);
    }
    
    this.perTopLevelCatCallback=new Object();
    this.perTopLevelCatCallback["thisArg"]=this.perTopLevelCatCallback;
    this.perTopLevelCatCallback["solrFacetUtils"]=this.solrFacetUtils;
    this.perTopLevelCatCallback["render"]=function(container,filter,filterItem,index){
    	var topLevelCats=["engagement & wedding bands","jewelry","gifts","tableware & entertaining","home decor","bath"];
    	if (topLevelCats.indexOf(filterItem.term.toLowerCase())>=0){
    		this.solrFacetUtils.filterCallbacks.itemRender(container,filter,filterItem,index);
    	}
    };
    
    this.perTECatCallback=new Object();
    this.perTECatCallback["thisArg"]=this.perTopLevelCatCallback;
    this.perTECatCallback["solrFacetUtils"]=this.solrFacetUtils;
    this.perTECatCallback["render"]=function(container,filter,filterItem,index){
    	var topLevelCats=["bar accessories","casual dinnerware","flatware","formal china","stem and barware"];
    	if (topLevelCats.indexOf(filterItem.term.toLowerCase())>=0){
    		this.solrFacetUtils.filterCallbacks.itemRender(container,filter,filterItem,index);
    	}
    };
    
    this.priceCallback=new Object();
    this.priceCallback["thisArg"]=this;
    this.priceCallback["render"]=function(container,filter,filterItem,index){
    	if (filter.attributes.name=="filter_by_price") {
			var item=new Object();
			item["term"]=filterItem.term;
			item["label"]=this.solrFacetUtils.formatters.formatPrice(filterItem.label);
			filterItem=item;
    	}
    	this.solrFacetUtils.filterCallbacks.itemRender(container,filter,filterItem,index);
    };
}

MCFinaSearchUtils.prototype.setSolrFacetUtils=function(solrFacetUtils){
	this.solrFacetUtils=solrFacetUtils;
}

/**
 * Sets up internal data structures.
 */
MCFinaSearchUtils.prototype.init=function(searchResponse, selectedValues){
	this.selectedValues=selectedValues;
	
	var json=searchResponse;
	if (varUtils.isDef(searchResponse)){
		json=varUtils.stringToJSON(json);
		
		if (!varUtils.isDef(json["searchFailed"]) || !json["searchFailed"]){
			this.data=this.solrFacetUtils.convertFacetsToObjects(json,1);
		}
	}
}

MCFinaSearchUtils.prototype.uriDecode=function(value){
	var decoded=value;
	if (varUtils.hasValue(value)){
		decoded=decodeURIComponent(value);
	}
	
	return decoded;
	
}
/**
 * Drop down factory. Builds a set of drop downs for <code>collection</code>. You'll need to initialize
 * this class with the Solr data before calling this function as that is what the drop downs are populated with.
 */
MCFinaSearchUtils.prototype.buildFilters=function(collection,eventHandler){
	var filters=null;
	if (varUtils.isDef(this.data) && varUtils.isDef(this.data.facetFields)){
		var facetFields=this.data.facetFields;
		if (varUtils.isDef(collection)){
			var collections=this.dropDownCollections[collection];
			filters=new Array();
			var domUtils=new DomUtils();
			for (var i=0;i<collections.length;++i){
				if (collections[i]=="designer"){
					filters.push(domUtils.buildDomObject({name:"filter_by_brand","class":"select"},[eventHandler],facetFields.facet_brand,this.uriDecode(this.selectedValues.filter_by_brand)));
				} else if (collections[i]=="category"){
					filters.push(domUtils.buildDomObject({name:"filter_by_category","class":"select"},[eventHandler],facetFields.facet_category,this.uriDecode(this.selectedValues.filter_by_category)));
				} else if (collections[i]=="collection"){
					filters.push(domUtils.buildDomObject({name:"filter_by_collection","class":"select"},[eventHandler],facetFields.facet_collection,this.uriDecode(this.selectedValues.filter_by_collection)));
				} else if (collections[i]=="metal"){
					filters.push(domUtils.buildDomObject({name:"filter_by_metal","class":"select"},[eventHandler],facetFields.facet_metal,this.uriDecode(this.selectedValues.filter_by_metal)));
				} else if (collections[i]=="occasion"){
					filters.push(domUtils.buildDomObject({name:"filter_by_occasion","class":"select"},[eventHandler],facetFields.facet_occasion,this.uriDecode(this.selectedValues.filter_by_occasion)));
				} else if (collections[i]=="pattern"){
					filters.push(domUtils.buildDomObject({name:"filter_by_pattern","class":"select"},[eventHandler],facetFields.facet_pattern,this.uriDecode(this.selectedValues.filter_by_pattern)));
				} else if (collections[i]=="price"){
					filters.push(domUtils.buildDomObject({name:"filter_by_price","class":"select"},[eventHandler],facetFields.price,this.uriDecode(this.selectedValues.filter_by_price),this.priceCallback));
				} else if (collections[i]=="recipient"){
					filters.push(domUtils.buildDomObject({name:"filter_by_recipient","class":"select"},[eventHandler],facetFields.facet_recipient,this.uriDecode(this.selectedValues.filter_by_recipient)));
				} else if (collections[i]=="room"){
					filters.push(domUtils.buildDomObject({name:"filter_by_room","class":"select"},[eventHandler],facetFields.facet_room,this.uriDecode(this.selectedValues.filter_by_room)));
				} else if (collections[i]=="stone"){
					filters.push(domUtils.buildDomObject({name:"filter_by_stone","class":"select"},[eventHandler],facetFields.facet_stone,this.uriDecode(this.selectedValues.filter_by_stone)));
				} else if (collections[i]=="style"){
					filters.push(domUtils.buildDomObject({name:"filter_by_style","class":"select"},[eventHandler],facetFields.facet_style,this.uriDecode(this.selectedValues.filter_by_style)));
				} else if (collections[i]=="type"){
					filters.push(domUtils.buildDomObject({name:"filter_by_type","class":"select"},[eventHandler],facetFields.facet_type,this.uriDecode(this.selectedValues.filter_by_type)));
				} else if (collections[i]=="topLevelCategory"){
					//Build data
					filters.push(domUtils.buildDomObject({name:"filter_by_category","class":"select"},[eventHandler],facetFields.facet_category,this.uriDecode(this.selectedValues.filter_by_category),this.perTopLevelCatCallback));
				} else if (collections[i]=="teDesignerCategory"){
					//Build data
					filters.push(domUtils.buildDomObject({name:"filter_by_category","class":"select"},[eventHandler],facetFields.facet_category,this.uriDecode(this.selectedValues.filter_by_category),this.perTECatCallback));
				}
			}
		}
	}
	
	return filters;
}

/**
 * Builds and renders the drop downs. Will initialize with the passed in data object/string if it hasn't been done yet.
 */
MCFinaSearchUtils.prototype.installFilters=function(dropDowns,data,selectedValues){
	try {
		if (varUtils.isDef(data) && varUtils.isDef(selectedValues)){
			this.init(data,selectedValues);
		}
		if (varUtils.isDef(window["searchType"])){
			var eventHandler=this.submitHandler;
			var filterCallback=this.perFilterCallback;
			
			var vertFilters=jQuery("ol#searchFilterFormControls");
			var horzFilters=jQuery("fieldset#searchFilterFormControls");
			if (vertFilters.length>0){
				eventHandler=this.updateHandler;
				filterCallback=this.perFilterCallbackFooter;
				if (dropDowns=="engagementWeddingBand"){
					dropDowns=dropDowns.concat("Footer");
				}
			} else if (searchType=="cat_gifts_search"){
				//Extra help for the gifts category
				var pageTitle=jQuery("h2.pagetitle");
				if (pageTitle.length>0){
					var title=pageTitle[0].innerHTML.toLowerCase();
					if (title=="for baby"){
						dropDowns="giftsForBaby";
					} else if (title=="frames"){
						dropDowns="giftsFrame";
					}
				}
			}
			
			var filters=this.buildFilters(dropDowns,eventHandler);
			this.solrFacetUtils.renderFilters(jQuery("#searchFilterFormControls"),filters,filterCallback);
			this.installMissingFilters(dropDowns);
		}
	} catch (e){
		//silence
		alert(e);
	}
}

MCFinaSearchUtils.prototype.installMissingFilters=function(dropDowns){
	var startIndex="filter_by_".length;
	var collections=this.dropDownCollections[dropDowns]
	for (var filter in this.selectedValues){
		if (varUtils.hasValue(this.selectedValues[filter]) && filter.indexOf("filter_by_")==0){
			var filterName=filter.substr(startIndex);
			var index=collections.indexOf(filterName);
			if (!(index>=0)){
				var input=jQuery("<input type='hidden'/>").appendTo(jQuery("#searchFilterForm"));
				input.attr("name",filter);
				input.attr("value",this.selectedValues[filter]);
			}
		}
	}
}

/**
 * Initalizes and installs search related functionality on the page:
 * <ul><li>Autocomplete</li><li>Filters</li><li>Term suggestion (for misspellings)</li></ul>
 */
MCFinaSearchUtils.prototype.initSearch=function(dropDowns,data,selectedValues){
	this.init(data,selectedValues);
	this.installAutocomplete(contextPath+"/views/common/search/autocompleteProxy.jsp")
	
	var searchSuggestions=jQuery("div#search_suggestions");
	if (searchSuggestions.length>0){
		(new SolrTermSuggest()).renderTermSuggestions(jQuery("#search_suggestions"),(contextPath+"/sitesearch/search_do"),varUtils.stringToJSON(data));
	} else {
		//On search results page.
		if (window.location.pathname.indexOf("search_do")>=0){
			this.installFilters(dropDowns);
		} else {
			var liveQuery=true;
			var filterForm=jQuery("form#searchFilterForm");
			if (filterForm.length>0){
				if (liveQuery){
					this.installLiveFilters();
				} else {
					this.init(data,selectedValues);
					this.installFilters(dropDowns);
				}
			}
		}
	}
}

/**
 * Adapts JQuery event handling mechanism to our classes, that is, the this argument
 * and parameters are pulled from the event object itself (you'll obviously need to set this up
 * when you create your events).
 */
MCFinaSearchUtils.prototype.eventHandlerProxy=function(event){
	event.data.handler.apply(event.data.thisArg,event.data.args);
}

/**
 * Event handler for filter change actions. Just submits the parent form.
 */
MCFinaSearchUtils.prototype.filterSearchResults=function(form,pageField,page){
	if (varUtils.isDef(pageField)){
		pageField.val(page);
	}
	form.submit();
}

/**
 * Handles the change events from filters so that the remaining filters contain mutually
 * applicable values.
 */
MCFinaSearchUtils.prototype.updateFilters=function(form){
    var params=new Object();
    params["search_type"]="filter_refresh";
    params["resultSetSize"]=0;
    params["primary_search_type"]=form[0].search_type.value;
    var selectedValues=new Object();
    var selectBoxes=jQuery("select[name^='filter_by']");
    for (var i=0;i<selectBoxes.length;++i){
	    var value=selectBoxes[i].value;
	    if (varUtils.hasValue(value)){
	    	var decoded=decodeURIComponent(value);
		    params[selectBoxes[i].name]=decoded;
		    selectedValues[selectBoxes[i].name]=decoded;
	    }
    }
    var solrWrapper=this;
    jQuery.getJSON(form[0].action,params,
            function(responseData){
	    	jQuery("ol#searchFilterFormControls").empty();
    	    solrWrapper.installFilters(dropDownSet,responseData, selectedValues);
    	});
}

/**
 * Sets up the autocomplete plug in on the global search box. 
 */
MCFinaSearchUtils.prototype.installAutocomplete=function(proxy){
	var autocomplete=new SolrAutocomplete();
	autocomplete.installAutocomplete(proxy, jQuery("#search"), ["facet_brand"], ["name","sku","image_url","is_pattern"]);
}
/**
 * Builder for live search query. Returns results to populate the filters.
 */
MCFinaSearchUtils.prototype.installLiveFilters=function(){
	var url="/mcfina_search";
//	var url=contextPath+"/views/common/search/solrProxy.jsp";
	var solrQueryUtils=new SolrQueryUtils(url,"json");

	solrQueryUtils.addFacetParam("f.facet_brand.facet.limit",-1);
	solrQueryUtils.addFacetParam("f.facet_collection.facet.limit",-1);
	solrQueryUtils.addFacetParam("f.facet_pattern.facet.limit",-1);

	solrQueryUtils.addFacetField("sort_name");
	solrQueryUtils.addFacetField("facet_brand");
	solrQueryUtils.addFacetField("facet_category");
	solrQueryUtils.addFacetField("category_id");
	solrQueryUtils.addFacetField("facet_metal");
	solrQueryUtils.addFacetField("facet_pattern");
	solrQueryUtils.addFacetField("facet_collection");
	solrQueryUtils.addFacetField("facet_stone");
	solrQueryUtils.addFacetField("facet_type");
	solrQueryUtils.addFacetField("facet_style");
	solrQueryUtils.addFacetField("facet_room");
	solrQueryUtils.addFacetField("facet_recipient");
	solrQueryUtils.addFacetField("facet_occasion");
	solrQueryUtils.addFacetField("product_attributes");
	
	
	var searchType=jQuery("form#searchFilterForm input[name='search_type']").val();
	if (searchType=="cat_gifts_search"){
		solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[0,5000]));
		solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[5000,10000]));
		solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[15000,20000]));
		solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[20000,25000]));
	} else {
		solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[0,25000]));
	}

	solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[25000,50000]));
	solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[50000,75000]));
	solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[75000,100000]));
	solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[100000,150000]));
	solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[150000,200000]));
	solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[200000,250000]));
	solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[250000,300000]));
	solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[300000,400000]));
	solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[400000,500000]));
	solrQueryUtils.addFacetQuery(solrQueryUtils.makeRangeParameter(false,true,false,true,"price",[500000,Infinity]));

	var finaSearchUtils=this;
	var jsonCallback=function(data,status){
		finaSearchUtils.installFilters(dropDownSet, data, selectedValues);
	}
	
	var updateCategoryIdList=function(data,status){
		solrQueryUtils.addQueryParameter(solrQueryUtils.makeMultiValueParameter(true,false,"category_id",data));
	}
	
	try {
		var params=new Object();
		if (searchType=="manufacturer_cat_search"){
			var brand=jQuery("form#searchFilterForm input[name='man_name']").val();
			solrQueryUtils.addQueryParameter(solrQueryUtils.makeSingleValueParameter(true,false,"facet_brand",brand));
		}
		
		if (!(dropDownSet=="tablewareAndEntertainingDesigner" || dropDownSet=="tablewareAndEntertaining")){
			solrQueryUtils.addQueryParameter(solrQueryUtils.makeSingleValueParameter(false,false,"is_pattern","true"));
			solrQueryUtils.addQueryParameter(solrQueryUtils.makeRangeParameter(false,false,false,true,"price",[-Infinity,0]));
		}
		
		var catid=jQuery("form#searchFilterForm input[name='cat_id']").val();
		params["catId"]=catid;
		jQuery.get(contextPath+"/views/common/search/solrProxyCatalogHelper.jsp",params,
				function(data,status){
			updateCategoryIdList(data,status);
			solrQueryUtils.forwardToProxy(0,0,null,jsonCallback,false);
		},"json");
    } catch (e){
        alert(e);
    }
}

/**
 * Yahoo User Interface version of autocomplete. Works but conflicts with Fina's styling.
 */
/*
MCFinaSearchUtils.prototype.installAutocompleteYUI=function(proxy, targetElementId, targetContainerId){
	var dsXHR = new YAHOO.util.XHRDataSource(proxy);
	dsXHR.responseType=YAHOO.util.XHRDataSource.TYPE_JSON;
	dsXHR.responseSchema = {
	        fields : [
	            { key: "name" }
	        ]
	    };
	            
	dsXHR.parseJSONData=function(request , response){
	    var data=new Object();
	    data["results"]=new Array();

	    var iterator=function(title,yuiSchemaKey,items){
	        var values=new Array();
	    	for (var i=0; i<items.length;i+=2){
	            var item=new Object();
	            item[yuiSchemaKey]=items[i];
	            values.push(item);
	        }
	        return values;
	    }
	    
	    try {
	    	data["results"]=data["results"].concat(iterator("Brand","name",response.facet_counts.facet_fields.facet_brand));
	    } catch (e){
	        //alert(e);
	        data=false;
	    }

	    return data;
	}

	var solrQueryUtils=new SolrQueryUtils(proxy,"json");
	solrQueryUtils.addFacetField("facet_brand");

	var aComplete=new YAHOO.widget.AutoComplete(targetElementId,targetContainerId, dsXHR);
	aComplete.generateRequest=function(sQuery){
		solrQueryUtils.resetQuery();
		solrQueryUtils.addQueryParameter(solrQueryUtils.makeSingleValueParameter(false,true,"brand",sQuery+"*"));
	    var query=solrQueryUtils.getQueryString(0,0,false,true);
		return "?"+query;
	}
}
*/

function MCFinaPaginationUtils(solrResultPaginator,data){
	this.solrResultPaginator=solrResultPaginator;
	this.data=null;
	if (varUtils.hasValue(data)){
		this.data=varUtils.stringToJSON(data);
	}
}

MCFinaPaginationUtils.prototype.setResultPaginator=function(resultPaginator){
	this.solrResultPaginator=resultPaginator;
}

/**
 * Renders the pagination controls and search results.
 */
MCFinaPaginationUtils.prototype.renderPage = function(container, imageSize, linkType, insert_zoomed_image) {
	try {
		var callbacks = new Object();
		
		callbacks["render"] = function(container, documents, document, index) {
			var listItem = jQuery('<li></li>').appendTo(container);
			if (insert_zoomed_image) {
				listItem.attr("id","prod_image_li_"+ document.id);
				listItem.attr("style","z-index: 10; min-height: 210px;");
			}

			var anchor = jQuery("<a></a>").appendTo(listItem);
			var link = document[linkType].replace(/^null/, contextPath);
			anchor.attr("href", "/" + link);
			anchor.attr("title", document.name + " by " + document.brand);

			if (!insert_zoomed_image) {
				
				// when not inserting the zoomed-in image, we still need to show the regular image.
				var imageUtils = new ImageUtils(contextPath, staticImgPath, fluidBaseItemURL);
				var imageTag = imageUtils.getProductImgTag(document.sku, imageSize, document.name, false,
								(!varUtils.isDef(document.image_url) || (document.pattern && document.image_url == "images/placeholder100x100.jpg")),
								false);
				jQuery(imageTag).appendTo(anchor);
			}
			
			jQuery("<br/>").appendTo(anchor);
			var patternName = undefined;
			if (varUtils.isDef(document.pattern_name) && document.pattern_name.length > 0) {
				if (typeof document.pattern_name == "string") {
					patternName = document.pattern_name;
				} else {
					patternName = document.pattern_name[0];
				}
			}

			(jQuery("<span></span>").appendTo(anchor)).text(varUtils.isDef(patternName) ? patternName : document.name);
			jQuery("<br/>").appendTo(anchor);
			(jQuery("<span></span>").appendTo(anchor)).text("by " + document.brand);
			
			if (varUtils.isDef(patternName)) {
				jQuery("<br/>").appendTo(anchor);
				(jQuery("<span></span>").appendTo(anchor)).text(document.name);
			}

			//The multiplier depends on how the price is stored in the db - check to ensure this is correct.
			var unformatted = parseInt(document.price * 1);
			var price = varUtils.formatCurrency(convert_to_dollars(unformatted));
			jQuery("<br/>").appendTo(listItem);
			(jQuery("<span></span>").appendTo(listItem)).text(((unformatted + 0) > 0 ? "$" + price : ""));
		}

		var domUtils = new DomUtils();
		this.solrResultPaginator.renderPagination((jQuery("<p></p>").appendTo(container)).attr("id", "upperPaginationContainer").attr("class", "paging"),this.data.response.numFound);
		(new SolrDocumentUtils()).renderDocuments((jQuery("<div></div>").appendTo(container)).attr("class", "products"),domUtils.buildDomObject(null, null, this.data.response.docs, null, callbacks));
		this.solrResultPaginator.renderPagination((jQuery("<p></p>").appendTo(container)).attr("id", "lowerPaginationContainer").attr("class", "paging"),this.data.response.numFound);
		
		if (insert_zoomed_image) {
			
			// padding so that the bottom of the zoomed-in image doesn't get hidden by the footer.
			(jQuery('<div><br></div>').appendTo(container)).attr('style', 'clear: both');
			
			var static_linking = '';
			if (linkType == 'static_url') {
				static_linking = 't';
			}

			for (var i = 0; i < this.data.response.docs.length; i++) {
				insert_image('medium', 'prod_image_li_' + this.data.response.docs[i].id, this.data.response.docs[i], fluidBaseItemURL, static_linking, 'before', true, true, false);
			}
		}
	} catch (e) {
		//alert(e);
	}
}

function MCFinaPageUtils(){}
/**
 * Check if the browser has flash enabled and insert a static image if not.
 */
MCFinaPageUtils.prototype.checkFlash=function(){
	var productFlashContainer="div#display:905:SKU:detail.fluid-display";
	
	if (!pageInfo.envInfo.isFlashEnabled){
        if (varUtils.isDef(pageInfo.product) && varUtils.hasValue(pageInfo.product.sku)){
            var fluidContainer=jQuery(productFlashContainer.replace(/SKU/,pageInfo.product.sku));
            if (fluidContainer.length>0){
                var imageTag=(new ImageUtils(pageInfo.pathInfo.contextPath,pageInfo.pathInfo.staticImgPath,pageInfo.pathInfo.fluidBaseItemURL)).
                imageUtils.getProductImgTag(pageInfo.product.sku,"detail",pageInfo.product.name,true,false,false);
                jQuery(imageTag).appendTo(fluidContainer);
            }
        }
    }
}
/**
 * Check if this page is to be printed.
 * 
 * @param checkFlash - Set to <code>true</code> if you also want to check if shockwave/flash is enabled.
 */
MCFinaPageUtils.prototype.printCheck=function(checkFlash){
	var isPrint=urlUtils.getQueryStringParam("print");
    if (varUtils.isTrue(isPrint) && varUtils.isDef(product)){
        var imageUtils=new ImageUtils(contextPath,staticBaseItemURL,fluidBaseItemURL);
        jQuery("div.static-display").append(imageUtils.getProductImgTag(product.sku,"detail",product.name,true,false));
    } if (varUtils.isTrue(checkFlash)){
    	this.checkFlash();
    }
}