var select_search = false;				// true if they issue a search by modifying a select box selectedIndex (do not show location results)
var active_search = null;

// keep track of how results many we have displayed per class
var Search_count = 0;
var RelatedSearch_count = 0;
var MerchantSearch_count = 0;
var LocationSearch_count = 0;
var CitySearch_count = 0;
var ZipSearch_count = 0;

container_node_classes = ["result", "result_hover", "related_search", "merchant_search", "location_search"];

function SearchResult( data )
{
	this.data = data;
	
	this.documentFragment = SearchResult_DocumentFragment;
	this.toString = SearchResult_ToString;
}

function RelatedSearchResult( data )
{
	this.data = data;
	this.related = true;
	this.className = "related_search";
	
	this.documentFragment = SearchResult_DocumentFragment;
	this.toString = SearchResult_ToString;
}

function MerchantSearchResult( data )
{
	this.data = data;
	this.merchant = true;
	this.className = "merchant_search";
	
	this.documentFragment = SearchResult_DocumentFragment;
	this.toString = SearchResult_ToString;
}

function LocationSearchResult( obj )
{
	this.data = obj.d;
	this.address = obj.a;
	this.city = obj.c;
	this.distance = obj.m;
	
	this.documentFragment = LocationSearchResult_DocumentFragment;
	this.toString = LocationSearchResult_ToString;
}

function CitySearchResult( obj )
{
	this.data = 'city';
	this.city = obj.c;
	this.state = obj.s.toUpperCase();
	this.zip = obj.z;
	this.address = obj.a;
	this.county = obj.county;
	this.country = obj.country.toUpperCase();
	this.citysearch = true;
	
	this.documentFragment = LocationSearchResult_DocumentFragment;
	this.toString = CityZipSearchResult_ToString;
}

function ZipSearchResult( obj )
{
	this.data = 'zip';
	this.city = obj.c;
	this.state = obj.s.toUpperCase();
	this.zip = obj.z;
	this.address = obj.a;
	this.county = obj.county;
	this.country = obj.country.toUpperCase();
	this.zipsearch = true;
	
	this.documentFragment = LocationSearchResult_DocumentFragment;
	this.toString = CityZipSearchResult_ToString;
}

function SearchResult_DocumentFragment()
{
	var reg = new RegExp("("+ type_node.value.trim() +")", "ig");
	var data = this.toString().replace(reg, '<span class="match">$1</span>')
	var frag = document.createDocumentFragment();
	var text_container = document.createElement("SPAN");
	
	if ( typeof this.related != "undefined" )
		text_container.setAttribute("className", "related_search");
	else if ( typeof this.merchant != "undefined" )
		text_container.setAttribute("className", "merchant_search");
	
	text_container.innerHTML = data;
	frag.appendChild( text_container );
	
	if ( this.related )
		RelatedSearch_count += 1;
	else if ( this.merchant )
		MerchantSearch_count += 1;
	else
		Search_count += 1;

	return( frag );
}

function LocationSearchResult_DocumentFragment()
{
	var frag = document.createDocumentFragment();
	var text_container = document.createElement("SPAN");
	
	text_container.setAttribute("className", "location_search");
	
	text_container.innerHTML = this.toString();
	frag.appendChild( text_container );
	
	if ( this.citysearch )
		CitySearch_count += 1;
	else if ( this.zipsearch )
		ZipSearch_count += 1;
	else
		LocationSearch_count += 1;

	return( frag );
}

function SearchResult_ToString()
{
	return( this.data );
}

function LocationSearchResult_ToString()
{
	var distance = Math.round(this.distance);
	var data = '<span title="'+ this.address +', '+ this.city +'"><strong>'+ this.data +'</strong></span>';
	
	if ( distance <= 0 )
		return( data +" (less than 1 mile)");
	else
		return( data +" ("+ distance +" mile"+ (( distance > 1 ) ? "s" : "" ) +")" );
}

function CityZipSearchResult_ToString()
{
	var str = this.zip +' '+ this.city +' '+ this.state +' '+ this.county +' '+ this.country;
	var data = '<span><strong>'+ str +'</strong></span>';
	return( data );
}

