var lsResultDiv		= new Array();
var lsField			= new Array();
var lsSearchField	= new Array();
var lsAjaxUrl 		= new Array();
// lsDelay = waittime in ms before performing live search via AJAX
var lsDelay 		= 250;
var lsListTotal   	= 0;
var lsListCurrent 	= -1;
var jsonResult 		= new Array();
var lsOldValue		= new Array();
var lsCallback		= new Array();

function liveSearchInit(fieldId, ajaxUrl, callback) {
	var lsSearchFieldId = fieldId + '_search';
	var lsSearchResultId = fieldId + '_result';
	
	lsField[fieldId] = $('#' + fieldId);
	lsSearchField[fieldId] = $('#' + lsSearchFieldId);
	
	lsAjaxUrl[fieldId] = ajaxUrl;
	lsCallback[fieldId] = callback;
	
	// add searchresult div
	$('body').append('<div class="lsResults" id="' + lsSearchResultId + '" style="display: none;"></div>');
	lsResultDiv[fieldId] = $('#' + lsSearchResultId);
	
	// onblur clear field
	lsSearchField[fieldId].blur(function() {
		if (lsSearchField[fieldId].val() == '') {
			lsEmptySearch(fieldId);
		}
		else {
			lsSetSearchKey(fieldId);
		}
		// clear search results
		setTimeout(function() {clearLiveSearchResults(fieldId);}, 10);
		//clearLiveSearchResults(fieldId);
	});
	
	// append onkeyup listener
	lsSearchField[fieldId].keyup(function (e) {
		// get keyCode (window.event is for IE)
		var keyCode = e.keyCode || window.event.keyCode;
		var lastValue = lsSearchField[fieldId].val();
	
		
		// check for cursor movement
		if (handleCursor(fieldId, keyCode)){
			return;
		}
		else {
			if (lastValue.search(/^[A-Z]{2},/) != -1) {
				// remember old setting
				lsOldValue[fieldId] = lastValue;
			}			
		}
		//alert(lsResultDiv[fieldId].is(':hidden'));
		//$('#debug').html($('#debug').html() + " / hidden (" + fieldId + ") = " + lsResultDiv[fieldId].is(':hidden'));
		// check for an ENTER (13), ESC (27)
		if (keyCode == 13 || keyCode == 27){
			// clear fields on ESC (27)
			if (keyCode == 27) {
				//if (!lsResultDiv[fieldId].is(':hidden')) {
					// reset search if searchresult div was visible
					lsSetSearchKey(fieldId);
					//lsEmptySearch(fieldId);
				//}
			}
			clearLiveSearchResults(fieldId);
			return;
		}
		
		// if is text and not filled with XX, (XX = iso language code), call with delay
		if (lastValue.search(/^[A-Z]{2},/) == -1) {
			setTimeout(function () {lsLiveSearch(fieldId, lastValue);}, lsDelay);
		}
	});
}

function lsEmptySearch(fieldId) {
	lsField[fieldId].val('');
	lsSearchField[fieldId].val('');
}

function lsSetSearchKey(fieldId) {
	if (lsListCurrent >= 0) {
		// set selected item
		lsField[fieldId].val(jsonResult[fieldId][lsListCurrent]['key']);
		// run callback on set
		if (lsCallback[fieldId] != undefined) {
			eval(lsCallback[fieldId]);
		}
	}
	else {
		if (lsField[fieldId].val() == '') {
			// empty search if searchkey not avialable
			lsEmptySearch(fieldId);
		}
		else {
			// we have a id -> set searchfield value if not set already
			if (lsSearchField[fieldId].val().search(/^[A-Z]{2},/) == -1) {
				lsSearchField[fieldId].val(lsOldValue[fieldId]);
			}
		}
	}
}

