/*
 * 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.position = $(this.input).getCoordinates();
	    this.event();

	},
	event: function () {
		
			var localThis = this;
			this.input.addEvent('keyup', function(event) {
			event = new Event(event);
			this.keyPress(event.key);
			}.bind(this))
			.addEvent('click', function(event) {
				  if ($(localThis.update_hidden)) localThis.appear(localThis.update_hidden);
			}.bind(this))
			.addEvent('blur', function(event) {
				  if ($(localThis.update_hidden)) localThis.fade(localThis.update_hidden);
			}.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_hidden);break;
			case 'backspace':
			 if (this.input.value.length >= this.options.minchar) {
				  this.start();
				} else {
				  $(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
	  		var el = $(this.update_hidden);
  			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) {
					/* next element */
					if (where == 'down') {
	  				var h = $(this.selected.id).getNext();
	  			} else {
	  			  var h = $(this.selected.id).getPrevious();
	  			}
        }
        /* first element*/
				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;

     if ($(this.update_hidden)) $(this.update_hidden).remove();
	   if ($('list_ul_'+this.input.name)) $('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,
      '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 () {

	    var url = this.url + "?id="+$(this.input.id).value;
      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()};
	  //ARNAUD
	  url = encodeURI(url);
	  //fin ARNAUD
  	  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)  				 
  				 .addEvent('mouseout', function(e) {
						 this.removeClass('selected');
  				 })
           .addEvent('click', function(e) {
						 localThis.input.value = localThis.filter(this.innerHTML);
						 $(localThis.update_hidden).setStyle('display','none');
  				 });
    	});
 
			/* 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) {
	  // remove HTML tag
		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':'block',
					'visibility':'hidden'
					}).effect('opacity').start(0,1);
			} catch(e)	{
				$(div).setStyle('display','block');
			}
	},
	loading: function () {
	      this.input.removeClass('onloading');
			  this.input.addClass('onloading');
	}
});
