/**
 * 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.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, 0, 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: "get",
      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: 0,
        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();
};

