LiveSearch = Class.create();

LiveSearch.prototype = Object.extend(new Ajax.Base(),{

  initialize: function(params) {
    this.search_timeout = '';
    this.result_items = '';
    this.selected_item = '';
    this.keypress_event_listener = this.watch_keypress.bindAsEventListener(this);
    this.ignore_keys = $A(new Array(Event.KEY_DOWN,Event.KEY_UP,Event.KEY_ESC,Event.KEY_RIGHT,Event.KEY_LEFT));
    this.params = $H(params);
	
	this.input = jQuery('input#s');
	
    if (this.params.get('input') == undefined) {
      this.params.set('input', 's');
    }
    if (!$(this.params.get('input'))) {
      return;
    }
	
    if (this.params.get('results_container') == undefined) {
      this.params.set('results_container', 'search_results');
    }
    if (!$(this.params.get('results_container'))) {
      jQuery('form#search').after('<span id="loader_stop"></span><span id="spinner"></span>');
      jQuery('.searchfield_leftcap').after('<div id="' + this.params.get('results_container') + '"></div>');
    }
	
	this.input.addClass('livesearch').val('Search');
	jQuery('input#s')
		.focus(function() {
			if (jQuery('input#s').val() == 'Search') {
				jQuery('input#s').val('');
			}
			if (navigator.appVersion.indexOf('AppleWebKit')>0) {
				jQuery('.searchfield_leftcap').addClass('searchfield_leftcap_focus');
				jQuery('#search').addClass('search_focus');
				jQuery('.searchfield_rightcap').addClass('searchfield_rightcap_focus');
			}
		})
		.blur(function() {
			timerID=setTimeout("jQuery('#search_results').fadeOut('fast')", 200);
			if (jQuery('input#s').val() == '') {
				jQuery('#loader_stop').unbind('click').fadeTo('fast', 0.3).css('cursor', 'default');
				jQuery('input#s').val('Search');
			}
			if (navigator.appVersion.indexOf('AppleWebKit')>0) {
				jQuery('.searchfield_leftcap').removeClass('searchfield_leftcap_focus');
				jQuery('#search').removeClass('search_focus');
				jQuery('.searchfield_rightcap').removeClass('searchfield_rightcap_focus');
			}
		});
		
	jQuery('#spinner').hide();
	jQuery('#loader_stop').show().fadeTo('fast', 0.3);
	
    if (this.params.get('search_interval') == undefined) {
      this.params.set('search_interval', 1000);
    }
    if (this.params.get('loader') == undefined) {
      this.params.set('loader', 'spinner');
    }
	
    this.input.attr('autocomplete','off');
    this.input.attr('accesskey','s');
	
	jQuery('#searchform input[type=submit]').hide(); // Hide the submit button

    /*Element.ancestors($(this.params.get('input'))).each(function(a) { // stop the form from being submitted
      if (a.tagName.toLowerCase() == 'form') {
        Event.observe(a,'submit',function(e) {
          Event.stop(e);
          return false;
        });
        return;
      }
    });*/

    Event.observe(this.params.get('input'),'keyup',function(e) {this.delay_search(e)}.bind(this));
  },

  delay_search: function(e) {
    var key = e.keyCode;
    if (this.ignore_keys.include(key)) {
      return;
    }
    if (key == Event.KEY_RETURN && this.selected_item != '') {
      return;
    }
	if (this.input.val() == '') {
      reset_search();
      return false;
    }
	else if (key == 27) {
	  this.input.val('');
	}
    else if (key != 13) {
	  this.show_loader();
	  if (this.search_timeout) {
		clearTimeout(this.search_timeout);
	  }
	  this.search_timeout = setTimeout(function(){this.search()}.bind(this),this.params.get('search_interval'));
	}
  },

  search: function() {
	if (this.input.val() == '') {
		this.hide_loader_totally();
		return false;
	} else {
    new Ajax.Request(this.params.get('url'),{asynchronous:true, evalScripts:true, parameters:$({s: $(this.params.get('input')).value}), onComplete: function(result) {
      this.display_results(result.responseText);
      this.hide_loader();
	  jQuery('#search_results a').click(function(){clearTimeout(timerID);});
    }.bind(this)});
	}
  },

  display_results: function(content) {
    Event.stopObserving(this.params.get('input'), 'keydown', this.keypress_event_listener);
    this.clear_selected_items();
    this.selected_item = '';
    this.result_items = '';
    $(this.params.get('results_container')).innerHTML = content;
    jQuery('#search_results').fadeIn('fast');
	jQuery('#search_results').fadeTo('fast', 0.95);
    this.result_items = $A($(this.params.get('results_container')).getElementsByTagName('span'));
    if (this.result_items.length == 0) {
      this.result_items = $A($(this.params.get('results_container')).getElementsByTagName('li'));
    }
    this.result_items.each(function(item) {
      Element.observe(item,'mouseover',function() {
        Element.addClassName(item,'active');
      }.bind(item).bind(this));
      Element.observe(item,'mouseout',function() {
        Element.removeClassName(item,'active');
      }.bind(item).bind(this));
      Element.observe(item,'click',function() {
        this.clear_selected_items();
        Element.addClassName(item,'selected');
        this.selected_item = item;
        this.goto_result();
      }.bind(this).bind(item));
    }.bind(this));
    Event.observe($(this.params.get('input')), 'keydown', this.keypress_event_listener);
  },

  show_loader: function() {
    if (!$(this.params.get('loader'))) { return; }
    if ($('loader_stop')) { jQuery('#loader_stop').fadeOut('fast');}
    jQuery('#spinner').fadeIn('fast');
  },

  hide_loader: function() {
    if (!$(this.params.get('loader'))) { return; }
    jQuery('#spinner').fadeOut('fast');
    if ($('loader_stop')) { jQuery('#loader_stop').click(function(){reset_search();}).show().fadeTo('fast', 1.0).css('cursor', 'pointer'); }
  },
  
  hide_loader_totally: function() {
	if (!$(this.params.get('loader'))) { return; }
	jQuery('#spinner').fadeOut('fast');
	if ($('loader_stop')) { jQuery('#loader_stop').show().fadeTo('fast', 0.3).css('cursor', 'default'); }
  },

  clear_selected_items: function() {
    if (this.result_items == '') { return; }
    this.result_items.each(function(item) {
      Element.removeClassName(item,'selected');
    });
    this.selected_item = '';
    $A($(this.params.get('results_container')).getElementsByTagName('dt')).each(function(dt){ 
      Element.removeClassName(dt,'selected');
    });
  },

  watch_keypress: function(e) {
    if ($(this.params.get('results_container')).visible()) {
      switch(e.keyCode) {
        case Event.KEY_UP:
          this.select_prev();
          if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(e);
          return;
        case Event.KEY_DOWN:
          this.select_next();
          if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(e);
          return;
        case Event.KEY_ESC:
          jQuery('#search_results').fadeOut('fast');
          if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(e);
          return;
        case Event.KEY_RETURN:
          this.goto_result();
          if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(e);
          return;
      }
    }
  },

  select_next: function() {
    if (this.selected_item == '') {
      this.selected_item = this.result_items.first();
      Element.addClassName(this.selected_item,'selected');
    } else {
      if (this.selected_item == this.result_items.last()) {
        var item = this.result_items.first();
      } else {
        var item = this.result_items[this.result_items.indexOf(this.selected_item)+1];
      }
      this.clear_selected_items();
      Element.addClassName(item,'selected');
      this.selected_item = item;
    }
  },

  select_prev: function() {
    if (this.selected_item == '') {
      this.selected_item = this.result_items.last();
      Element.addClassName(this.selected_item,'selected');
    } else {
      if (this.selected_item == this.result_items.first()) {
        var item = this.result_items.last();
      } else {
        var item = this.result_items[this.result_items.indexOf(this.selected_item)-1]
      }
      this.clear_selected_items();
      Element.addClassName(item,'selected');
      this.selected_item = item;
    }
  },

  goto_result: function() {
    if ($(this.selected_item).getElementsByTagName('a').length == 0) {
      return;
    }
    setTimeout(function() { Element.addClassName($(this.selected_item),'highlight');}.bind(this),100);
    setTimeout(function() { Element.removeClassName($(this.selected_item),'highlight');}.bind(this),220);
    setTimeout(function() { Element.addClassName($(this.selected_item),'highlight');}.bind(this),300);
    setTimeout(function() { window.location = $(this.selected_item).getElementsByTagName('a')[0].href;}.bind(this),360);
  }
  
});

function reset_search() {
	jQuery('input#s').val('');
	jQuery('input#s').focus();

	jQuery('#loader_stop').unbind('click').fadeTo('fast', 0.3).css('cursor', 'default');

	if ( jQuery('#search_results').length ) {
		jQuery('#search_results').fadeOut('fast');
	}
}