function clearElement(element) {
	while(element.hasChildNodes()) {
		element.removeChild(element.firstChild);
	}
}

function clearElementById(id) {
	var element = document.getElementById(id);
	clearElement(element);
}

function SuggesterItem(name, suggester, parent, input, ul, url_function, fill_function, use_function) {
	this.name = name;
	this.suggester = suggester;

	this.parent = parent;
	this.index = this.parent.index;

	this.input = input;
	this.input.index = this.index;

	this.ul = ul;
	this.ul.index = this.index;

	this.url_function = url_function;
	this.fill_function = fill_function;
	this.use_function = use_function;

	this.selected_index = -1;
	this.last = null;

	this.results = [];
}



SuggesterItem.prototype.call_url_function = function(value) {
	if (this.url_function) {
		return this.url_function(this,value);
	} else {
		return 'http://hlava.net/index.php?url=suggest&value='+value+'&id='+this.input.index;		
	}
}

SuggesterItem.prototype.call_fill_function = function(li,result) {
	if (this.fill_function) {
		return this.fill_function(this,li,result);
	} else {
		li.value = result[0];
		li.appendChild(document.createTextNode(result[1]));
	}
}
	

SuggesterItem.prototype.call_use_function = function() {
	if ((this.selected_index > -1) && (this.selected_index < this.results.length)) {
		if (this.use_function) {
				this.use_function(this,this.results[this.selected_index]);
		} 	else {
			this.input.value = this.ul.childNodes[this.selected_index].firstChild.nodeValue;
		}
	}
	this.ul.style.visibility = "hidden";
}


SuggesterItem.prototype.dispOn = function() {
	clearTimeout(this.timer);
	this.ul.style.visibility = "visible";
	this.selected_index = -1;
}

SuggesterItem.prototype.dispOff = function(noshedule) {
	if (noshedule) {
		this.ul.style.visibility = 'hidden';
		this.selected_index = -1;
	} else {
		this.timer = setTimeout('suggester.item('+this.index+').dispOff(true)', 500);
	}
}



SuggesterItem.prototype.disp = function(results) {

	clearElement(this.ul);
	this.selected_index = -1;
	this.results = results;

	this.ul.style.zIndex = 500;


	for (var i=0; i < this.results.length; i+=1) {
		var li = document.createElement("li");
		li.index = this.ul.index;
		li.parent = this.ul.parent;
		li.selected_index = i;

		this.call_fill_function(li,this.results[i]);

		this.ul.appendChild(li);

		li.onmouseover = function() { 
			var item = suggester.item(this.index); 
			item.selected_index = -1; 
			item.redraw(); 
			this.style.background='#000000'; 
			this.style.color='#FFFFFF'; 
		};

		li.onmouseout = function() { 
			var item = suggester.item(this.index); 
			item.selected_index = -1; 
			item.redraw(); 
			this.style.background='#FAFAF6'; 
			this.style.color='#000000'; 
		};

		li.onclick = function() {	suggester.item(this.index).selected_index = this.selected_index; suggester.use(this.index); };

	}

	if (results.length > 0) {
		this.ul.style.zIndex = 500;
		this.ul.style.visibility = 'visible';
		} else {
		this.ul.style.zIndex = -1;
		this.ul.style.visibility = 'hidden';
	}
}

SuggesterItem.prototype.redraw = function() {
	for (var i = 0; i < this.ul.childNodes.length; i++) {
		if (this.selected_index == i) {
			this.ul.childNodes[i].style.color='#FFFFFF';
			this.ul.childNodes[i].style.background='#000000';
		} else {
			this.ul.childNodes[i].style.background='#FAFAF6';
			this.ul.childNodes[i].style.color='#000000';
		}
	}
}

SuggesterItem.prototype.keys = function(e) {
	if (navigator.appName == 'Netscape') { 
		var key = e.keyCode 
	} else { 
		var key = window.event.keyCode 
	}

  if (key == 38) { // up
	   if (this.selected_index > 0) {
				this.selected_index--;
			}

			this.redraw();
			return false;
	}

	if (key == 40) {  // down
		if (this.selected_index < (this.ul.childNodes.length - 1)) {
			this.selected_index++;
		}

		this.redraw();
		return false;
	}


	if ((key == 13) && (this.selected_index > -1)) {  // nedovoli enter, pokud vybiram sipkama z naseptavatka
		this.suggester.use(this.index);
		return false;
	}
}


function Suggester() {
	this.items = [];
};


Suggester.prototype.register = function(id_name, auto_install, url_function, fill_function, use_function) {
	var o = document.getElementById(id_name);
	if (o) {
		var input = null;
		var ul = null;

		o.index = this.items.length;

		if (auto_install) {
			clearElement(o);

			var input = document.createElement('input');
			var ul = document.createElement('ul');

			this.items.push(new SuggesterItem(id_name, this, o, input, ul, url_function, fill_function, use_function));

			o.appendChild(input);
			o.appendChild(document.createElement('br'));
			o.appendChild(ul);
		} else {

			var inputs = o.getElementsByTagName('input');
			if (inputs.length > 0) {
				input = inputs.item(0);
			} else {
				alert('Can not register '+id_name+' no input defined');
			}
			var uls = o.getElementsByTagName('ul');
			if (uls.length > 0) {
				ul = uls.item(0);
			} else {
				alert('Can not register '+id_name+' no ul defined');
			}

			this.items.push(new SuggesterItem(id_name, this,o,input,ul,url_function, fill_function, use_function));
		}

		input.onkeyup = function() { suggester.go(this.index) }
		input.onkeydown = function(e) { return suggester.keys(this.index,e); }

		input.onblur = function() { suggester.dispOff(this.index,false) }

		input.autocomplete = "off";
		input.setAttribute('autocomplete','off'); 
	} else {
		alert('Can not register '+id_name);
	}
};

Suggester.prototype.item = function(index) {
	if (this.items[index]) {
		return this.items[index];
	} else {
		return false;
	}
};


Suggester.prototype.go = function(index) {
	var item = this.items[index];
	if (item) {
		if (item.input.value != item.last) {
			item.last = item.input.value;
			var oScript = document.createElement('script');
			oScript.setAttribute('type','text/javascript');
			var url = item.call_url_function(item.input.value);
			if (url) {
				oScript.setAttribute('src',url);
				item.parent.appendChild(oScript);
			}
		}
	}
}

Suggester.prototype.disp = function(index,results) {
	var item = this.item(index);
	if (item) {
		item.disp(results);
	}
}

Suggester.prototype.dispOn = function(index) {
	var item = this.item(index);
	if (item) {
		item.dispOn();
	}
}

Suggester.prototype.dispOff = function(index,noshedule) {
	var item = this.item(index);
	if (item) {
		item.dispOff(noshedule);
	}
}

Suggester.prototype.redraw = function(index) {
	var item = this.item(index);
	if (item) {
		item.redraw();
	}
}

Suggester.prototype.use = function(index) {
	var item = this.item(index);
	if (item) {
		item.call_use_function();
		for (var i = 0; i < this.items.length; i++) {
			if (i == index) { continue; }
			var other = this.items[i];
			other.results = item.results;
			other.selected_index = item.selected_index;
			other.call_use_function();
		}
	}
}

Suggester.prototype.keys = function(index,e) {
	var item = this.item(index);
	if (item) {
		return item.keys(e);
	}
	return e;
}
