/**
 * vstupni bod pro modul
 * 
 * zavislosti:
 * pro fungovani potrebuje jquery
 */

/**
 * objekt vyhledavace
 * 
 * @param _elemetId id elementu na ktery se ma naseptavac navazat
 * @param url url na ktere se ma dotazovat pro data
 * @param rendererCallback metoda, ktera prevede json obljekt na objekt naseptavace
 */
function JsWhisperer(_elemetId, _url, _rendererCallback) {
	/**
	 * element na ktery se naseptavac vaze
	 */
	var element = $("#"+ _elemetId);
	/**
	 * url kam posilat dotazy
	 */
	var url = _url;
	/**
	 * callback funkce ktera renderuje jden element vraceny od serveru
	 */
	var rendererCallback = _rendererCallback;
	/**
	 * seriove cislo odesilaneho pozadavku
	 */
	var serialNumber = 1;
	/**
	 * seriove cislo posledniho prijateho pozadavku
	 */
	var lastRecivedSerialNumber = 0;
	/**
	 * index vybraneho produktu
	 */
	var selectedIndex = -1;
	/**
	 * posledni zobrazovani text
	 */
	var lastText = "";
	/**
	 * posledni objekty, ktere server vratil
	 */
	var lastObjects = [];
	/**
	 * posledni jquery objekty, ktere server vratil
	 */
	var lastJqueryObjects = [];
	/**
	 * souradnice leveho horniho rohu
	 */
	var position = element.offset();
	/**
	 * panel obsahujici vysledky naseptavani
	 */
	var popupPanel = $('<ul style="position:absolute;" class="js-whisperer-popup-panel '+ _elemetId +'-js-whisperer-popup-panel"></ul>');
	popupPanel.hide();
	popupPanel.css(position);
	// pridat do dokumentu
	$("body").append(popupPanel);	
	
	// nastav udalosl pro focus elementu
	element.focus(function() {
		popupPanel.show("slow");
	});
	// nastav udalosl pro blur elementu
	element.blur(function() {
		setTimeout(function() {
			popupPanel.hide("slow");
		}, 100);
	});
	// zmacknuti nejake klavesy
	element.keyup(function(event) {
		if(event.keyCode == 40) {// sipka dolu
			if(lastJqueryObjects.length > selectedIndex+1) {
				selectedIndex++;
				if(selectedIndex > 0)
					lastJqueryObjects[selectedIndex-1].removeClass("forused");
				lastJqueryObjects[selectedIndex].addClass("forused");
			}
		} else if(event.keyCode == 38) { // sipka nahoru
			if(0 <= selectedIndex) {
				lastJqueryObjects[selectedIndex--].removeClass("forused");
				if(selectedIndex >= 0)
					lastJqueryObjects[selectedIndex].addClass("forused");
			}
		} else if(lastText != element.val()) { // zmenil se text v poli
			lastText = element.val();
			// zakodovava ceske znaky
			_makeServerCall(encodeURI(lastText), serialNumber++);
		}
	});
	// nastavuje udealost na odeslani formulare jen pokud neni vybrana zadna moznost jinak presmeruje na stranku produktu
	element.closest("form").submit(function() {
		if(selectedIndex >= 0 
			&& selectedIndex < lastObjects.length) {
			window.location = lastObjects[selectedIndex].url;
			return false;
		}
		return selectedIndex < 0;
	});
	
	/**
	 * posune oteviraci okno
	 */
	this.adjustPosition = function(_top, _left) {
		position.top += _top;
		position.left += _left;
		popupPanel.css(position);
	}
	
	/**
	 * zavola server
	 * @param findValue
	 * @param serialNumber
	 */
	function _makeServerCall(findValue, serialNumber) {
		jQuery.getJSON(url, // je nutne nastavit
				{find: findValue, serialNumber: serialNumber},
				function(data) {	
					_RenderResults(data.results, data.serialNumber);
				}
		);
	}
	
	/**
	 * vyrenderuje vysledek
	 * @param data
	 * @param serialNumber
	 */
	function _RenderResults(data, serialNumber) {
		if(serialNumber > lastRecivedSerialNumber) { // kontrola aby se nerenderovaly predchozi requesty
			lastRecivedSerialNumber = serialNumber;
			popupPanel.empty();
			lastObjects = data;
			lastJqueryObjects.length = 0;
			selectedIndex = -1;
			jQuery.each(data, function(index, value) {
				var valueString = _rendererCallback(value);
				var valueObject = $(valueString);
				lastJqueryObjects.push(valueObject);
				popupPanel.append(valueObject);
			});
		}
	}
}
