/*******************************************************
					AUTO SUGGEST
*****************************************************/
var AutoSuggest =
{
	callableType: [ 'products' ],
	minChar: 3, timeoutSec: 0.4,

	url: location.protocol + "//" + location.host + "/catalog/autoSuggest.php",
	xhr: null, to: false,

	callers: [], __serial: 0, active: false,
	suggestInfo: {
		val: null,
		type: null
	},


	// *********************
	//		Initial Caller Setup
	__initCaller: function (caller, strict, hintDivId, callbackFunction)
	{
		caller.serial = this.__serial++;

		var hintDiv = $ (caller.hintDiv);
		if (!hintDiv)
			hintDiv = $ (hintDivId);

		if (!callbackFunction)
			callbackFunction = caller.callback;


		this.callers[caller.serial] = ({
			caller: caller,
			strict: strict ? 1 : 0,
			callback: callbackFunction,
			hintDiv: hintDiv,
			focusIndex: 0,
			serial: caller.serial
		});

		caller.__as = this;
		caller.__asP = this.callers[caller.serial];

		if (caller.onfocus)
			caller._onfocus = caller.onfocus;
		caller.onfocus = function (event)
		{
			AutoSuggest.removeFocusFake (this.serial, true);
			if (this._onfocus)
				this._onfocus (event);
		}
	},


	// *********************
	//		Standar Method to Use
	getHint: function (event, caller, type, strict, hintDivId, callbackFunction)
	{
		if (typeof caller.serial == "undefined")
			this.__initCaller (caller, strict, hintDivId, callbackFunction);

		this.active = caller.serial;

		if (caller.value.length + 1 < AutoSuggest.minChar)
		{
			this.closeActive ();
			return true;
		}

		event = getEvent (event);

		if (event.key == 13)
		{
			preventDispatch (event);
			return false;
		}
		else if (event.key == 40)
		{
			preventDispatch (event);
			this.initFocusFake (caller.serial);
			return false;
		}
		else
		{
			this.suggestInfo.val = caller.value; // + getChar (event.key);
			this.suggestInfo.type = type;
			this.suggestInfo.strict = strict ? 1 : 0;
			this.suggestInfo.caller = caller;

			$cT (this.to);
			this.to = $sT ("AutoSuggest.send ();", this.timeoutSec * 1000);
		}
	},
	getActive: function ()
	{
		return this.callers[this.active];
	},
	closeActive: function ()
	{
		var caller = this.getActive ();
		if (caller && caller.hintDiv != undefined)
		{
			caller.hintDiv.className = "searchEngine_hintContainer searchEngine_hintContainer_off";
			AutoSuggest.unregisterCloseEvents ();
		}
	},


	// *********************
	//		Server Side Methods
	send: function ()
	{
		if (this.xhr)
			this.xhr.abort ();

		this.xhr = getXHR ();
		var url = AutoSuggest.url + "?suggestType=" + AutoSuggest.suggestInfo.type + "&suggestValue=" + AutoSuggest.suggestInfo.val + "&strictWindow=" + AutoSuggest.suggestInfo.strict;
		var addConfig = AutoSuggest.suggestInfo.caller.getAttribute ("addConfig");
		url += "&" + addConfig;

		this.xhr.onreadystatechange = AutoSuggest.stateChanged;
		this.xhr.open ("GET", url, true);
		this.xhr.send (null);
	},
	stateChanged: function ()
	{
		if (AutoSuggest.xhr.readyState == 4 || AutoSuggest.xhr.readyState == "complete")
		{
			if (this.responseText != "")
				AutoSuggest.applyHint ();
			this.xhr = false;
		}
	},


	// *********************
	//		Drawing Methods
	applyHint: function ()
	{
		try
		{
			eval ("var result = " + this.xhr.responseText + ";");
			this.result = result;
			AutoSuggest.registerCloseEvents ();
		}
		catch (e)
		{
			debugger;
			// alert ("err: " + this.xhr.responseText);
			return;
		}

		var i, div;

		var as = this.callers[this.active];
		for (i = as.hintDiv.childNodes.length - 1; i >= 0 ; i--)
			as.hintDiv.removeChild (as.hintDiv.childNodes[i]);


		if (result == false)
			as.hintDiv.className = "searchEngine_hintContainer searchEngine_hintContainer_off";
		else
		{
			for (i = 0; i < result.length; i++)
			{
				div = this.createItemDiv (result[i].n);
				div.prodoID = result[i].p;
				as.hintDiv.appendChild (div);
			}

			as.hintDiv.className = "searchEngine_hintContainer";
		}
	},
	createItemDiv: function (code)
	{
		var div = document.createElement ("div");
		div.className = "searchEngine_hintItem searchEngine_hintItem_out";
		div.onmouseover = AutoSuggest.itemOver;
		div.onmouseout = AutoSuggest.itemOut;
		div.onclick = AutoSuggest.itemClick;

		div.innerHTML = code;

		return div;
	},


	// *********************
	//		Call Back Methods
	getValueFromID: function (id)
	{
		for (var asd in this.result)
		{
			if (this.result[asd].p == id)
				return this.result[asd].n;
		}

		return false;
	},
	doCallback: function (id)
	{
		var as = this.callers[this.active];

		this.selectedId = id;

		as.hintDiv.className = "searchEngine_hintContainer searchEngine_hintContainer_off";
		as.caller.value = "";
		as.caller.focus ();

		as.callback (as.caller, id, this.getValueFromID (id));
	},


	// *********************
	//		Event Handlers
	itemOver: function ()
	{
		this.className = "searchEngine_hintItem searchEngine_hintItem_over";
		AutoSuggest.callers[AutoSuggest.active].selectedId = this.prodoID;
	},
	itemOut: function ()
	{
		this.className = "searchEngine_hintItem searchEngine_hintItem_out";
	},
	itemClick: function ()
	{
		this.className = "searchEngine_hintItem searchEngine_hintItem_out";
		/*
		if (typeof this.prodoID != 'undefined')
			location.href = location.protocol + "//" + location.host + "/catalog/product_info.php?products_model=" + this.prodoID;
		*/
		AutoSuggest.doCallback (this.prodoID);
	},
	itemKeydown: function (event)
	{
		event = getEvent (event);
		AutoSuggest.trueItemKeyDown (this, event);
	},
	trueItemKeyDown: function (caller, event)
	{
		var as = this.callers[this.active];

		try {
			as.caller.blur ();
		} catch (e) {}

		var ch = as.hintDiv.childNodes, hd = as.hintDiv;

		switch (event.key)
		{
			case 40:
				preventDispatch (event);

				if (as.focusIndex + 1 < ch.length && as.focusIndex >= 0)
				{
					ch[as.focusIndex].onmouseout ();
					var focused = ch[++as.focusIndex];
					focused.onmouseover ();
					this.checkDownScroll (focused);
				}
				else if (this.focusIndex < 0)
				{
					as.focusIndex = 0;
					ch[0].onmouseover ();
					this.checkUpScroll (ch[0]);
				}
				break;

			case 38:
				preventDispatch (event);

				if (as.focusIndex >= 0)
					ch[as.focusIndex].onmouseout ();

				if (as.focusIndex > 0)
				{
					var focused = ch[--as.focusIndex];
					focused.onmouseover ();
					this.checkUpScroll (focused);
				}
				else
					this.removeFocusFake ();
				break;

			case 13:
				preventDispatch (event);

				AutoSuggest.doCallback (AutoSuggest.callers[AutoSuggest.active].selectedId);
				break;

			default:
				return true;
		}

		return false;
	},
	checkDownScroll: function (focused)
	{
		var h = focused.offsetTop + focused.offsetHeight + 20;
		var as = this.callers[this.active];

		if (as.hintDiv.offsetHeight + as.hintDiv.scrollTop < h)
		{
			var scrollTo = h - as.hintDiv.offsetHeight;
			as.hintDiv.scrollTop = scrollTo;
		}
	},
	checkUpScroll: function (focused)
	{
		var as = this.callers[this.active];
		if (as.hintDiv.scrollTop > focused.offsetTop - 5)
		{
			var scrollTo = Math.max (0, focused.offsetTop - 5);
			as.hintDiv.scrollTop = scrollTo;
		}
	},


	initFocusFake: function ()
	{
		var as = this.callers[this.active];
		as.caller.blur ();
		as.hintDiv.childNodes[0].onmouseover ();

		if (window.attachEvent)
			document.body.attachEvent ("onkeydown", this.itemKeydown);
		else
			window.addEventListener ("keydown", this.itemKeydown, true);

		if (as.focusIndex !== false)
			return;

		as.focusIndex = 0;
	},
	removeFocusFake: function (serial, fromFocus)
	{
		var as = AutoSuggest.callers[AutoSuggest.active];
		if (!fromFocus)
			return as.caller.focus ();

		if (as.hintDiv.childNodes.length > as.focusIndex)
			as.hintDiv.childNodes[as.focusIndex].onmouseout ();
		as.focusIndex = 0;

		if (window.attachEvent)
			document.body.detachEvent ("onkeydown", AutoSuggest.itemKeydown);
		else
			window.removeEventListener ("keydown", AutoSuggest.itemKeydown, true);
	}
}