function click_zipcity_result( node )
{
	var data = eval( node.getAttribute("data") );
	if ( typeof data.city != "undefined" )
	{
		type_form.city.value = data.city;
		type_form.state.value = data.state;
	} else
		type_form.zip.value = data.zip;
}

function fetch_data()
{
	if ( type_timer != null )
	{
		clearTimeout(type_timer);
		type_timer = null;
	}
	
	if ( conn.is_open )
		return;

	var name = type_node.getAttribute("name");
	var lenval = type_node.value.length;
	
	if ( !isNaN(type_node.value) && ( (name == "city" && lenval >= 2) || (name == "searchstr" && lenval >= 4) ) )
	{
		// assume user is typing a zipcode when a numeric value is inserted in the city field
		// swap to zip code gui and put them in the zipcode textbox

		var temp = type_node.value;
		
		if ( name == "city" )
			type_node.value = "enter city";
		else
			type_node.value = "enter search query";
		
		document.getElementById("zip_tab").onclick();
		type_node = type_node.form.zip;
		type_node.value = temp;
		type_node.focus();
		
		set_caret_position(type_node, type_node.value.length, type_node.value.length);
	}

	var searchtype = type_node.getAttribute("id");
	var query = "", val = type_node.value.trim();
	var check_len = 3;
	
	switch ( searchtype )
	{
		case "mall_city_search" :
		case "mall_state_search" :
			// this search does not conform to 'check_len'
			
			var city = document.getElementById("mall_city_search");
			var state = document.getElementById("mall_state_search");
			
			var range = document.getElementById("mallsearch_range");
			range = range.options[range.selectedIndex].value;
			
			if ( city.value.trim() != city.getAttribute("default") )
				query += "c="+ escape( city.value.trim() );
			else
				city = false;
			
			if ( state.value.trim() != state.getAttribute("default") && state.value.trim().length >= 2 )
				query = (( city ) ? query +"&" : "") +"s="+ escape( state.value.trim() );
			else
				state = false;
			
			if ( city || state )
				query += "&r="+ parseInt(range);
			
			type_node = city;
			
			break;
		
		case "mall_zip_search" :
			var zip = document.getElementById("mall_zip_search");
			var range = document.getElementById("mallsearch_range");
			range = range.options[range.selectedIndex].value;
			
			val = zip.value.trim();
			val = val.replace(/[^0-9\-]+/g, "");
			
			if ( val < check_len )
				return;
			
			query = "z="+ escape(val) +"&r="+ parseInt(range);
			break;
		
		case "mall_keyword_search" :
			var keywords = document.getElementById("mall_keyword_search");
			
			if ( (val = keywords.value.trim()) < check_len )
				return;
			
			if ( val != keywords.getAttribute("default") )
				query = "k="+ escape(val);
			
			break;
	}

	if ( query.length == 0 )
		return;
	
	// reset counts
	Search_count = 0;
	RelatedSearch_count = 0;
	MerchantSearch_count = 0;
	LocationSearch_count = 0;
	CitySearch_count = 0;
	ZipSearch_count = 0;

	var cats = document.getElementById("mallsearch_categories");
	var catid = cats.options[cats.selectedIndex].value;

	if ( catid != "-1" )
		query = "cid="+ parseInt(catid) +"&"+ query;
	
	if ( !simulate_search(query) )
	{
		conn.search = query;
		conn.val = val;
		conn.onSuccess = find_search_data;
		conn.send("get", location.href.replace(location.search, '') +"?mode=typeassist&"+ query);
	}
}