function lsRepositionResultsDiv(fieldId) {
	// get the field position
	var sf_pos    = lsSearchField[fieldId].offset();
	var sf_top    = sf_pos.top;
	var sf_left   = sf_pos.left;

	// get the field size
	var sf_height = lsSearchField[fieldId].height();
	var sf_width  = lsSearchField[fieldId].width();

	// apply the css styles - optimized for Firefox
	lsResultDiv[fieldId].css("position", "absolute");
	lsResultDiv[fieldId].css("left", sf_left);
	lsResultDiv[fieldId].css("top", sf_top + sf_height + 5);
	lsResultDiv[fieldId].css("width", sf_width * 1.25);
}

// clear searchresult div
function clearLiveSearchResults(fieldId) {
	lsResultDiv[fieldId].html('');
	lsResultDiv[fieldId].hide(300);
}

// show live search results
function lsLiveSearch(fieldId, lastValue) {
	// adjust searchresult div to current position
	lsRepositionResultsDiv(fieldId);
	
	// get current value after AJAX searchstart
	var currentValue = lsSearchField[fieldId].val(); 
	
	// if it's equal the value from the time of the call, allow
	if (lastValue != currentValue){
		return;
	}
	
	// empty input
	if (currentValue == ''){
		clearLiveSearchResults(fieldId);
		return;
	}
	
	// get remote data as JSON
	$.getJSON(lsAjaxUrl[fieldId] + '=' + encodeURI(currentValue), function(json) {
		// get result count
		jsonResult[fieldId] = json;
		var resultCount = json.length;
		lsListTotal = resultCount;
		
		if (resultCount > 0) {
			var searchData = '<ul>';
			
			for (var r = 0;r < resultCount;r++) {
				//searchData += "<li class='" + ((r % 2 == 0) ? 'shadow' : '') + "'>" + json[r]['value'].replace((new RegExp("(" + currentValue + ")", "i")), "<b>$1</b>") + "</li>";
				searchData += "<li class='" + ((r % 2 == 0) ? 'shadow' : '') + "'>" + json[r]['value'] + "</li>";
			}
			searchData += '</ul>';

			// update search result div
			lsResultDiv[fieldId].html(searchData);
			lsResultDiv[fieldId].show();
			
			// get all li items ad set selected on mouseover
			var lis = lsResultDiv[fieldId].find('li');
			
			lis.click(function() {
				lsSetSearchKey(fieldId);
			});	
			
			lis.mouseover( function() {
				// reset all classNames
				lis.each(function() {this.className = '';});
				// set selected value to searchfield
				if ((nv = this.childNodes[0].nodeValue) == null) {
					nv = this.childNodes[0].childNodes[0].nodeValue;
				}
				lsSearchField[fieldId].val(nv);
				// set selected className
				this.className = "selected";
				var i = -1;
				lis.each(function() {
					i++;
					if (this.className == 'selected') {
						lsListCurrent = i;
					}
				});
			});

		}
		else {
			clearLiveSearchResults(fieldId);
		}
	});
}

/**
 * handle cursor key, currently check for up/down key
 * @author GANTNER IT-L�sungen 
 */ 
function handleCursor(fieldId, keyCode) {
	// check for cursor up/down/left/right
	// left = 37
	// up = 38
	// right = 39
	// down = 40
	if (keyCode == 37 || keyCode == 38 || keyCode == 39 || keyCode == 40) {
		if (keyCode == 38) {
			if (lsListCurrent == 0 || lsListCurrent == -1){
				// set last position
				lsListCurrent = lsListTotal - 1;
			}
			else {
				// one up 
				lsListCurrent--;
			}
		} else if (keyCode == 40) {
			if (lsListCurrent == lsListTotal - 1){
				// set first position
				lsListCurrent = 0;
			}
			else {
				// one down
				lsListCurrent++;
			}
		}

		// update list selection
		lsResultDiv[fieldId].find('li').each(function(i) {
			if (i == lsListCurrent){
				if ((nv = this.childNodes[0].nodeValue) == null) {
					nv = this.childNodes[0].childNodes[0].nodeValue;
				}				
				lsSearchField[fieldId].val(stripHTML(nv));
				this.className = "selected";
			} else {
				this.className = '';
			}
		});
		
		return true;
	} 
	
	else {
		// reset
		lsListCurrent = -1;
		
		return false;
	}
}