autoCompleteCache = new Array();

function showAutoComplete(where, type, event) {
	//if (Prototype.Browser.IE) autocompleteMove(event, where, type);
	if (event !== undefined && (event.keyCode == 13 || event.keyCode == 38 || event.keyCode == 40 || event.keyCode == 27))
		return ;
	
	var val = "";
	val = $F(where + '_' + type);
	if (val != $F(where + '_geo_text')) {
		$(where + '_geo_text').value = val;
	}
	
	//get first letter of input
	val = val.substring(0, 1).toLowerCase();
	
	//if input not empty
	if (!val.empty()) {
	    
		//#start
		$(where + '_' + type + '_icon').addClassName('searchgo');
		
		//check cache
		result = getCache(type, val);
		
		//if not cached
		if (result === false) {
			
			//create cache
			createCache(type, val);
			
			//perform ajax query
			var url = baseUrl + 'offer/ajax/todo/autocomplete/';
			new Ajax.Request(url, {
				method: 'post',
				parameters: {
					value 	: val,
					type 	: type
				},
				
				//on success, get response from json
				onSuccess: function(transport) {
					result = transport.responseText.evalJSON();

					//if response empty
					if (!result.length) {
						
						//set result to 'false'
						result = 'false';
					}
					
					//set cache
					setCache(type, val, result);
					
					//draw autocomplete
					drawAutoComplete(where, type, result);
					
					//#end
					$(where + '_' + type + '_icon').removeClassName('searchgo');
				},
				onFailed: function() {
					alert('Ошибка на стороне сервера.');
				}
			});
		
		//if cache exist
		} else if (result != '') {
			
			//draw autocomplete from cache
			drawAutoComplete(where, type, result);
			
			//#end
			$(where + '_' + type + '_icon').removeClassName('searchgo');
		}
		
	//if input is empty
	} else {
		var check_ac_div = $(where + '_' + type + '_ac');
		
		//if autotcomplete not already hiding
		//#HARDCODED: checking by style.opacity (changed with Scriptaculous Effect.Fade())
		if (check_ac_div && !check_ac_div.style.opacity) {

			//hide autocomplete
			hideAutoComplete(where, type, true);
			
		}
	}
}

function drawAutoComplete(where, type, result) {
	
	function _highlight(val, name, full_name) {
		
		if (name.toLowerCase().indexOf(val.toLowerCase()) == 0) {

			//if coincidence in name
			var new_name = '<span id="item_col" class="colored">' + name.substring(0, val.length) + '</span>' + name.substring(val.length, name.length - val.length + name.substring(0, val.length).length);
			return full_name.replace(name, new_name);
			
		} else if (full_name.toLowerCase().indexOf(val.toLowerCase()) == 0) {

			//if coincidence in full name
			return '<span id="item_col" class="colored">' + full_name.substring(0, val.length) + '</span>' + full_name.substring(val.length, full_name.length - val.length + full_name.substring(0, val.length).length);

		} else {
			return 0;
		}
	}
	
	//if type still not changed when ajax executing
	if ($F(where + '_geo_type') == type) {

		//if autocomplete already exists
		var test_ac_div = $(where + '_' + type + '_ac');
		var fade = "";
		if (test_ac_div) {
			
			//redraw without fading
			fade = false;
			hideAutoComplete(where, type, fade);
		} else {
			//else fade
			fade = true;
		}
		
		//get actual value
//		var val = $F(where + '_' + type);
		var val = $F(where + '_geo_text');
		
		
		//create container
		var ac_div = document.createElement('div');
		ac_div.id = where + '_' + type + '_ac';
		ac_div.style.position = 'absolute';
		ac_div.style.top = getElementPosition(where + "_" + type).top + "px";
		ac_div.style.left = getElementPosition(where + "_" + type).left + "px";
		$('body').appendChild(ac_div);
		
		
		//if result not empty
		if (result !== 'false') {
			
			//define drawed counter
			var drawed = 0;
			
			//foreach element
			var lim = result.length;
			for (var i = 0; i < lim; i++) {
				
				//check and highlight element
				main = _highlight(val, result[i]['name'], result[i]['full_name']);
				if (main != 0) {
					
					//if element is good, perform additional info (path, synonym)
					var additional = '';
					if (result[i]['synonym'] != '') {
						additional += '<span class="colored">' + result[i]['synonym'] + '</span><br />';
					}
					additional += result[i]['path'];
					
					//add output to autocomplete
					var name = "";
					if (result[i]['synonym'] != '') {
						name = result[i]['full_name'];//['synonym'];
					} else if (type == 'street') {
						name = result[i]['name'];
					} else {
						name = result[i]['full_name'];
					}
					ac_div.innerHTML += '<div id="item_' + drawed + '" class="item" onmouseover="addHover(this);" onmouseout="removeHover();" onclick="selectGeo(\'' + where + '\', \'' + type + '\', ' + result[i]['id'] + ', \'' + name + '\');"><div id="res_' + drawed + '" style="display: none" >' + name + '</div><div id="id_' + drawed + '" style="display: none" >' + result[i]['id'] + '</div><h2 class="textsize2">'+main+'</h2><span class="textsize3">'+additional+'</span></div>';
					//ac_div.innerHTML += '<div style="cursor: pointer;" onclick="selectGeo(\'' + where + '\', \'' + type + '\', ' + result[i]['id'] + ', \'' + name + '\');" onmouseover="this.style.background=\'#F4D71B\';" onmouseout="this.style.background=\'#000\';"><span style="font-size: 16px;">' + main + '</span><br /><span style="font-size: 11px;">' + additional + '</span></div><hr>';
					
					//increase counter
					drawed++;
				}
				
				//if output limit reached
				if (drawed == 10) {
					
					ac_div.innerHTML += '<div class="textsize3">ещё ' + (lim - 10) + ' совпадений</div>';
					break;
				}
				
			}
			
			//if no elements drawed, draw "No matches"
			if (!drawed) {
			    if (ac_div){
				ac_div = $(ac_div);
				ac_div.remove();
			    }
			}
			
			//show container
			if (drawed) {
				if (fade) {
					Effect.Appear(where + '_' + type + '_ac', {duration: 0.5});
				} else {
					$(where + '_' + type + '_ac').style.display = 'block';
				}
			}
			ac_div.className = 'display list_street';
		
		//if result is empty, draw "No matches"
		}
	}
}

