	/*
		API 
		public methods
			constructor()
			setDivMouseOverAction()
			setDivClickAction()
			clearAutoComplete()
			setJsonResultAction()
			setMinSearchChar()
	*/

/**
 * AutoComplete Field - JavaScript Code
 * @author Tiago P classe inspired by the fromvega function source at http://www.fromvega.com
 */

function AutoComplete(field_id,results_id, get_url,function_to_call,loading){
// global variables
this.acListTotal   =  0;
this.acListCurrent = -1;
this.acDelay		  = 400;
this.acURL		  = get_url;

this.acSearchId	  = "#" + field_id;
this.acResultsId	  = "#" + results_id;

this.divMouseOverAction = null;
this.divClickAction = null;

this.jsonResultAction = function_to_call;
this.disp_loader = loading;
this.minSearchChar = 2;

this.results = new Array();

	var that = this;
	//listeners
	
	var searchInput = jQuery(this.acSearchId).get(0);
	
	addEvent(searchInput,"keyup",function(e){ that.acSearchField_keyup(e) });
	addEvent(searchInput,"keydown",function(e){ that.acSearchField_keyup(e) });
	addEvent(searchInput,"blur",function(e){ setTimeout(function(){that.clearAutoComplete()},200)});
}

AutoComplete.prototype = {
	
acSearchField_keyup : function(e){			 
		// get keyCode (window.event is for IE)	
		
		e = e || window.event;
		var keyCode = e.keyCode || window.event.keyCode;
		var lastVal = jQuery(this.acSearchId).val();	
		var type = e.type;
		
		if(keyCode == 38 || keyCode == 40){
			this.updownArrow(keyCode,type); 
			return;
		}
	
		// check for an ENTER or ESC
		if(keyCode == 13 || keyCode == 27){
			this.clearAutoComplete();
			return;
		}
		
		//alert(jQuery(this.acSearchId).val());
		var that = this; 
		setTimeout(function () {that.autoComplete(lastVal)}, that.acDelay);	// if is text, call with delay
},

// treat the auto-complete action (delayed function)
autoComplete : function(lastValue){
	
	var part = jQuery(this.acSearchId).val();	// get the field value	
	part = trim(part);	// if it's empty clear the resuts box and return
	//alert("PART : "+part+ " - LASTVAL : "+lastValue);
	if(part.length < this.minSearchChar){
		 this.clearAutoComplete();
		return;
	}
	//jQuery(this.acSearchId).html("PART : "+part+ " - LASTVAL : "+lastValue);
	// if it's equal the value from the time of the call, allow
	if(lastValue != part) return;
	
	if(this.disp_loader){
		this.divPosition();
		jQuery(this.acResultsId).html("<img src='"+img_load.src+"' />");
	}
	
	var that = this;
	jQuery.getJSON(this.acURL + part, function(json){ // get remote data as JSON
										  //alert('est');
		// get the total of results
		var ansLength = that.acListTotal = json.length;
		if(ansLength > 0){	// if there are results populate the results div
			
			that.results = json;
			
			if(that.jsonResultAction != null){
				that.jsonResultAction(json);
			}else{
				//defaults actions 
				var newData = '';	
				for(i=0; i < ansLength; i++) {	// create a div for each result
					newData += '<div class="unselected">' + json[i] + '</div>';
				}
				jQuery(that.acResultsId).html(newData);	// update the results div
			}
				var divs = jQuery(that.acResultsId + " > div");	// for all divs in results
			
				if(that.divMouseOverAction != null){
					fct_mouseover = that.divMouseOverAction;
				}else{
					fct_mouseover = function(moused) {
						divs.each(function(){ this.className = "unselected";  });
						moused.className = "selected";
					}
				}
			
				if(that.divClickAction != null){
					fct_click = that.divClickAction;
				}else{
					fct_click = function(clicked) {	// on click copy the result text to the search field and hide
						jQuery(that.acSearchId).val(clicked.childNodes[0].nodeValue);
						that.clearAutoComplete();
					}
				}
				//events
				divs.mouseover(function(){fct_mouseover(this)});
				divs.click(function(){fct_click(this)});
		} else {
			that.clearAutoComplete();
		}
	});
}
// clear auto complete box
, clearAutoComplete : function()
{	
	jQuery(this.acResultsId).css("display","none");
	jQuery(this.acResultsId).html('');
	
}

// treat up and down key strokes defining the next selected element
, updownArrow : function(keyCode,type) {
		
		if(keyCode == 38 && type == "keydown"){ // keyUp
			if(this.acListCurrent == 0 || this.acListCurrent == -1){
				this.acListCurrent = this.acListTotal-1;
			}else{
				this.acListCurrent--;
			}
			
		}else if(keyCode == 40 && type == "keydown" ) { // keyDown						
			if(this.acListCurrent == this.acListTotal-1){
				this.acListCurrent = 0;
			}else {
				this.acListCurrent++;
			}
		}
		
		this.changeListStyle();
}

, changeListStyle : function(){
	var that = this;
	
	jQuery(this.acResultsId).children().each(function(i){			 
		if(i == that.acListCurrent){
			this.className = "selected";
		} else {
			this.className = "unselected";
		}
	});
	
	return true;
	
	},

	setDivMouseOverAction : function(action){
		this.divMouseOverAction = action;
	},
	setDivClickAction : function(action){
		this.divClickAction = action;
	},
	setJsonResultAction : function(action){
		this.jsonResultAction = action;
	},
	setMinSearchChar : function(nb){
		this.minSearchChar = nb;	
	},
	
	divPosition : function(){
		
		var input = jQuery(this.acSearchId);
		var coord = input.offset();
		
		var height = input.height() + 4;
		var x = coord.left;
    	var y = coord.top + height;
		
		jQuery(this.acResultsId).css("position","absolute");
		//jQuery(this.acResultsId).css("top",y);
    	//jQuery(this.acResultsId).css("left",x);
		jQuery(this.acResultsId).css("display","block");
		jQuery(this.acResultsId).css("z-index","999");
		jQuery(this.acResultsId).css("border","1px solid #7d7d7d");
		jQuery(this.acResultsId).css("font-size","12px");
		jQuery(this.acResultsId).css("width","350px");
		//jQuery(this.acResultsId).css("margin-left","-3px");
		jQuery(this.acResultsId).css("max-height","200px");
		jQuery(this.acResultsId).css("overflow-y","auto");
		
	}
	
}

/**** UTILS ****/

function trim(sString) {
    while (sString.substring(0,1) == ' ' || sString.substring(0,1) == '\t' || sString.substring(0,1) == '\r' || sString.substring(0,1) == '\n'){
        sString = sString.substring(1, sString.length);
    }
    while (sString.substring(sString.length-1, sString.length) == ' ' || sString.substring(sString.length-1, sString.length) == '\t' || sString.substring(sString.length-1, sString.length) == '\r' || sString.substring(sString.length-1, sString.length) == '\n'){
        sString = sString.substring(0,sString.length-1);
    }
    return sString;
}

function addEvent(element, eventName, callback){
   if (element.addEventListener)
      element.addEventListener(eventName, callback, false);
   else if (element.attachEvent)
      element.attachEvent('on'+eventName, callback);
}