function find_search_data()
{
	var arr = eval(this.data);		// expecting JSON
	
	var selsearch = select_search;
	select_search = false;
	
	results_container.innerHTML = "";
	
	if ( arr.length == 0 )
		return;

	if ( arr[0].err == undefined )
	{
		window.search_data = arr;
		
		var i, p, x, xlen = arr.length, data_len;
		var city, state, zip, range, msg;
		var obj, objclass, gotdata = false;
		var frag = document.createDocumentFragment();
		
		for (x = 0; x < xlen; x++)
		{
			data_len = arr[x].length;
			if ( data_len > 0 )
			{
				switch ( type_node.getAttribute("id") )
				{
					case "mall_keyword_search" :
						if ( x == 0 ) objclass = "SearchResult";
						else if ( x == 1 ) objclass = "RelatedSearchResult";
						else if ( x == 2 ) objclass = "MerchantSearchResult";
						break;
					
					case "mall_zip_search" :
						if ( x == 0 ) objclass = "ZipSearchResult";
						else if ( x == 1 ) objclass = "LocationSearchResult";
						else if ( x == 2 ) objclass = "MerchantSearchResult";
						else if ( x == 3 ) objclass = "RelatedSearchResult";
						break;
					
					case "mall_city_search" :
					case "mall_state_search" :
						if ( x == 0 ) objclass = "CitySearchResult";
						else if ( x == 1 ) objclass = "LocationSearchResult";
						else if ( x == 2 ) objclass = "MerchantSearchResult";
						else if ( x == 3 ) objclass = "RelatedSearchResult";
						break;
				}
				
				for (i = 0; i < data_len; i++)
				{
					if ( /*(objclass == "SearchResult" && Search_count == 0) ||*/
							(objclass == "RelatedSearchResult" && RelatedSearch_count == 0) ||
							(objclass == "MerchantSearchResult" && MerchantSearch_count == 0) ||
							(objclass == "LocationSearchResult" && LocationSearch_count == 0) ||
							(objclass == "ZipSearchResult" && ZipSearch_count == 0) ||
							(objclass == "CitySearchResult" && CitySearch_count == 0)
					) {
						var fieldset = document.createElement("fieldset");
						var legend = document.createElement("legend");
						
						var category_str = "";
						if ( type_node.form.categories.selectedIndex > 3 )
							category_str = " in "+ type_node.form.categories[type_node.form.categories.selectedIndex].text;
						
						if ( objclass == "SearchResult" )
						{
							legend.appendChild( document.createTextNode("matches"+ category_str) );
							fieldset.setAttribute("class", "search_result");
						} else if ( objclass == "MerchantSearchResult" ) {
							if ( type_form.searchstr.value != "" && type_form.searchstr.value != "enter search query" )
								msg = 'merchants matching "'+ type_form.searchstr.value +'"'+ category_str;
							else
								msg = "merchant results"+ category_str;
							
							legend.appendChild( document.createTextNode(msg) );
							fieldset.setAttribute("class", "merchant_result");
						} else if ( objclass == "RelatedSearchResult" ) {
							if ( type_form.searchstr.value != "" && type_form.searchstr.value != "enter search query" )
								msg = 'related search phrases to "'+ type_form.searchstr.value +'"'+ category_str;
							else
								msg = "related search phrases"+ category_str;
							
							legend.appendChild( document.createTextNode(msg) );
							fieldset.setAttribute("class", "related_result");
						} else if ( objclass == "LocationSearchResult" ) {
							range = type_form.radius.options[type_form.radius.selectedIndex].value;
							city = type_form.city.value;
							state = type_form.state.value;
							zip = type_form.zip.value;
							
							msg = "within ";
							if ( range > 0 )
								msg += range +" mile"+ ((range != 1)?"s":"") +" of ";

							if ( city != "" && city != "enter city" )
							{
								msg += city;
								if ( state != "" && state != "state" )
									msg += ", "+ state;
							} else if ( zip != "" && zip != "enter zipcode" )
								msg += zip;
							
							legend.appendChild( document.createTextNode("merchants "+ msg + category_str) );
							fieldset.setAttribute("class", "merchant_result");
						} else if ( objclass == "ZipSearchResult" ) {
							if ( selsearch ) continue;																// don't show zip results unless it's a zip search
							
							legend.appendChild( document.createTextNode('zipcode matches') );
							fieldset.setAttribute("class", "search_result");
						} else if ( objclass == "CitySearchResult" ) {
							if ( selsearch ) continue;																// don't show city / state results unless it's a location search
							
							legend.appendChild( document.createTextNode('location matches') );
							fieldset.setAttribute("class", "search_result");
						}
						
						if ( legend.hasChildNodes() )
						{
							fieldset.appendChild( legend );
							frag.appendChild( fieldset );
						}
					}
					
					gotdata = true;
					obj = new window[objclass]( arr[x][i] );
					
					p = document.createElement("P");
					p.appendChild( obj.documentFragment() );
					p.onmouseover = rollover_type_search_result;
					p.onmouseout = rolloff_type_search_result;
					p.onclick = click_type_search_result;
					p.className = ( typeof obj.className != "undefined" ) ? obj.className : "result";
					
					p.setAttribute("data_index", i);
					p.setAttribute("hold_class", p.className);
					
					if ( objclass == "ZipSearchResult" || objclass == "CitySearchResult" )
					{
						p.setAttribute("clickfunc", "click_zipcity_result");
						
						if ( objclass == "ZipSearchResult" )
							p.setAttribute("data", "({zip:\""+ obj.zip +"\"})");
						else
							p.setAttribute("data", "({city:\""+ obj.city +"\", state:\""+ obj.state +"\"})");
					} else
						p.setAttribute("data", obj.data);

					frag.appendChild( p );
				}
			}
		}
		
		if ( !search_cached(this.search) )
		{
			if ( search_cache_num + 1 > search_cache_len )
				search_cache_num = 0;
			
			search_cache[ search_cache_num++ ] = {query:this.search, data:this.data};
		}
		
		display_results_container();
		
		if ( !gotdata )
			no_search_data();
		else
		{
			results_container.appendChild( frag );
			get_container_nodes(1);
			open_results_container();
		}
	} else
		alert( arr[0].err );
}

