var debug = false;
window.log = function() {
	if (debug) {
		log.history = log.history || [];	 // store logs to an array for reference
		log.history.push(arguments);
		if(this.console) console.log( Array.prototype.slice.call(arguments) );
	}
};

var _LT = function(inputField, outputField, options) {
	var self = this; // self-hack

	self.element = _getById(inputField);
	self.element.setAttribute("autocomplete", "off");
	self.update	 = _getById(outputField);
	self.formElement = _getFormElement();
	self.originalValue = self.element.value;
	self.options = {
		host: "localhost",
		param: "query",
		jsonCallback: 'demo_suggest._results',
		select: "group",
		hl: 1
	}
	for(option in options) {
		self.options[option] = options[option];
	}
	self.extractRegex = new RegExp('<span class="' + self.options.select + '"[^>]*>(.*?)<\/span>', '');	
	if(self.options["hiddenSelect"]) self.hiddenRegex = new RegExp('<span class="' + self.options.hiddenSelect + '"[^>]*>(.*?)<\/span>', '');
	self.htmlRescueRegex = new RegExp("(<[^>]*)<b>(.*?)<\/b>", 'g');
	self.htmlRescueRegex2 = new RegExp("(&[^;]*)<b>(.*?)<\/b>", 'g');

	self.cache = {};
	self.index = -1;
	
	_addEvents();
	
	function _getFormElement() {
		var parent = self.element.parentNode;
		while(parent.tagName.toLowerCase() != 'form') {
		if(parent.tagName.toLowerCase() == 'body') return null;
			parent = parent.parentNode;
		}
		return parent;
	}

	function _search() {
		self.index = -1;
		log(value);
		var value = _trim(self.element.value);
		if (value.length == 0) {
			_hide_update();
			return false;
		}
		if (self.cache[value]) { self._results(self.cache[value]); return false; }
		if (value.length == 0) return false;
		var url = _url() + value;
		if(self.options["getAddField"]) {
			var add = _getById(self.options.getAddField).value;
			if(add && add != '') url += "&" + add;
		}
		if (self.scriptTag) self.scriptTag.parentNode.removeChild(self.scriptTag);
		
		self.scriptTag = _newElement('script', { src: url, type: 'text/javascript' }, '');
		document.getElementsByTagName('head')[0].appendChild(self.scriptTag);			 
		
	}

	function _getUlHtml(list, hlRegex, liClass) {
		var listElements = "";
        var max_length = list.length;
        if (typeof(search_small) != "undefined"){
            if(max_length > 4) max_length = 4;
        }
		for (var i = 0; i < max_length; i++) {
			var content;
			if(list[i]["header"] && list[i]["list"]) {
				content = '<span class="group">' + list[i].header + '</span>';
				if(list[i]["select"]) {
					listElements += _newElementString('li', { "onmouseout": '_LT._deselect(this)', "onmouseover": '_LT._select(this)', "title": "", "class": liClass }, content + ' <span class="' + self.options.select + '" style="display:none;">' + list[i].select + "</span>");
				} else if(list[i]["deeplink"]) {
					listElements += _newElementString('li', { "deeplink": list[i].deeplink, "onmouseout": '_LT._deselect(this)', "onmouseover": '_LT._select(this)', "title": "", "class": liClass	}, content);
				} else {
					listElements += _newElementString('li', { "title": "", "class": liClass + '_ns' }, content);
				}				

				listElements +=	 _getUlHtml(list[i].list, hlRegex, liClass + '_sub');
				continue;
			}

			if(!(list[i]["group"]) && !(list[i]["header"])) continue;
			if(self.options.hl) {
                var group = list[i]["group"];
                if (list[i][group]){
				    var hl = list[i][group].replace(hlRegex, "<b>$1</b>");
				    hl = hl.replace(self.htmlRescueRegex, "$1$2");
				    hl = hl.replace(self.htmlRescueRegex2, "$1$2");
				    //content = '<img src="' + list[i]["url"] + '" /><span class="group">' + hl + "</span>";
                    if(typeof(list[i]["url"])=="undefined"){
                        list[i]["url"] = _get_default_cover();
                    }
                    content = '<div class="group"><div class="chart_image"><img src="'+ list[i]["url"] + '" /></div><div class="padder_l_48 padder_14">' + hl + "</div></div>";
                }
			}
            else{
                if(typeof(list[i]["url"])=="undefined"){
                   list[i]["url"] = _get_default_cover();
                }
                content = '<img class="chart_image float_none" src="' + list[i]["url"] + '" /><span class="group">' + list[i]["Interpret"] + "</span>";
            }


			if (self.options.extraField && list[i][self.options.extraField]) {
				 content += " <span class='extraField'>" 
							+ list[i][self.options.extraField] 
							+ "</span>"
			}

			if (self.options.select != 'group' && list[i][self.options.select]) {
				 content += ' <span class="' 
				+ self.options.select 
				+ '" style="display:none;">'
				+ list[i][self.options.select] 
				+ "</span>"
			}

			if(self.options["hiddenSelect"]) content += '<span class="' + self.options.hiddenSelect + '" style="display:none;">' + list[i][self.options["hiddenSelect"]] + "</span>";

			listElements += _newElementString('li', { "deeplink": list[i].deeplink, "onmouseout": '_LT._deselect(this)', "onmouseover": '_LT._select(this)', "title": list[i].meta ? list[i].meta : "", "class": liClass }, content);
		 };

		return listElements;
	}
	
	self._results = function(result) {
		if (!self.cache[result.query]) self.cache[result.query] = result;
		if (result.suggests && result.suggests.length > 0) {
			
			self.update.innerHTML = '';
			var hlRegex = new RegExp("(" + self.originalValue.replace(/^ +/, "").replace(/ +$/,"").split(" ").join("|") + ")", 'ig');
			var html = _getUlHtml(result.suggests, hlRegex, 'autocomplete_results');

			self.update.innerHTML = _newElementString('ul', { id: 'autocomplete_results' }, html);
			self.resultElements = self.update.firstChild.childNodes;
			
			_show();
		}
		else if (typeof(result.suggests) === 'undefined') {}
		else self.update.style.display = 'none';
	}
	
	function _url() {
		var host = self.options.host.match(/^.*\:\/\//) ? self.options.host : "http://" + self.options.host;
		return(host + self.options.url + "?jsoncallback=" + self.options.jsonCallback + "&" + self.options.param + "=");
	}
	
	function _newElement(tag, options, content) {
		var element = document.createElement(tag);
		for (option in options) {
			element.setAttribute(option, options[option]);
		}
		if (tag != 'script' && content) {
			var text = document.createTextNode(content);
			element.appendChild(text);
		}
		return element;
	}
	
	function _newElementString(tag, options, content) {
		var html = "<" + tag;
		for (option in options) {
			html += " " + option + "='" + options[option] + "'";
		}
		html += ">" + content + "</" + tag + ">";
		return html;
	}
	
	function _trim(text) {
		text = text.replace( /^\s+/g, "" );
		return text.replace( /\s+$/g, "" );
	}
	
	function _addEvent(evnt, elem, func) {
		elem = _getById(elem);
		if (elem.addEventListener)
			elem.addEventListener(evnt, func, false);
		else if (elem.attachEvent) {
			var r = elem.attachEvent("on" + evnt, func);
			return r;
		}
	}
	
	function _stopEvent(e) {
		if (e && e.stopPropogation) e.stopPropogation();
		else if (window.event && window.event.cancelBubble)
			window.event.cancelBubble = true;
		if (e &&e.preventDefault) e.preventDefault();
		else if (window.event && window.event.returnValue)
			window.event.returnValue = false;
	}
	
	function _eventElement(e) {
		var targ;
		if (!e) e = window.event;
		if (e.target) targ = e.target;
		else if (e.srcElement) targ = e.srcElement;
		if (targ.nodeType == 3) targ = targ.parentNode;
		return targ;
	}
	
	function _show() {
		self.update.style.display = 'block';
	}
	function _hide() {
		self.update.style.display = 'none';
		//self.element.blur();
	}
	function _hide_update() {
		self.update.style.display = 'none';
	}

	
	function _stripTags(string) {
		return string.replace(/(<([^>]+)>)/ig,"").replace(/\(.*\)/ig, '');
	}
	
	function _addEvents() {
		// event delegation
		_addEvent('blur', self.element, function(event) {
			self.element.setAttribute("hasFocus", "false");
		});
		_addEvent('focus', self.element, function(event) {
			if(self.options["hiddenField"]) {
				_getById(self.options["hiddenField"]).value = null; 
				self.element.value = "";
			}
			self.element.setAttribute("hasFocus", "true");
		});
		_addEvent('keyup', self.element, _onkeyup);
		_addEvent('keydown', self.element, _onkeydown);
		_addEvent('click', self.update, function(event) {
			var element = _eventElement(event);
			/*if (element == self.element) {
				_show();
			}*/
			//else {
				while ( (element.tagName.toLowerCase() != 'li') &&
				(element.tagName.toLowerCase() != 'body') ) element = element.parentNode;
//				if (element.tagName.toLowerCase() == 'span') element = element.parentNode;
				if (element.tagName.toLowerCase() == 'li') { //&& element.className == 'lt_selected'
				if(_getById(element).className.match(/_ns$/)) {
					return;
				}
				var url = element.getAttribute("deeplink");
				var value = $j('.lt_selected_autocomplete_results_sub').text();//_extractTerm(element);
				self.element.value = value;
				_submit(url);
			}	 
			_hide();
			//}
		});
		_addEvent('click', document.body, function(event) {
			if (_eventElement(event) != self.element && self.update.style.display == 'block') {
				_hide();
			}
		});

	}
	
	function _submit(url) {
		if (!url && self.index < 0) return false;
		if (!url) {
			url = self.resultElements[self.index].getAttribute("deeplink");
		}
		if(self.options["hiddenSelect"] && self.options["hiddenField"] && (self.index >= 0))
        	_getById(self.options.hiddenField).value = _extractHidden(self.resultElements[self.index]);

		if (url && url != "undefined") {
			window.location.href = url;
		} else if(self.formElement != null) {
			self.formElement.submit()
		} else if(self.options["hiddenSelect"] && self.options["hiddenField"]) {
			_hide();
		} else return false;
	}
	
	function _deselectElements(elements) {
		for (var i = elements.length - 1; i >= 0; i--){
			elements[i].className =	 elements[i].className.replace(/lt_selected_/, "");
		};
	}
	
	function _onkeyup(event) {
		if (self.element.getAttribute("hasFocus") === "true") {
			switch(event.keyCode) {
				case 27: // ESC
					_hide();
					_stopEvent(event);
					ltIndex = -1;
					break;
				case 39: // cursor right
					_hide();
					_stopEvent(event);
					break;
				case 38: // cursor up
					_stopEvent(event);
					_markPrevious();
					break;
				case 40: // cursor down
					_stopEvent(event);
					_markNext();
					break;
				case 13: // Return key
					_stopEvent(event);
					_submit();
					break;
				default:
					self.originalValue = self.element.value;
					_search();
					break;
			}
		}
		/*else {
			_search();
			if (self.element.getAttribute("hasFocus") === "true" && self.update.innerHTML.length == 0) {
				_show();
				_stopEvent(event);
			}
		}*/
	}
	
	function _onkeydown(event) {
		if (self.element.getAttribute("hasFocus") === "true") {
			switch(event.keyCode) {
				case 38:
					_stopEvent(event);
					break;
				case 40:
					_stopEvent(event);
					break;
			}
		}
	}
	
	function _markNext() {
		self.index = (self.index == self.resultElements.length -1) ? 0 : self.index + 1;
		_deselectElements(self.resultElements);
		if (self.index > -1) {
			if(_getById(self.resultElements[self.index]).className.match(/_ns$/)) _markNext();
			else {
				_LT._select(self.resultElements[self.index]);
				_show();
				self.element.value = $j('.lt_selected_autocomplete_results_sub').text(); //_extractTerm(self.resultElements[self.index]);
			}
		}
/*		else if (self.fromElement == null) {
				self.index = 0;
				_LT._select(self.resultElements[self.index]);
		}*/
		else {
			self.element.value = self.originalValue;
			_hide();
		}
	}
	
	function _markPrevious() {
		self.index = (self.index == -1) ? self.resultElements.length -1	 : self.index - 1;
		_deselectElements(self.resultElements);
		if (self.index > -1) {
			if(_getById(self.resultElements[self.index]).className.match(/_ns$/)) _markPrevious();
			else {
				_LT._select(self.resultElements[self.index]);
				_show();
				self.element.value = $j('.lt_selected_autocomplete_results_sub').text(); //_extractTerm(self.resultElements[self.index]);
			}
		}
/*		else if (self.fromElement == null) {
		self.index = 0;
		_LT._select(self.resultElements[self.index]);
		}*/
		 else {
			self.element.value = self.originalValue;
			_hide_update();
		}
		return false;
	};
	
	function _extractTerm(element) {
		var html = $j(element).find("." + self.options.select);
		if (html && html[0]) return _stripTags(html[0].innerHTML);
		else return "";
	}
	function _extractHidden(element) {
		var html = $j(element).find("." + self.options.select);
		if (html && html[0]) return _stripTags(html[0].innerHTML);
		else return ""; //_stripTags(self.extractRegex);
	}

	/*document.onkeyup = function keyPress(event) {
		if (typeof(event) == "undefined") event = window.event;
		_onkeyup(event);
	}
	document.onkeydown = function keyPressDown(event) {
		if (typeof(event) == "undefined") event = window.event;
		_onkeydown(event);
	}*/
	
}


_LT._select = function(element) {
	_getById(element).className = 'lt_selected_' + _getById(element).className.replace(/lt_selected_/, "");
};
_LT._deselect = function(element) {
	_getById(element).className = _getById(element).className.replace(/lt_selected_/, "");
};

function _getById(element) {
	if (typeof(element) == 'string')
		return document.getElementById(element);
	else
		return element;
}

function _get_default_cover(){
     var randomnumber=Math.floor(Math.random()*22);
     var picture_name = "TuneStar-default-cover-" + randomnumber + "_100.png";
     var cover = 'http://media.tunestar.de/themes/musicbox/images_ts/' + picture_name;
     return cover;
}
