/*
 * Autocompleter Emoxion
 * with Mootools
 * Manuel Garcia (thekeeper)
 * http://www.mgarcia.info
 * Version 0.9
 *
 * Copyright (c) 2007 Manuel Garcia
 * http://www.opensource.org/licenses/mit-license.php
 */

var Autocomplete = new Class({

	initialize: function (inp,url,options) {
	    /* Asignamos valores a variables globales, e iniciamos el evento*/
     	this.url = url;
	    this.input = $(inp);

	    if (!this.update_hidden) this.update_hidden = 'update_hidden_'+this.input.name;
	    if (!this.update_show) this.update_show = 'update_show_'+this.input.name;
	    if (!this.onloading) this.onloading = 'onloading_'+this.input.name;

	    this.input.setProperty('autocomplete', 'off')
	    this.options = options;
	    this.event();

	},
	event: function () {
			/* Añadimos evento onkeyup al input */
			this.input.addEvent('keyup', function(event) {
			event = new Event(event);
			this.keyPress(event.key);
			}.bind(this));

			var localThis = this;
			/*buscamos al formulario ke pertenece*/
			var form = $$('form', 'input');
      $$(form).each(function(el){
        if (el.name == localThis.input.name) {
           /* añadimos un evento para cancelar el submit*/
           form[0].addEvent('submit', function(event) {
						if ($(localThis.update_show)) localThis.fade(localThis.update_show);
					 }.bind(this));
        }
			});
	},
	keyPress: function (key) {

	    switch (key) {
	    case 'down':
	      this.move('down');
			break;
			case 'left':
			break;
			case 'right':
			break;
			case 'up':
         this.move('up');
			break;
			case '#':
			break;
			case 'enter':
				this.fade(this.update_show);
			break;

			case 'backspace':
				if (this.input.value.length >= this.options.minchar) {
				  this.start();
				} else {
				  this.fade(this.update_show);
				}
			break;
	    default:

		    if (this.input.value.length >= this.options.minchar) {
	       if(!/\W/.test(key)) {
	       // solution repeat seam query
					if (this.query != this.input.value ) {
					  this.start();
					  this.query = this.input.value;
					}
	    	 }
	    	}
	    break;
	    }
	},
	move: function(where) {

	  		var el = $(this.update_show);
  			var elements = el.getElementsByTagName('li');

				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) {
					/* siguiente elemento */
					if (where == 'down') {
	  				var h = $(this.selected.id).getNext();
	  			} else {
	  			  var h = $(this.selected.id).getPrevious();
	  			}
        }
        /* si no exíste elemento siguamos en primero*/
				if (!h) var h = elements[0];

				this.input.value = localThis.filter(h.innerHTML);

   			if (h) {
	  			h.addClass('selected');
	  		} else {
	  		  this.selected = false;
	  		}

	},
	start: function () {

	    // onloading
		  if (this.options.onloading) this.loading();
      this.selected=false;
			this.count = 0;
	    this.update_f  =  this.options.update;
	   	// update with ajax
	    if ($(this.update_hidden)) {
	      $(this.update_hidden).remove();
	   	}
	   	if ($(this.update_show)) {
	      $(this.update_show).remove();
	   	}

			this.position = $(this.input).getCoordinates();

			this.div = new Element('div');
			this.div.id = (this.update_hidden);
      this.div.setStyle('display','none');
  		this.div.injectBefore(this.input);
  		this.options.update = this.div.id;

  		// show result
			this.div = new Element('div');
			this.div.className = "autocompleter";
			this.div.id = (this.update_show);
      this.div.setStyles({'display':'none',
      'position':'absolute',
      'overflow':'none',
      'top':(this.position.top+this.position.height)+'px',
      'left':(this.position.left)+'px',
      'width': this.position.width+'px'});
  		this.div.injectAfter(this.input);
      var localThis = this;

	 		if (this.Timer) this.Timer = $clear(this.Timer);

  		/* Enviamos la información con un delay de 400 */
  		/* reiniciamos capa*/
  		$(this.update_show).innerHTML = ' ';
  	  this.Timer = (function(){localThis.post_data()}).delay(400);

	},
	post_data: function () {

	    var url = this.url + "&id="+$(this.input.id).value;
      var localThis = this;
  		if (this.options.OnComplete) this.options.OnComplete = $clear(this.options.OnComplete);
  	  this.options.OnComplete = (function(){localThis.update()}).delay(1000);

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

	},
	update: function () {

	    /* Procesamos la información recibida*/
	    var up = $(this.update_hidden);
  		var elements = up.getElementsByTagName('li');

	  	var list = new Element('ul');
	  	list.id = ('list_ul_'+this.input.name);
  		list.injectInside(this.update_show);

  		if (elements.length == 0) {
				var li = new Element('li');
				li.setHTML('Sin resultados.');
				li.injectInside(list.id);
				li.addEvent('click', function(e) {
				 $(localThis.update_show).setStyle('display','none');
  			});
  			this.options.OnComplete = (function(){localThis.fade(localThis.update_show)}).delay(2000);
			}

			var i = 0;
			var localThis = this;
//			return (this.options.markQuery && this.queryValue) ? txt.replace(new RegExp('^(' + RegExp.escape(this.queryValue) + ')', 'i'), '<span class="autocompleter-queried">$1</span>') : txt;
			$$(elements).each(function(el){

        	 var li = new Element('li');
					 li.setStyles({ cursor: 'pointer', 'list-style': 'none','padding':'.2em' });
					 li.id = ('li_' + i++);
					 li.onclick = el.onclick;

					 var html = localThis.filter(el.innerHTML);
					 html = html.replace(new RegExp('(' + localThis.escape($(localThis.input.id).value) + ')', 'i'), '<strong>$1</strong>')

     		   li.setHTML(html);
     		   li.addEvent('mousemove', function(e) {
						 this.addClass('selected');
  				 });
  				 li.addEvent('mouseout', function(e) {
						 this.removeClass('selected');
  				 });

					 li.addEvent('click', function(e) {
						 localThis.input.value = localThis.filter(this.innerHTML);
						 $(localThis.update_show).setStyle('display','none');
  				 });
					  li.injectInside(('list_ul_'+localThis.input.name));
    	});

			/* Ocultamos onloading*/
			if (this.options.onloading) this.fade(this.onloading);
			/* Mostramos la capa de resultados */
      this.appear(this.update_show);
      this.options.OnComplete = (function(){localThis.fade(localThis.update_show)}).delay(20000);
	},
	filter: function(obj) {
	  // elimina etiquetas HTML
		obj = obj.replace(/<[^>]*>/gi, "");
		obj = obj.replace(/<[^>]*\/gi>/, "");
		obj = obj.trim();
	  return obj;
	},
	 escape: function (txt) {
   	return txt.replace(/[.*+?^${}()|[\]\/\\]/gi, '\\$1');
	},
	fade: function (div) {
			$(div).setStyle('display','none');
	},

	appear: function (div) {
		  try
			{
				$(div).setStyles({
					'display':'inline',
					'visibility':'hidden'
					}).effect('opacity').start(0,1)
			} catch(e)	{
				$(div).setStyle('display','inline');
			}
	},
	loading: function () {
	      if ($(this.onloading)) {
	          $(this.onloading).remove();
	      }
			  this.input.setStyle('display','inline');
        this.position = $(this.input).getCoordinates();
        this.input.setStyles({
          'padding-left':'20px'
        });
        
     		this.div = new Element('div');
			  this.div.id = this.onloading;
			  this.div.setStyles({
        'display':'inline',
			  'padding':'.2em',
			  'position':'absolute',
        'top':(this.position.top)+'px',
        'left':(this.position.left/*+this.position.width*/)+'px'
        });
			  this.div.injectBefore(this.input.id);

			  img = new Element('img');
        img.src = this.options.onloading
			  img.injectInside(this.div);


	}
});