function display_results_container()
{
	if ( results_container.getAttribute("open") == "0" && results_container.style.display != "block" )
	{
		var parent_info = get_node_info( document.getElementById("mall_search_parent") );
		var node_info = get_node_info( type_node );
		
		results_container.style.display = "block";
		results_container.style.height = "0px";
		results_container.style.overflow = "hidden";
		results_container.style.top = (node_info.y + node_info.h + 5) +"px";
		results_container.style.left = (parent_info.x + ((dom)?1:1)) +"px";
		results_container.style.width = (document.getElementById("mall_search_container").offsetWidth - ((dom)?2:2)) +"px";			// for some reason it's 2px too big, probably a padding / margin bug in css
	}
}

function check_focus_value(input, val)
{
	if ( input.value.trim() == val )
		input.value = '';
}

function check_blur_value(input, val)
{
	if ( input.value.trim() == '' )
		input.value = val;
}

function show_dynamsearch(id)
{
	if ( !active_search )
	{
		var nodes = getElementsByClassName("active_searchtab", document.body);
		if ( nodes.length == 0 )
		{
			throw("There is no active search tab");
			return( false );
		} else
			active_search = nodes[0].getAttribute("id").split('_')[0];
	}
	
	document.getElementById(active_search +"_search").className = "dynamsearch";
	document.getElementById(active_search +"_tab").className = "searchtab";
	
	document.getElementById(id +"_search").className = "active_dynamsearch";
	document.getElementById(id +"_tab").className = "active_searchtab";
	active_search = id;
}

function change_mallsearch_select()
{
	var val = type_node.value.trim();
	select_search = true;
	if ( val.length > 0 && val != type_node.getAttribute("default") )
		fetch_data();
}

function click_type_search_result()
{
	var func = this.getAttribute("clickfunc");
	if ( typeof window[func] == "function" )
		window[func](this);
	else
		document.getElementById("mall_keyword_search").value = this.getAttribute("data");

	if ( typeof do_type_search_click == "function" )
		do_type_search_click(this);
	
	type_form.submit();
}

function init_mall_search()
{
	search_cache_len = 35;
	
	document.getElementById("mall_keyword_search").setAttribute("default", "enter search query");
	document.getElementById("mall_zip_search").setAttribute("default", "enter zip code");
	document.getElementById("mall_city_search").setAttribute("default", "enter city");
	document.getElementById("mall_state_search").setAttribute("default", "state");
}

function dump( str )
{
	var node = document.getElementById("dump");
	var p = document.createElement("P");
	p.appendChild( document.createTextNode( str ) );
	
	node.appendChild( p );
}

if ( window.attachEvent )
	window.attachEvent("onload", init_mall_search);
else
	window.addEventListener("load", init_mall_search, false);