/**
 * AutoComplete Field - JavaScript Code
 *
 * This is a sample source code provided by fromvega.
 * Search for the complete article at http://www.fromvega.com
 *
 * Enjoy!
 *
 * @author fromvega
 *
 */

// global variables

var AutoComplete = function setAutoComplete(field_id, results_id, get_url){

	var acListTotal   =  0;
	var acListCurrent = -1;
	var acDelay		  = 500;
	var acURL		  = null;
	var acSearchId	  = null;
	var acResultsId	  = null;
	var acSearchField = null;
	var acResultsDiv  = null;

	// initialize vars
	acSearchId  = "#" + field_id;
	acResultsId = "#" + results_id;
	acURL 		= get_url;
	var anElement = field_id;
	if (!anElement) {
		return false;
	}
	if (typeof anElement == "string") { // try for the ID
		anElement = document.getElementById ? document.getElementById(field_id) : document.all ? document.all[field_id] : document.layers ? document.layers[field_id] : field_id;
	}
	
	if (typeof anElement == "string") { // the grab failed: typeof null yields "object"
		return false;
	}
	
	this.element = anElement;
	this.element.autosugest = this;
	
	// create the results div
	$("body").append('<div class="results" id="' + results_id + '"></div>');

	// register mostly used vars
	acSearchField	= $(acSearchId);
	acResultsDiv	= $(acResultsId);
	
	this.setAcSearchField = function (valor) {
		acSearchField = $(valor);
		return true;
	}
	
	this.setAcResultsDiv = function (valor) {
		acResultsDiv = $(valor);
		return true;
	}
	
	this.getAcSearchField = function () {
		return acSearchField;
	}
	
	this.getAcResultsDiv = function () {
		return acResultsDiv;
	}
	
	this.getAcDelay = function () {
		return acDelay;
	}
	
	this.getAcURL = function () {
		return acURL;
	}
	
	this.getAcListTotal = function () {
		return acListTotal;
	}
	
	this.getAcListCurrent = function () {
		return acListCurrent;
	}
	
	this.setAcListCurrent = function (valor) {
		acListCurrent = valor;
		return true;
	}
	
	this.getAcSearchId = function () {
		return acSearchId;
	}
	
	
	this.getAcResultsId = function () {
		return acResultsId;
	}
	
	// reposition div
	//this.repositionResultsDiv();
	
	// on blur listener
	this.element.onblur = this.elementBlur;

	// on key up listener
	this.element.onkeyup = this.elementKeyup;
	
	// on key up listener
	this.element.onkeypress = this.elementKeyPress;
	
}

// treat the auto-complete action (delayed function)
AutoComplete.prototype.autoComplete = function (lastValue)
{
	acSearchField = this.getAcSearchField();
	acResultsDiv = this.getAcResultsDiv();
	acListTotal = this.getAcListTotal();
	acResultsId = this.getAcResultsId();
	autosugest = this;
	// get the field value
	var part = acSearchField.val();

	// if it's empty clear the resuts box and return
	if(part == ''){
		this.clearAutoComplete();
		return;
	}

	// if it's equal the value from the time of the call, allow
	if(lastValue != part){
		return;
	}

	// get remote data as JSON
	$.getJSON(this.getAcURL() + part, function(json){

		// get the total of results
		var ansLength = acListTotal = json.length;

		// if there are results populate the results div
		if(ansLength > 0){

			var newData = '';

			// create a div for each result
			for(i=0; i < ansLength; i++) {
				newData += '<div class="unselected">' + json[i] + '</div>';
			}

			// update the results div
			acResultsDiv.html(newData);
			acResultsDiv.css("display","block");
			
			// for all divs in results
			var divs = $(acResultsId + " > div");
		
			// on mouse over clean previous selected and set a new one
			divs.mouseover( function() {
				divs.each(function(){ this.className = "unselected"; });
				this.className = "selected";
			})
		
			// on click copy the result text to the search field and hide
			divs.click( function() {
				acSearchField.val(this.childNodes[0].nodeValue);				
				autosugest.clearAutoComplete();
			});

		} else {
			autosugest.clearAutoComplete();
		}
	});
}

