
/*
 * Autocompleter EMX
 * with Mootools
 * Manuel Garcia (thekeeper)
 * http://www.mgarcia.info
 * Version 1
 *
 * Copyright (c) 2007 Manuel Garcia
 * http://www.opensource.org/licenses/mit-license.php
 */

var Autocompleter = new Class({
	initialize: function (inp,url,options) {
     	this.url = url;
	    this.input = $(inp);
	    this.ajax= 1;
	    if (!this.update_hidden) this.update_hidden = 'update_hidden_'+this.input.name;
	    this.input.setProperty('autocomplete', 'off');
	    this.options = options;
	    this.event();
	},
	event: function () {
			var localThis = this;
			this.input.addEvent('keyup', function(event) {
			event = new Event(event);
	    	this.position = $(this.input).getCoordinates();
			this.position.width = 500;
			this.keyPress(event.key, event);
			}.bind(this))
			.addEvent('click', function(event) {
				  if ($(localThis.update_hidden)) localThis.appear(localThis.update_hidden);
			}.bind(this));
	},
	keyPress: function (key, e) {
		this.old_value = this.input.value;
	    switch (key) {
			/*
	    	case 'down': this.move('down');	break;
			case 'up': this.move('up');	break;			
			*/
			case 'left': break;
			case 'right': break;
			case '#':	break;
			case 'delete':			
			case 'backspace':			
				this.fade(this.update_hidden); 
				break;
			/*
			 if (this.input.value.length >= this.options.minchar) {
				  this.start();
				} else {
					if (this.update_hidden && $(this.update_hidden))
					  $(this.update_hidden).empty();
				}*/
			break;
	    default:
		    if (this.input.value.length >= this.options.minchar) {
        	var reg = new RegExp('(' + this.escape($(this.input.id).value) + ')', 'i');
			/*			
		    try {
		      // cache
		      var i=0;
		      var e=0;
  			  var localThis = this;
  			  var elements = $(this.update_hidden).getElementsByTagName('li');
  			  $$(elements).each(function(el){
  			    var html = localThis.filter(el.innerHTML);
  			    e++;
            if (reg.test(html)) {
              localThis.ajax = 0;              
              el.innerHTML = html.replace(new RegExp('(' + localThis.escape($(localThis.input.id).value) + ')', 'i'), '<strong>$1</strong>');
              el.setStyle('display','block');
            } else {
              i++;
              el.setStyle('display','none');
            }
  			  });
  			  if (e == i) this.ajax=1; 
          
  			  this.appear(this.update_hidden);
  			 } catch(e) {}
		 */
		if(!/\W/.test(key)) 
		{
			if (this.ajax) 
			{
				// solution repeat seam query
				if (this.query != this.input.value) 
				{
					this.start();
					this.query = this.input.value;
				} 
				else 
				{ 
					if ($(this.update_hidden)) 
					{
						this.appear(this.update_hidden);
					}
				}
			}
		}
	    break;
		}
		}
	},
	move: function(where) {
	      // move key up and down
			if (! (el = $(this.update_hidden)) )
				return;
			if (! (elements = el.getElementsByTagName('li')) )
				return;
			var localThis = this;
  			$$(elements).each(function(el){
						if (el.className == 'selected') {
						    localThis.input.value = localThis.filter(el.innerHTML);
						    el.removeClass('selected');
		          			localThis.selected = el;
						}
	  			});
			
				if (this.selected && where == 'down') {
	  				var h = $(this.selected.id).getNext();
	  			} else if (this.selected) {
	  				var h = $(this.selected.id).getPrevious();
	  			}
				else
					h = elements[0];
        /* first element*/
			if (!h) 
			{
				this.selected = false;
				return;
			}
			h.addClass('selected');
			this.selected = h;
	},
	start: function () {
	    // onloading
		  if (this.options.onloading) this.loading();
      this.selected=false;
			this.count = 0;
	    this.update_f  =  this.options.update;

     if ($(this.update_hidden)) $(this.update_hidden).remove();
	 if ($('list_ul_'+this.input.name)) 
	 {
   			unhideSelects();
			$('list_ul_'+this.input.name).remove();
	 }
     var localThis = this;
  		// show result
			this.div = new Element('div')
			.setProperty('id',this.update_hidden)
      .setStyles({
			'display':'none',
      'position':'absolute',
      'top':this.position.bottom,
      'left':this.position.left,
      'z-index':'10000',
      'background' : 'white',
      'border' : '1px outset #CCCCCC',
      'width': this.position.width+'px'})
      .addEvent('mouseout',function(e){
				localThis.input.removeEvents('blur');
			}.bind(this))
      .addEvent('mouseleave',function(e){
				localThis.input.addEvent('blur', function(event) {
				  if ($(localThis.update_hidden)) localThis.fade(localThis.update_hidden);
				}.bind(this))
			})
  		.injectInside(document.body);
	   
      this.options.update = this.div.id;
	 		if (this.Timer) this.Timer = $clear(this.Timer);
  		/* go go */
  	  this.Timer = (function(){localThis.post_data()}).delay(600);

	},
	post_data: function (page) {
	  var url = this.url + "?value="+$(this.input.id).value;
	  if (page)
		url += "&page=" + page;
      var localThis = this;
      this.fade($(this.update_hidden));
  		//if (this.options.onComplete) this.options.onComplete = $clear(this.options.onComplete);
  	  this.options.onComplete = function(){localThis.update()};
  	  new Ajax(url, this.options).request();  
	},
	update: function () {
	    /* Get data */
	    this.nav = [];
	    var up = $(this.update_hidden);
  		var elements = up.getElementsByTagName('li');
			var localThis = this;
      		  
			var i = 0;
			$$(elements).each(function(el){
			     i++;
					 var html = localThis.filter(el.innerHTML);
					 html = html.replace(new RegExp('(' + localThis.escape($(localThis.input.id).value) + ')', 'i'), '<strong>$1</strong>');
					 localThis.nav[i] =  localThis.filter(html);
           el.innerHTML = html;
           el.removeEvents();
           el.addEvent('mousemove', function(e) {
						 this.addClass('selected');
  				 })
  				 .setProperty('id','li_' + i)
  				 .setStyle('cursor','pointer')			 
  				 .addEvent('mouseout', function(e) {
						 this.removeClass('selected');
  				 })
           .addEvent('click', function(e) {
				localThis.input.value = localThis.filter(this.innerHTML);
				$(localThis.update_hidden).setStyle('display','none');
				unhideSelects();
				localThis.input.focus();
  			});
    	});
			/* hidden onloading*/
			if (this.options.onloading) this.input.removeClass('onloading');
			/* show div */
      this.appear(this.update_hidden);
      this.options.onComplete = function(){localThis.fade(localThis.update_hidden)}
	},
	filter: function(obj) {
		var text = document.createTextNode(obj);
		obj = text.nodeValue;
		obj = obj.replace(/<[^>]*>/gi, "");
		obj = obj.replace(/<[^>]*\/gi>/, "");
		obj = obj.replace(/&amp;/, "&");
		obj = obj.trim();
		return obj;
	},
	escape: function (txt) {
   	return txt.replace(/[.*+?^${}()|[\]\/\\]/gi, '\\$1');
	},
	fade: function (div) {
			unhideSelects();
			$(div).setStyle('display','none');
	},
	appear: function (div) {
		  if (this && this.old_value)
		  {
		    this.input.value = this.old_value;
			//this.old_value = false;
		  }
		  try
			{
				$(div).setStyles({
					'display':'block',
					'visibility':'hidden',
					'zindex':1000
				}).effect('opacity').start(0,1);
			} catch(e)	{
				$(div).setStyle('display','block');
			}
		hideSelects();
		window.autocompleter = this;
	},
	loading: function () {
	      this.input.removeClass('onloading');
			  this.input.addClass('onloading');
	}
});

