/*===========================================================
Aktíválja az automatikus kiegészítést a megadott mezőhöz.
A mezőnek IE esetén tartalmaznia kell az autocomplete="off"
attribútumot! (nem szabványos, de csak így működik jól)

Paraméterek:
	field	: Az akítválandó mező. Lehet node vagy "form::field" alakú string.
	id		: Azonosító a lekérdezéshez
	url		: A server oldali script url-e.
===========================================================*/
function AutoComplete(field, id_query, url, callback)
{
	if( typeof(field) == "string" )
	{
		var fname = field.split("::")[0];
		var iname = field.split("::")[1];
			var field = document.forms[fname][iname];
	}

	this.field		= field;
	this.id_query	= id_query;
	this.id			= fname+"::"+iname+"-"+id_query;
	this.url		= url;
	if( callback )
		this.callback = callback;

	this.field.autocomplete = "off";
	AutoComplete.prototype.instances[this.id] = this;
	eval('this.field.onkeyup = function (e) {return AutoComplete.prototype.instances["'+this.id+'"].getList(e||event)};');
	eval('this.field.onkeydown = function (e) {return AutoComplete.prototype.instances["'+this.id+'"].checkAction(e||event)};');
	eval('this.field.onblur = function (e) {return AutoComplete.prototype.instances["'+this.id+'"].blurHandler(e||event)};');
	eval('this.field.onfocus = function (e) {return AutoComplete.prototype.instances["'+this.id+'"].clearTimer()};');
}

AutoComplete.prototype = {
	instances	: {},
	cssClass	: "autocomplete",	// A választó doboz css osztálya
	field		: null,
	url			: "",
	id			: "",
	id_query	: "",
	list		: [],
	pfx			: "",				// Aktuális prefix
	row			: -1,
	name_id		: "id",				// A lekérdezésben az azonosítót meghatározó változó neve
	name_pfx	: "pfx",			// A lekérdezésben az eddig beírt szöveget meghatározó változó neve
	visible		: false,
	blurTimer	: null,
	apfx		: "",
	callback	: false,

	getList	: function(e)
	{
		switch( e.keyCode )
		{
			case 40:
						return false;
			case 38:
			case 13:	return false;

			default:	this.hideSelectNode();

						var pfx = this.field.value
						var l = pfx.replace(/[\s]+/g,'').length;

						if( l>0 )
						{
							if( this.pfx.length && (pfx.toUpperCase().substr(0, this.pfx.length) == this.pfx.toUpperCase()) )
							{
								this.filterLocalList(pfx);
								this.showList();
							}
							else
							{
								var post = {};
								post[this.name_id]	= this.id_query;
								post[this.name_pfx]	= pfx;

								this.apfx = pfx;
		 						Ajax.call("AutoComplete:"+this.id, this.url, {obj:this,method:"ajaxUpdate"}, null, {post:post});
							}
						}
						else
						{
							var node = this.getSelectNode();
							node.style.visibility = "hidden";
							this.hideSelectNode();

							return false;
						}

						return true;
		}
	},

	filterLocalList : function(pfx)
	{
		var upfx = pfx.toUpperCase();
		var pfxl = pfx.length;
		var res = [];
		for(var i=0;i<this.list.length;i++)
		{
			if( this.list[i].toUpperCase().substr(0,pfxl) == upfx )
				res.push(this.list[i]);
		}

		this.pfx = pfx;
		this.list = res;
	},

	blurHandler	: function(e)
	{
		this.blurTimer = setTimeout('AutoComplete.prototype.instances["'+this.id+'"].hideSelectNode()',100);
	},

	ajaxUpdate : function(call)
	{
		if( (call.event == Ajax.EV_COMPLETE) && (Ajax.getHttpStatus(call.id) == 200) )
		{
			try{
				eval("this.list = "+call.http.responseText);
				this.pfx = this.apfx;
			}
			catch(e) {
				this.list = [];
			}
			this.showList();
		}
	},

	showList : function()
	{
		var node = this.getSelectNode();
		node.style.visibility = "hidden";
		this.visible = false;
		if( this.list && this.list.length )
		{
			node.innerHTML = "";
			var alist = [];
			for(var i=0;i<this.list.length;i++)
				alist.push('<a href="javascript:;" onclick="AutoComplete.prototype.instances[\''+this.id+'\'].selectRow('+i+')" >'+this.list[i]+'</a>');

			node.innerHTML = alist.join("");
			node.style.visibility = "visible";
			this.visible = true;
			if( node.offsetHeight > 200 )
				node.style.height="200px";
			else
				node.style.height="auto";

			addIframeUnderlay(node.id);

			this.row = -1;
		}
		else
			this.hideSelectNode();
	},

	setActiveRow: function(active)
	{
		var node = document.getElementById(this.id+"__NODE");
		if( node )
		{
			var i = 0;
			for(anode = node.firstChild;anode;anode=anode.nextSibling)
				anode.className = (i++==active) ? 'active' : '';
		}
	},

	getNX: function(node)
	{
		var x = node.offsetLeft;
		while( node.offsetParent )
		{
			node = node.offsetParent;
			x += node.offsetLeft;
		}
		return x;
	},

	getNY: function(node)
	{
		var y = node.offsetTop;
		while( node.offsetParent )
		{
			node = node.offsetParent;
			y += node.offsetTop;
		}
		return y;
	},

	getSelectNode: function()
	{
		var node = document.getElementById(this.id+"__NODE");
		if( node )
			return node;

		var node = document.createElement('div');
		node.id = this.id+"__NODE";
		node.className = this.cssClass;
		node.style.position = "absolute";
		node.style.left = this.getNX(this.field) + "px";
		node.style.top  = this.getNY(this.field) + this.field.offsetHeight + "px";
//		node.style.width = this.field.offsetWidth + "px";
		node.style.visibility = "hidden";
		node.style.overflow = "auto";
		document.body.appendChild(node);
		eval('node.onfocus = function(){ AutoComplete.prototype.instances["'+this.id+'"].clearTimer()};');
		eval('node.onblur = function(){ AutoComplete.prototype.instances["'+this.id+'"].blurHandler()};');
		return node;
	},

	clearTimer: function()
	{
		if( this.blurTimer )
			clearTimeout(this.blurTimer);

		this.blurTimer = null;
	},

	hideSelectNode: function()
	{
		var node = document.getElementById(this.id+"__NODE");
		if( node )
		{
			delIframeUnderlay(node.id);
			node.parentNode.removeChild(node);
			this.visible = false;
		}
	},


	selectRow: function(index)
	{
		if( this.list && this.list[index] )
		{
			this.field.value = this.list[index];
			this.hideSelectNode();
			if( this.callback )
				this.callback[0][this.callback[1]](this.callback[2]);
		}
	},

	checkAction: function(e)
	{
		var node = document.getElementById(this.id+"__NODE");
		if( node && e && e.keyCode )
		{
			switch( e.keyCode )
			{
				case 40 : if( this.row < this.list.length-1 )
							this.row++;
						  this.setActiveRow(this.row);
						  return false;
						  break;
				case 38 : if( this.row > 0 )
							this.row--;
						  this.setActiveRow(this.row);
						  return false;
						  break;
				case 13	: if( (this.row >= 0) && (this.row < this.list.length) )
							  this.selectRow(this.row);
						  return false;
						  break;

				case 9	:	if( (this.row >= 0) && (this.row < this.list.length) )
							{
								  this.selectRow(this.row);
								  return false;
							}
							if( this.list.length )
							{
								this.row = 0;
								this.setActiveRow(this.row);
								this.selectRow(this.row);
							}
							break;

			}
		}
		return true;
	}

}