// clear auto complete box
AutoComplete.prototype.clearAutoComplete =  function ()
{
	this.getAcResultsDiv().html('');
	this.getAcResultsDiv().css("display","none");
}

// reposition the results div accordingly to the search field
AutoComplete.prototype.repositionResultsDiv = function ()
{
	// get the field position
	var sf_pos    = this.getAcSearchField().offset();
	var sf_top    = sf_pos.top;
	var sf_left   = sf_pos.left;

	// get the field size
	var sf_height = this.getAcSearchField().height();
	var sf_width  = this.getAcSearchField().width();

	// apply the css styles - optimized for Firefox
	this.getAcResultsDiv().css("position","absolute");
	this.getAcResultsDiv().css("z-index","1500");
	this.getAcResultsDiv().css("left", sf_left - 2);
	this.getAcResultsDiv().css("top", sf_top + sf_height + 5);
	this.getAcResultsDiv().css("width", sf_width - 2);
}


// treat up and down key strokes defining the next selected element
AutoComplete.prototype.updownArrow =  function (keyCode) {
	var autosugest = this;
    autosugest.repositionResultsDiv();
    
	if(keyCode == 40 || keyCode == 38){
		if(keyCode == 38){ // keyUp`
			if(this.getAcListCurrent() == 0 || this.getAcListCurrent() == -1){
				this.setAcListCurrent(this.getAcListTotal()-1);
				
			}else{
				this.setAcListCurrent(this.getAcListCurrent()-1);
			}
		} else { // keyDown
			if(this.getAcListCurrent() == this.getAcListTotal()-1){
				this.setAcListCurrent(0);
			}else {
				this.setAcListCurrent(this.getAcListCurrent()+1);
			}
			
		}
		// loop through each result div applying the correct style
		autosugest = this;
		this.getAcResultsDiv().children().each(function(i){
			if(i == autosugest.getAcListCurrent()){
				autosugest.getAcSearchField().val(this.childNodes[0].nodeValue);
				this.className = "selected";
			} else {
				this.className = "unselected";
			}
		});

		return true;
	} else {
		// reset
		this.setAcListCurrent(-1);
		return false;
	}
}

AutoComplete.prototype.elementKeyup = function (evt) {

		// get keyCode (window.event is for IE)
		//var keyCode = e.keyCode || window.event.keyCode;
		var keyCode = (document.all) ? window.event.keyCode : evt.which;
		var lastVal = this.autosugest.getAcSearchField().val();

		
		// check an treat up and down arrows
		if(this.autosugest.updownArrow(keyCode)){
			return;
		}
		
		// check for an ENTER or ESC
		if(keyCode == 13 || keyCode == 27){
			this.autosugest.clearAutoComplete();
			if(keyCode == 13) {
				if (document.all) {
					window.event.keyCode = 0;
				}else {
					//evt.which = 0;
				}
			}
			return;
		}
		autosugest = this.autosugest;
		// if is text, call with delay
		setTimeout(function () {autosugest.autoComplete(lastVal)}, this.autosugest.getAcDelay());
}

AutoComplete.prototype.elementKeyPress = function (evt) {

		// get keyCode (window.event is for IE)
		//var keyCode = e.keyCode || window.event.keyCode;
		var keyCode = (document.all) ? window.event.keyCode : evt.which;
		// check for an ENTER or ESC
		if(keyCode == 13){
			this.autosugest.clearAutoComplete();
			return false;
		}
		return true;
}

AutoComplete.prototype.elementBlur = function () {
	autosugest =  this.autosugest;
	setTimeout(function () {this.autosugest.clearAutoComplete()}, 200) 
}

