jQuery.fn.suggest = function( settings) {
	settings = jQuery.extend({
		resultsId:		'',
		resultsClass:	'suggest_results',
		delay:			300,
		minInput:		2,
		data:		[],
		maxResults:		10
	},settings);
	
	var input = this.get(0);
	var $input = $(input);
	var timeout = null;
	var previous = "";
	var active = -1;
	var results = document.createElement('div');
	var lastKey = null;
	
	$(results).attr({id: settings.resultsId});
	$(results).hide().addClass(settings.resultsClass).css("position", "absolute");
	
	$("body").append(results);
	
	$input.attr("autocomplete", "off");
	_hideList();
	
	if(settings.data.length > 0) _renderStaticList();

	function _renderResults(data) {
		var ul = document.createElement('ul');
		var re = new RegExp('('+$input.val()+')', 'i');
		$(data).find('suggestion').each(function(i) {
			if(i <= settings.maxResults) {
				var ref = $(this);
				var text = ref.text();
				var li = document.createElement('li');
				li.innerHTML = text.replace(re,'<b>$1</b>');
				ul.appendChild(li);
			}
		});
		results.appendChild(ul);
		$('li', results).hover(
			function() {
				var list = $('li', results);
				list.removeClass('activ_option');
				$(this).addClass('activ_option');
				active = $('li', results).indexOf($(this).get(0));
			},
			function() {
				$(this).removeClass('activ_option');
			}
		).click(function(e) {e.preventDefault();e.stopPropagation();_select();});
	}
	
	function _renderStaticList() {
		var ul = document.createElement('ul');
		$(settings.data).each(function(i) {
			var text = this;
			var li = document.createElement('li');
			li.innerHTML = text;
			ul.appendChild(li);
		});
		results.appendChild(ul);
		$('li', results).hover(
				function() {
					var list = $('li', results);
					list.removeClass('activ_option');
					$(this).addClass('activ_option');
					active = $('li', results).indexOf($(this).get(0));
				},
				function() {
					$(this).removeClass('activ_option');
				}
			).click(function(e) {e.preventDefault();e.stopPropagation();_select();});
	}
	
	function _search() {
		if(lastKey == 46 || (lastKey > 8 && lastKey <= 32)) return _hideList();
		if($input.val() == previous) return;
		previous = $input.val();
		_cleanList();
		if(previous.length < settings.minInput) return;
		if(settings.data.length > 0) {
			_renderStaticList();
			_showList();
		} else {
			SuggestService.suggestLoctations($input.val(),function(data) {
				_renderResults(data);
				_showList();
			});
		}
		active = -1;
	}
	
	function _keydown(e) {
		lastKey = e.charCode || e.keyCode || -1;
		switch(lastKey) {
			case 9: //tab
			case 13: //return
				if(_select()) {
					e.preventDefault(); //Do not submit form
					$input.focus();
				}
				break;
			case 38: //up
				_moveList(-1);
				break;
			case 40: //down
				_moveList(1);
				break;
			default:
				if (timeout) window.clearTimeout(timeout);
				timeout = window.setTimeout(function () {_search()},settings.delay);
				break;
		}
	}
	
	function _moveList(step) {
		var list = $('li', results);
		if(!list) return;
		active += step;
		
		if(active < 0) {
			active = 0;
		}
		if(active > list.size()) {
			active = list.size()-1;
		}
		
		list.removeClass('activ_option');
		$(list[active]).addClass('activ_option');
	}
	
	function _cleanList() {
		$(results).empty();
	}
	
	function _showList() {
		if(!$(results).is(':empty')) {
			var offset = $input.offset();
			$(results).css({
				width: parseInt($input.width()) + "px",
				top: (offset.top + input.offsetHeight) + "px",
				left: offset.left + "px"
			}).show();
		}
	}
	
	function _hideList(value) {
		if(value == 'true') {
			_hideListNow;
			return false;
		}
		if (timeout) {
			window.clearTimeout(timeout);
		}
		timeout = window.setTimeout(_hideListNow, 200);
	}
	
	function _hideListNow() {
		$(results).hide();
	}
	
	function _select() {
		var li = $('li.activ_option', results);
				
		if(li.text() != '') {
			$input.val(li.text());
			_hideList();
			_cleanList();
			
			return true;
		}
		return false;
	}
	
	$input.bind('keydown.suggest',_keydown);
	$input.bind('blur',_hideList);
	$input.bind('focus',_showList);
}

