// Autocompleter-based Search Object
// Author: Nick Benik
// Version: 7.02.2008
// Description: AJAX Object for custom search functionality
//
// Based on code from:
// ----------------------------------------------------------------------------------------------
// script.aculo.us controls.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//           (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
//           (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
// Contributors:
//  Richard Livsey
//  Rahul Bhargava
//  Rob Wills
// 
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/
// ----------------------------------------------------------------------------------------------



if(typeof Effect == 'undefined')

  throw("controls.js requires including script.aculo.us' effects.js library");



var sbCustomSearch = Class.create({

  initialize: function(element, update, url, section, options) {

    element			= $(element);

    this.element	= element; 

    this.update		= $(update);  

    this.hasFocus	= false; 

    this.changed	= false; 

    this.active		= false; 

    this.page		= 0;

	this.lastResults		= {};

    this.oldElementValue	= this.element.value;

    this.url				= url;

	this.ajaxPending		= false;

	this.site_section = section; 

    if(this.setOptions)

      this.setOptions(options);

    else

      this.options = options || { };



    this.options.asynchronous  	= true;

    this.options.onComplete    	= this.onComplete.bind(this);

    this.options.defaultParams 	= this.options.parameters || null;

    this.options.paramName    = this.options.paramName || this.element.name;

    this.options.tokens       = this.options.tokens || [];

    this.options.frequency    = this.options.frequency || 0.4;

    this.options.minChars     = this.options.minChars || 1;

    this.options.onShow       = this.options.onShow || 

      function(element, update){ 

        Effect.Appear(update,{duration:0.15});

      };

    this.options.onHide = this.options.onHide || 

      function(element, update){ new Effect.Fade(update,{duration:0.15}) };



    this.observer = null;

    

    this.element.setAttribute('autocomplete','off');



    Element.hide(this.update);



    Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));

    Event.observe(this.element, 'focus', this.onFocus.bindAsEventListener(this));

    Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));

  },



  show: function() {

    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);

  },

  

  hide: function() {

	if (this.hasFocus) return;

    this.stopIndicator();
	
    if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);

  },



  startIndicator: function() {
	
	if(this.options.indicator) Element.show(this.options.indicator);

  },



  stopIndicator: function() {

    if(this.options.indicator) Element.hide(this.options.indicator);

  },



  onKeyPress: function(event) {

    if(this.active)

      switch(event.keyCode) {

       case Event.KEY_TAB:

       case Event.KEY_RETURN:

         Event.stop(event);

       case Event.KEY_ESC:

         this.hide();

         this.active = false;

         Event.stop(event);

         return;

       case Event.KEY_LEFT:

       case Event.KEY_RIGHT:

         return;

       case Event.KEY_UP:

         this.pagePrevious();

         Event.stop(event);

         return;

       case Event.KEY_DOWN:

         this.pageNext();

         Event.stop(event);

         return;

      }

     else 

       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || 

         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;



    this.changed = true;

    this.hasFocus = true;

	

    if(this.observer) clearTimeout(this.observer);

      this.observer = 

        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);

  },



  activate: function() {

	if (this.hasFocus) return;

    this.changed = false;

    this.hasFocus = true;

	this.page = 0;

	if (!this.element.value.blank()) {

		this.getUpdatedChoices();

	}

  },



  onFocus: function(event) {

    this.activate();

  }, 

  

  onBlur: function(event) {

    // needed to make click events working

    setTimeout(this.hide.bind(this), 250);

    this.hasFocus = false;

    this.active = false;     

  }, 

  

  render: function() {
	  
	

	// clear the results list

	var rmEl = this.update.select('.search_results_row');

	for (var i = 0; i<rmEl.length; i++) {

		// remove single result

		var tn = rmEl[i].parentNode;

		tn.parentNode.removeChild(tn);

	}

	delete rmEl;

	

	// populate the search footer section

	var searchFooter = this.update.select(".search_results_footer")[0];

	var resultLbl = searchFooter.select(".col_left")[0];

	if (this.lastResults.total > 0) {

		resultLbl.innerHTML = this.lastResults.resultmin + " - " + this.lastResults.resultmax + " of " + this.lastResults.total + " results";

	} else {
		
		//alert("No matching results.");
		resultLbl.innerHTML = "No matching results.";

	}

	

	// populate the results list

	var entryCount = this.lastResults.sresults.length;

	//alert(entryCount);
	//added 9/26/2008 ct
	if (entryCount==0) {
		entryCount = 1;	
	}
	
	for (var i = 0; i < entryCount; i++) {

		try {

			var recData = this.lastResults.sresults[i];

			// clone node

			var cloneDIV = $('CLONE_search_result_row').cloneNode(true);

			cloneDIV.setAttribute('id','search_result_row-'+i);

			if(recData.type == 'F'){

			cloneDIV.href = "javascript:contact.FAQSearch("+recData.id+")";

			} else {

			cloneDIV.href = "/scripts/php/search_router.php?type="+recData.type+"&id="+recData.id+"&section="+this.site_section;			 

			}

			// update copy

			var tn1 = cloneDIV.select('.search_results_row')[0];

			var tn2 = tn1.select('.text_description')[0];

			tn2.innerHTML = recData.description;

			var tn2 = tn1.select('.text_header')[0];

			tn2.innerHTML = recData.title;

			

			// insert into results DIV and display

			this.update.insertBefore(cloneDIV, searchFooter);

			cloneDIV.show();

		} catch(e) {}

	}

  

    if(entryCount > 0) {

      if(this.hasFocus) { 

        this.show();

        this.active = true;

      }

    } else {

     this.active = false;

     this.hide();

    }

  },



  pagePrevious: function() {

	if (this.page > 0) {

		this.page--;

	}

	if (!this.hasFocus) {

		this.hasFocus = true;

		this.update.show();

		this.element.focus();

	}

	this.getUpdatedChoices();

  },

  

  pageNext: function() {

	if ((this.lastResults.total - this.lastResults.resultmax) > 0) {

		this.page++;

	}

	if (!this.hasFocus) {

		this.hasFocus = true;

		this.update.show();

		this.element.focus();

	}

	this.getUpdatedChoices();

  },



  updateChoices: function(resultsObj) {

	if(!this.changed && this.hasFocus) {

		if (!resultsObj.total) {

			resultsObj = {error:'something is wrong with the returned search results', 

							resultmax:0,

							resultmin:0,

							sresults: [],

							total: 0

						};

		}

		this.lastResults = resultsObj;

		this.stopIndicator();
		
		this.render();

	}
	

  },



  onObserverEvent: function() {

    this.changed = false;   

    if(this.element.value.length>=this.options.minChars) {

		this.page = 0;  

		this.getUpdatedChoices();

    } else {

		this.active = false;

		this.hide();

    }

    this.oldElementValue = this.element.value;

  },





  getUpdatedChoices: function() {

	if (this.ajaxPending) return;

	this.ajaxPending = true;

	

    this.startIndicator();
	
    

    var entry = encodeURIComponent(this.options.paramName) + '=' + encodeURIComponent(this.element.value);



    this.options.parameters = this.options.callback ?

      this.options.callback(this.element, entry) : entry;



    if(this.options.defaultParams) 

      this.options.parameters += '&' + this.options.defaultParams;

	

	this.options.parameters += '&pn=' + this.page;

	

    new Ajax.Request(this.url, this.options);

  },



  onComplete: function(request) {

	this.ajaxPending = false;

	var resultJSON = eval("("+request.responseText+")");

    this.updateChoices(resultJSON);

  }



});