/**
 * The constructor for the distance_search_object class.
 * Takes the DOM ID of the input field you wish to
 * use, and the URL of the script you want to run
 * to do the search.
 *
 * @param {string} pId The DOM ID of the input field
 * @param {string} pScriptUrl
 * @return {boolean}
 * @constructor
 */
function distance_search_object ( pId, pScriptUrl )
{
	if ( ! pId )
	{
		return false;
	}
	
	this.refRoot = pId;
	
	if ( ! ( this.ref = $(pId) ) )
	{
		return false;
	}
	
	if ( ! ( this.spinner = $(pId+"_spinner") ) )
	{
		return false;
	}
	
	if ( ! ( this.results = $(pId+"_results") ) )
	{
		return false;
	}
		
	if ( ! ( this.type = $(pId+"_type") ) )
	{
		return false;
	}
		
	if ( ! ( this.distance = $(pId+"_distance") ) )
	{
		return false;
	}
	
	if ( ! ( this.clearButton = $(pId+"_clear") ) )
	{
		return false;
	}

	if ( ! ( this.submitButton = $(pId+"_submit") ) )
	{
		return false;
	}

	this.auto_buffer = this.ref.value;

	var self = this;
	this.script_url = pScriptUrl;
	this.auto_timeout = setTimeout( function ( ) { self.clear_timeout(); }, "clear_timeout", 1000 );

	this.clear = true;
	this.dont_reset = false;
	this.ref.onkeydown = this.reset_timeout.bind(this);
	this.ref.onmouseup = this.init.bind(this);
	this.submitButton.onclick = this.search.bind(this);
	this.clearButton.onclick  = this.clear_search.bind(this);
	
	this.ref.style.color = "#999";
	this.ref.value = "Search";
	
	// Check for saved state and re-run the search if necessary...
	if ( this.getCookie( 'quickSearchCriteria_' + this.refRoot ) != "" )
	{
		this.init();
		this.ref.value = this.getCookie( 'quickSearchCriteria_' + this.refRoot );
		this.type.selectedIndex = ( this.getCookie( 'quickSearchType_' + this.refRoot ) );
		this.distance.selectedIndex = ( this.getCookie( 'quickSearchDistance_' + this.refRoot ) );
		this.search();
	}
}


/**
 * Utility function to set a cookie. Encapsulated in the distance_search_object
 * class to avoid polluting the global namespace.
 *
 * @param {string} c_name The name of the cookie
 * @param {string} value The value of the cookie
 * @param {integer} expiredays The number of days you want the cookie to last
 */
distance_search_object.prototype.setCookie = function (c_name,value,expiredays)
{
	var exdate = new Date();
	exdate.setDate( exdate.getDate() + expiredays );
	document.cookie = c_name + "=" + escape (value)+ ((expiredays==null) ? "" : ";expires=" + exdate.toGMTString()) + ";path=/";
};


/**
 * Utility function to retrieve a cookie. Encapsulated in the
 * distance_search_object class to avoid polluting the global namespace.
 *
 * @param {string} c_name The name of the cookie
 * @return {string} The value of the cookie
 */
distance_search_object.prototype.getCookie = function (c_name)
{
	if (document.cookie.length > 0)
	{
		c_start = document.cookie.indexOf(c_name + "=");
		if (c_start != -1)
		{ 
			c_start = c_start + c_name.length + 1; 
			c_end = document.cookie.indexOf(";", c_start);
			if (c_end == -1)
			{
				c_end = document.cookie.length;
			}
			return unescape(document.cookie.substring(c_start, c_end));
		}
	}
	return "";
};


/**
 * Search function.
 */
distance_search_object.prototype.search = function( )
{
	var self = this;
	
	this.setCookie( 'quickSearchCriteria_' + this.refRoot, this.ref.value, 1 );
	this.setCookie( 'quickSearchType_' + this.refRoot, this.type.selectedIndex, 1 );
	this.setCookie( 'quickSearchDistance_' + this.refRoot, this.distance.selectedIndex, 1 );
	this.results.style.display = 'none';
	this.spinner.style.display = 'block';
	
	new Ajax.Request(
		this.script_url,
		{
			method: "post",
			onSuccess: function ( response )
			{
				eval( self.refRoot + "_run( self, eval( response.responseText ) )" );
			},
			onFailure: function ( ) { alert( "Distance Search Failed, Please try again" ); },
			parameters:
			{
				search_criteria: this.ref.value,
				search_type: this.type.value,
				search_distance: this.distance.value
			}
		}
	);
};


/**
 * Checks to see if the contents of the search field
 * have changed, and if so, re-run the search.
 */
distance_search_object.prototype.check_search = function ( )
{
	var search_criteria = this.ref.value;
	
	if ( search_criteria != this.auto_buffer )
	{
		this.auto_buffer = search_criteria;
		this.results.style.display = "none";
		this.spinner.style.display = "block";
		this.search();
	}
};


/**
 * Set as the keyDown handler for the search input field. Every time
 * a key is pressed, a 1 second timer is re-set. The timer calls
 * check_search() upon firing, so as long as a key is struck every
 * second, the search will never execute.
 *
 * @param {event} evt The browser event (non-IE systems only.)
 * @return {boolean} Whether to continue resetting
 */
distance_search_object.prototype.reset_timeout = function ( evt )
{
	var self = this;
	var e = evt ? evt.which : window.event.keyCode;
	clearTimeout(this.auto_timeout);
	
	if ( e == 13 )
	{
		this.search();
		return false;
	}

	this.auto_timeout = setTimeout( function ( ) { self.clear_timeout(); }, 1000 );
	this.clear = false;
	
	return true;
};


/**
 * For now, just runs check_search.
 */
distance_search_object.prototype.clear_timeout = function ( )
{
	this.check_search();
};


/**
 * Set as the mouseUp handler for the input field. Clears out
 * the Search tag and sets the field's text color to black.
 */
distance_search_object.prototype.init = function ( )
{
	if ( ! this.dont_reset )
	{
		this.ref.style.color = "#000";
		this.ref.value = "";
		this.dont_reset = true;
	}
};


/**
 * Clears the search and loads a fresh page.
 */
distance_search_object.prototype.clear_search = function ( )
{
	this.setCookie( 'quickSearchCriteria_' + this.refRoot, "", 1 );
	this.ref.style.color = "#999";
	this.ref.value = "";
	this.dont_reset = false;
	this.search();
};