jQuery.fn.suggestCat = function( settings) {
	settings = jQuery.extend({
		resultsClass:	'suggest_results',
		delay:			300,
		minInput:		2,
		maxResults:		35
	},settings);
	
	var input = this.get(0);
	var $input = $(input);
	var timeout = null;
	var previous = "";
	var active = -1;
	var results = document.createElement('div');
	var lastKey = null;
	
	$(results).hide().addClass(settings.resultsClass).css("position", "absolute");
	
	$("body").append(results);
	
	$input.attr("autocomplete", "off");
	_hideList();			

	function _renderResults(data) {
		var ul = document.createElement('ul');
		var re = new RegExp('('+$input.val()+')', 'i');
		$(data).find('suggestionCat').each(function(i) {
			if(i <= settings.maxResults) {
				var ref = $(this);
				var text = ref.text();
				var li = document.createElement('li');
				li.innerHTML = text.replace(re,'<b>$1</b>');
				ul.appendChild(li);
			}
		});
		results.appendChild(ul);
		$('li', results).hover(
			function() {
				var list = $('li', results);
				list.removeClass('activ_option');
				$(this).addClass('activ_option');
				active = $('li', results).indexOf($(this).get(0));
			},
			function() {
				$(this).removeClass('activ_option');
			}
		).click(function(e) {e.preventDefault();e.stopPropagation();_select();});
	}
	
	function _search() {
		if(lastKey == 46 || (lastKey > 8 && lastKey <= 32)) return _hideList();
		if($input.val() == previous) return;
		previous = $input.val();
		_cleanList();
		if(previous.length < settings.minInput) return;
		SuggestService.suggestCategories($input.val(),function(data) {
			_renderResults(data);
			_showList();
		});
		active = -1;
	}
	
	function _keydown(e) {
		lastKey = e.charCode || e.keyCode || -1;
		switch(lastKey) {
			case 9: //tab
			case 13: //return
				if(_select()) {
					e.preventDefault(); //Do not submit form
					$input.focus();
				}
				break;
			case 38: //up
				_moveList(-1);
				break;
			case 40: //down
				_moveList(1);
				break;
			default:
				if (timeout) window.clearTimeout(timeout);
				timeout = window.setTimeout(function () {_search()},settings.delay);
				break;
		}
	}
	
	function _moveList(step) {
		var list = $('li', results);
		if(!list) return;
		active += step;
		
		if(active < 0) {
			active = 0;
		}
		if(active > list.size()) {
			active = list.size()-1;
		}
		
		list.removeClass('activ_option');
		$(list[active]).addClass('activ_option');
	}
	
	function _cleanList() {
		$(results).empty();
	}
	
	function _showList() {
		if(!$(results).is(':empty')) {
			var offset = $input.offset();
			$(results).css({
				width: parseInt($input.width()) + "px",
				top: (offset.top + input.offsetHeight) + "px",
				left: offset.left + "px"
			}).show();
		}
	}
	
	function _hideList(value) {
		if(value == 'true') {
			_hideListNow;
			return false;
		}
		if (timeout) {
			window.clearTimeout(timeout);
		}
		timeout = window.setTimeout(_hideListNow, 200);
	}
	
	function _hideListNow() {
		$(results).hide();
	}
	
	function _select() {
		var li = $('li.activ_option', results);
				
		if(li.text() != '') {
			$input.val(li.text());
			_hideList();
			_cleanList();
			
			return true;
		}
		return false;
	}
	
	$input.bind('keydown.suggest',_keydown);
	$input.bind('blur',_hideList);
	$input.bind('focus',_showList);
}

jQuery.fn.indexOf = function(e){
	for( var i=0; i<this.length; i++ ){
		if( this[i] == e ) return i;
	}
	return -1;
};