AutoSuggest.closeClickOut = function (event)
{
	event = getEvent (event);

	var active = AutoSuggest.getActive ();
	var isAutoSuggest = throughtParent (event.elemOver, "property", "id", active.hintDiv.id);
	isAutoSuggest = isAutoSuggest ? true : false;

	if (isAutoSuggest)
	{
		return;
	}
	else
	{
		AutoSuggest.closeActive ();
	}
}
AutoSuggest.eventSet = false;
AutoSuggest.registerCloseEvents = function ()
{
	if (AutoSuggest.eventSet)
		return;

	AutoSuggest.eventSet = true;
	if (document.attachEvent)
	{
		document.body.attachEvent ("onclick", AutoSuggest.closeClickOut);
	}
	else if (document.body.addEventListener)
	{
		document.body.addEventListener ("click", AutoSuggest.closeClickOut, false);
	}
}
AutoSuggest.unregisterCloseEvents = function ()
{
	if (!AutoSuggest.eventSet)
		return;

	AutoSuggest.eventSet = false;
	if (document.detachEvent)
	{
		document.body.detachEvent ("onclick", AutoSuggest.closeClickOut);
	}
	else if (document.body.removeEventListener)
	{
		document.body.removeEventListener ("click", AutoSuggest.closeClickOut, false);
	}
}