function addHover(el) {
	removeHover();

	el = $(el);
	$(el).removeClassName('item');
	$(el).addClassName('item_hover');

	var span = $(el).select('span')[0];
	span = $(span);
	if (span) {
		span.addClassName('colored4');
		span.removeClassName('colored');
	}
}

function removeHover() {
	$$('div.item_hover').each(function (div){
		$(div).removeClassName('item_hover');
		$(div).addClassName('item');
	});

	$$('span.colored4').each(function (span){
		$(span).removeClassName('colored4');
		$(span).addClassName('colored');
	});
}

function hideAutoComplete(where, type, fade) {
	//clear element
	var ac_div = $(where + '_' + type + '_ac');
	$(where + '_' + type).removeClassName('input_load');
	if (ac_div) {
		if (fade) {
			Effect.Fade(where + '_' + type + '_ac', {duration: 0.5});
			setTimeout('removeAutocompleteDiv();', 500);
		} else {
			ac_div.remove();
		}
	}
	
}

function removeAutocompleteDiv() {
    if ($$('div.list_street')[0]) {
	$$('div.list_street')[0].remove();
    }
}



function getCache(type, value) {
	var check_val = value;
	while (check_val != '') {
		
		//if cache container exist
		if (autoCompleteCache[type] && autoCompleteCache[type][check_val]) {
			
			//if cache container is empty and its last symbol, return "empty"
			if (autoCompleteCache[type][check_val] === 'false') {
				if (check_val.length == 1) {
					return 'false';
				}
				
			//if cache container not empty, return it
			} else {
				return autoCompleteCache[type][check_val];
			}
		}
		
		//if nothing to return, decrease input for 1 sybmol from end
		check_val = check_val.substring(0, check_val.length - 1);
	}
	
	//if all sybmols checked and no cache, return "no cache"
	return false;
	
}

function setCache(type, value, result) {
	
	//set cache
	autoCompleteCache[type][value] = result;
	
}

function getElementPosition(elemId){
	var elem = $(elemId);
	var w = elem.offsetWidth;
	var h = elem.offsetHeight;
	var l = 0;
	var t = elem.offsetHeight;
	while (elem){
		l += elem.offsetLeft;
		t += elem.offsetTop;
		elem = elem.offsetParent;
	}
	return {"left":l, "top":t, "width": w, "height":h};
}

function createCache(type, value) {
	
	//create cache container
	if (!autoCompleteCache[type]) {
		autoCompleteCache[type] = new Array();
	}
	if (!autoCompleteCache[type][value]) {
		autoCompleteCache[type][value] = new Array();
	}
	
}

autocompleteMove = function(event, where, type) {
	//alert('keyCode ' + event.keyCode);
	//alert('keyIdentifier ' + event.keyIdentifier);
	if (Prototype.Browser.Opera) showAutoComplete(where, type, event);
	
	var div_ac = $(where + "_" + type + "_ac");
	var hover_id = "", m = -1;
	if (div_ac) {
		$$('div.item_hover').each(function(div){
			hover_id = div.id;
		});
		var re = new RegExp("item_([0-9])+");
		var re_m = re.exec(hover_id);
		if (re_m) {
		    m = re_m[1];
		}
		
		switch (event.keyCode) {
			case 40 :
				//down
				m++;
				if (m > parseInt((div_ac.select('div').length / 3)  - 1)) {
					m = 0;
				}
				addHover("item_" + m);
				selectGeo(where, type, $("id_" + m).innerHTML, $("res_" + m).innerHTML);
			break;
			case 38 :
				//up
				m--;
				if (m <= -1) {
				    m = parseInt((div_ac.select('div').length / 3)  - 1);
				}
				addHover("item_" + m);
				selectGeo(where, type, $("id_" + m).innerHTML, $("res_" + m).innerHTML);
			break;
			case 13 :
				//enter
				if (m != -1) {
					selectGeo(where, type, $("id_" + m).innerHTML, $("res_" + m).innerHTML);
					hideAutoComplete(where, type, 1);
				}
			break;
			case 27 :
				//esc
				hideAutoComplete(where, type, 1);
			break;
		}
	}
}
