var SearchBox = function(element){
	var T = this,
		container = $(element),
		input = $("input", container),
		dropdown = $(".dropdown", container),
		itemlist = $("ul", dropdown),
		requestTimer = null,
		hideTimer = null,
		mouseOverControl = false,
		inputHasFocus = false,
		suggestCache = {},
		xRequest,
		prevSearch = "",
		searchActive = false,
		params = {
			/**
			 * Задержка до запроса на сервер
			 */
			requestDelay: 500,			
			/**
			 * Время анимации открытия списка
			 */
			animDuration: 150,			
			/**
			 * %s заменяется на encodeURIComponent(findString)
			 */
			searchURL: "/media/serch.php?site=" + encodeURIComponent(location.pathname.replace(/^\/|\/$/g, "")) + "&s=%s",
			/**
			 * Задержка скрытия
			 */
			hideDelay: 500
		},
		cancelCallback = false;
		
		
	function init() {
		input.bind("keyup", function () {
			var searchStr = input.val().replace(/^\s+|\s+$/, ""),
				cachedSuggestions;

			if (!searchStr) {
				hideDrop();
				cancelCallback = true;
				return;
			}
			
			if (prevSearch == searchStr) {
				return;
			} else {
				prevSearch = searchStr;
			}
			
			clearTimeout(requestTimer);
			if (cachedSuggestions = suggestCache[searchStr]) {
				setSuggestions(cachedSuggestions);
			} else {
				requestTimer = setTimeout(function () {
					loadSuggestions(searchStr, function (data) {
						if (!cancelCallback) {
							setSuggestions(data);
						}
					});
				}, params.requestDelay);
			}
		});
		
		input.bind("blur", function () {
			inputHasFocus = false;
			if (!mouseOverControl) {
				hideDrop();
			}
		})
		
		input.bind('focus', function () {
			inputHasFocus = true;
			cancelDelayedHideDrop();
		});
		
		container.bind("mousemove", function () {
			mouseOverControl = true;
			cancelDelayedHideDrop();
		});

		container.bind("mouseout", function () {
			mouseOverControl = false;
			if (!inputHasFocus) {
				delayedHideDrop();
			}
		});
	}
	
	function showDrop() {
 		itemlist.slideDown(params.animDuration);
 	}
	
 	function cancelDelayedHideDrop() {
 		clearTimeout(hideTimer);
 	}
 	
	function delayedHideDrop() {
		hideTimer = setTimeout(function () {
			hideDrop();
		}, params.hideDelay);
	}
	
	function hideDrop() {
		itemlist.slideUp(params.animDuration);
	}
		
	/**
	 * Асинхронное обращение к серверу за подсказкой. Запрос кешируется
	 * 
	 * @param findStr {String} Строка поиска
	 * @param callback {Function} Функция-обработчик загруженных данных
	 */
	function loadSuggestions(searchStr, callback) {
		// TODO останавливать загрузку от предыдущего запроса, если еще не завершилась
		if (!searchStr) {
			return [];
		}
		
		searchStr += "";
		
		var suggestions = [],
			cachedSuggestions,
			url;
		
		url = params.searchURL.replace("%s", encodeURIComponent(searchStr));
		
		xRequest = $.get(url, function (strData) {
			//TODO заменить на JSON parser
			var data = eval(strData);

			suggestCache[searchStr] = data;
			callback(data);
		});
	}
	
	/**
	 * Установка списка подсказок
	 * 
	 * @param suggList {Array} 
	 */
	function setSuggestions(suggList) {
		var suggestHtml = "";
		for (var i = 0, suggest; suggest = suggList[i]; ++i) {
			suggestHtml += "<li><a href=\"" + suggest.href + "\">" + suggest.name + "</a></li>";
		}
		itemlist.html(suggestHtml);
		
		if (suggList.length) {
			T.onsuggest.call(T, suggList);
			showDrop();
		}
	}
	
	/**
	 * Callback
	 */
	this.onsuggest = function () {
		//console.log("onsuggest");
		SiteHelper.updatePlayLists(dropdown[0]);
	};
	
	init();
}


$(window).bind("load", function () {
	$(".searchbox").each(function(){
		new SearchBox(this);
	});
})

