function getElement(id)
{
	return document.getElementById ? document.getElementById(id) : document.all ? document.all[id] : document.layers[id];
} 

var debug = false;

function setTagValue(result, id)
{
	getElement(id).value = result;
}

function evalResponse(result)
{
	try
	{
		eval(result);
	}
	catch (ex)
	{
		throw new Error('evalResponse()\n' + ex.message + '\n' + result);
	}
}

function onAjaxError_INTERNAL(status)
{
	/*
	getElement('ajaxErrorDiv').style.display = 'block';
	
	alert('ajax hiba: ' + status);
	//Safary does bot like this for some reason :-(
	
	if (typeof(onAjaxError) === 'function')
	{
		onAjaxError();
	}
	*/
}

function getXmlHttp()
{
	var xmlhttp = false;
	if (window.XMLHttpRequest)
	{
		xmlhttp = new window.XMLHttpRequest();
	}
	else if (window.ActiveXObject) // code for IE
	{
		try
		{
			xmlhttp = new window.ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e)
		{
			try
			{
				xmlhttp = new window.ActiveXObject("Microsoft.XMLHTTP");
			}
			catch (E)
			{
				xmlhttp = false;
			}
		}
	}
	
	return xmlhttp;
}

function passAjaxResponseToFunction(url, callbackFunction, params)
{
	try {
		var xmlhttp = getXmlHttp();
		if (xmlhttp) {
			xmlhttp.onreadystatechange = function orsc1() {
				var response = '';
				var functionToCall = '';
				try {
					if (xmlhttp && xmlhttp.readyState === 4)
					{
						if (xmlhttp.status === 200)
						{
							response = xmlhttp.responseText;
							functionToCall = callbackFunction + '(response' + (params ? ',' + params : '') + ')';
							//eval('if (typeof ' + callbackFunction + ' === "function") {' + functionToCall + '}');
							eval(functionToCall);
						}
						else
						{
							onAjaxError_INTERNAL(xmlhttp.status);
						}
					}
				} catch (ex) {
					throw new Error('orsc1\neval: ' + callbackFunction + '("' + response + '", ' + params + ')\n' + ex.message);
				}
			};

			xmlhttp.open('GET', url + (url.indexOf('?') === -1 ? '?' : '&') + 'rnd=' + Math.random(), true);
			xmlhttp.send(null);
		}
	} catch (ex) {
		throw new Error('passAjaxResponseToFunction("' + url + '", "' + callbackFunction + '", "' + params + '")\n' + ex.message);
	}
}

function ajaxPost(url, postdata, callbackFunction, params, async)
{
	try {
		if (async !== false)
		{
			async = true;
		}
		var xmlhttp = getXmlHttp();
		if (xmlhttp)
		{
			xmlhttp.onreadystatechange = function orsc2() {
				var response = '';
				try {
					if (xmlhttp && xmlhttp.readyState === 4)
					{
						if (xmlhttp.status === 200)
						{
							response = xmlhttp.responseText;
							var functionToCall = callbackFunction + '(response' + (params ? ',' + params : '') + ')';
							//eval('if (typeof ' + callbackFunction + ' === "function")\n{\n' + functionToCall + '\n}');
							eval(functionToCall);
						}
						else
						{
							onAjaxError_INTERNAL(xmlhttp.status);
						}
					}
				} catch (ex) {
					throw new Error('orsc2\neval: ' + callbackFunction + '("' + response + '", ' + params + ')\n' + ex.message);
				}
			};
		
			xmlhttp.open('POST', url + (url.indexOf('?') === -1 ? '?' : '&') + 'rnd=' + Math.random(), async);

			xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			xmlhttp.setRequestHeader("Content-length", postdata.length);
			xmlhttp.setRequestHeader("Connection", "close");

			xmlhttp.send(postdata);
		}
	} catch (ex) {
		throw new Error('ajaxPost("' + url + '", "' + postdata + '", "' + callbackFunction + '", "' + params + '")\n' + ex.message);
	}
} 







var acFields = [];
var acCloseEnabled = true; // close list on document.onclick
var acDocTimerID = null;
var acPopupID = 0;

/*extern getElement, getXmlHttp, stopEvent */

/**
 * hide all open autocomplete lists
 */
function onCloseAutoCompletes() {
	try {
		for (var i = 0; i < acFields.length; i += 1) {
			acFields[i].hideList();
		}
	} catch (ex) {
		throw new Error('onCloseAutoCompletes()\n' + ex.message);
	}
}

/**
 * autocomplete constructor function
 * @param  p_elementID      input field DOM id
 * @param  p_urlBase        response generator url
 * @param  p_width          popup width
 * @param  p_firstColWidth  width of 1st column in pixels (but only the number, without the px quantifier)
 * @param  p_maxItemCount   maximal number of items showed at a time
 * @param  p_userfunction   if a function is passed here, it will be run when an item is selected
 * @param  p_aconly         if true, then only allow to select from the drop down list (user entered text is not accepted)
 * @param  p_searchTermType search term type id
 * @param  p_hitCountLimit  hit count limit
 */
function AutoComplete(p_elementID, p_urlBase, p_width, p_firstColWidth, p_maxItemCount, p_userfunction, p_aconly, p_searchTermType, p_hitCountLimit) {
	var element = getElement(p_elementID),
		urlBase = p_urlBase,
		maxItemCount = p_maxItemCount,
		firstColWidth = (p_firstColWidth ? p_firstColWidth : element.offsetWidth - 10),
		userfunction = p_userfunction,
		aconly = p_aconly,
		searchTermType = p_searchTermType,
		hitCountLimit = p_hitCountLimit,
	
		popup = null,
		upButton = null,
		downButton = null,
		listItems = [],
	
		data  = [],
		descr = [],
		col3  = [],
		timerID = null,
		selectedIndex = -1,
		offset = 0,
		lastReqID = -1;
	
	function hideList() {
		try {
			if (popup) {
				popup.style.visibility = 'hidden';
				popup.style.display = 'none';
			}
		} catch (ex) {
			throw new Error('AutoComplete/hideList()\n' + ex.message);
		}
	}

	function showList() {
		try {
			var x = element.offsetLeft,
				y = element.offsetTop + element.offsetHeight,
				parent = element,
				item = null,
				index = 0,
				i = 0;

			while (parent.offsetParent) {
				parent = parent.offsetParent;
				x += parent.offsetLeft;
				y += parent.offsetTop;
			}
			popup.style.left = x + 'px';
			popup.style.top = y + 'px';
			for (i = 1; i < maxItemCount; i += 1) {
				item = listItems[i];
				index = offset + i;
			
				if (data[index]) {
					item.innerHTML = '<span style="width:' + firstColWidth + 'px;">' + data[index] + '</span>' + descr[index];
					item.style.display = 'block';
					item.className = (index == selectedIndex ? 'ACItemSelected' : 'ACItem');
				} else {
					item.style.display = 'none';
				}
			}
			upButton.className = (offset > 0 ? 'ACUpButton' : 'ACUpButtonDisabled');
			downButton.className = (offset < data.length - maxItemCount ? 'ACDownButton' : 'ACDownButtonDisabled');
			popup.style.visibility = 'visible';
			popup.style.display = 'block';
		} catch (ex) {
			throw new Error('AutoComplete/showList()\n' + ex.message);
		}
	}

	function onButtonUp() {
		if (offset > 0) {
			offset -= 1;
		}
		selectedIndex = -1;
		
		showList();
		element.focus();
		
		if (acDocTimerID) {
			clearTimeout(acDocTimerID);
		}
		acDocTimerID = setTimeout('acCloseEnabled = true;', 100);
		acCloseEnabled = false;
	}
	
	function onButtonDown() {
		if (offset < data.length - maxItemCount) {
			offset += 1;
		}
		selectedIndex = -1;
		
		showList();
		element.focus();
		
		if (acDocTimerID) {
			clearTimeout(acDocTimerID);
		}
		acDocTimerID = setTimeout('acCloseEnabled = true;', 100);
		acCloseEnabled = false;
	}
	
	function onItemOn() {
		if (data[selectedIndex]) {
			listItems[selectedIndex - offset].className = 'ACItem';
		}
		this.className = 'ACItemSelected';
		selectedIndex = this.getAttribute('index');
	}
	
	function onItemOff() {
		this.className = 'ACItem';
		selectedIndex = -1;
	}
	
	function selectItem(index) {
		if (index !== undefined) {
			selectedIndex = index;
		}
		element.value = (data[selectedIndex] ? data[selectedIndex] : element.value);
		hideList();
		if (typeof userfunction === 'function') {
			var p_value = element.value,
				p_descr = (descr[selectedIndex] ? descr[selectedIndex] : ''),
				p_col3  = (col3[selectedIndex] ? col3[selectedIndex] : '');

			userfunction(p_value, p_descr, p_col3);
		}
	}

	function onItemClick() {
		selectItem(offset + parseInt(this.getAttribute('index'), 10));
	}

	function updateData(params) {
		lastReqID += 1;
		var reqID = lastReqID,
			xmlhttp = getXmlHttp(),
			param_num = params.length,
			url = '',
			i = 0;

		if (!xmlhttp) {
			throw new Error('AutoComplete/updateData()\ncould not create xmlHTTP object');
		}
		xmlhttp.onreadystatechange = function ()
			{
				var i = 0,
					parts = null;

				if (xmlhttp && xmlhttp.readyState - 0 === 4) {
					if (reqID !== lastReqID) {
						return;
					}
					data = [];
					if (xmlhttp.status - 0 === 200) {
						if (xmlhttp.responseText.length > 0) {
							data = xmlhttp.responseText.split("\r\n");
						}
						
						var success = false;
						if (data.length > 0)
							success = data[0] == 'OK.';
						
						if (success)
						{
							for (i = 1; i < data.length; i += 1) {
								parts = data[i].split('|');
								data[i]  = parts[0];
								descr[i] = (parts.length > 1 ? parts[1] : '');
								col3[i]  = (parts.length > 2 ? parts[2] : '');
							}
						}
					} else {
						throw new Error('AutoComplete/updateData()\n(not 200) http status on AJAX finish: ' + xmlhttp.status);
					}
					if (data.length > 1) {
						showList();
					} else {
						hideList();
					}
				}
			};
		
		url = urlBase + (urlBase.indexOf('?') === -1 ? '?' : '&');
		url += params[0][0] + '=' + params[0][1];
		for (i = 1; i < param_num; i += 1) {
			url += '&' + params[i][0] + '=' + params[i][1];
		}
		//alert(url);
		xmlhttp.open('GET', url + '&rnd=' + Math.random(), true);
		xmlhttp.send(null);
	}

	function createUrlParams() {
		try {
			var arr = [];
			
			if (document.forms[0].azonosito != null)
			{
				arr[arr.length] = ['m', 3];
				arr[arr.length] = ['l', document.forms[0].azonosito.value];
			}
			else
			{
				var selectedGroup = getElement('F10').value;
				var selectedLibrary = getElement('F3').value;
				
				if (selectedLibrary != 0)
				{
					if (selectedLibrary.charAt(0) == '[')
						selectedLibrary = selectedLibrary.substr(1, selectedLibrary.length - 2);
					while (selectedLibrary.charAt(0) == '0')
						selectedLibrary = selectedLibrary.substr(1, selectedLibrary.length - 1);
					
					arr[arr.length] = ['m', 3];
					arr[arr.length] = ['l', selectedLibrary];
				}
				else
				{
					if (selectedGroup == 0)
						arr[arr.length] = ['m', 1];
					else
					{
						if (selectedGroup.charAt(0) == '[')
							selectedGroup = selectedGroup.substr(1, selectedGroup.length - 2);
						
						arr[arr.length] = ['m', 2];
						arr[arr.length] = ['g', selectedGroup];
					}
				}
			}
			
			arr[arr.length] = ['t', searchTermType];
			arr[arr.length] = ['c', hitCountLimit];
			
			var searchTerm = element.value;
			searchTerm = searchTerm.toUpperCase();
			searchTerm = encodeURIComponent(searchTerm);
			
			arr[arr.length] = ['s', searchTerm];

			return arr;
		} catch (ex) {
			throw new Error('AutoCmplete/createUrlParams()\n' + ex.message);
		}
	}
	
	function onTick() {
		try {
			selectedIndex = -1;
			offset = 0;
		
			if (element.value) {
				updateData(createUrlParams());
			} else {
				hideList();
			}
		} catch (ex) {
			throw new Error('AutoCmplete/onTick()\n' + ex.message);
		}
	}

	function scheduleDataUpdate() {
		if (timerID) {
			clearTimeout(timerID);
		}
		timerID = setTimeout(onTick, 500);
	}

	function onKeyDown(evnt) {
		var e = evnt || window.event,
			keyCode = e.keyCode || e.which;

		switch (keyCode) {
		case 9: // Tab.
			hideList();
			break;

		case 13: // Enter.
			if (-1 != selectedIndex || !aconly) {
				selectItem();
			}
			stopEvent(e);
			break;

		case 40: // Arrow down.
			if (data.length > 0) {
				selectedIndex += 1;
				
				if (selectedIndex < offset) {
					selectedIndex = offset;
				}
				if (selectedIndex >= data.length) {
					selectedIndex = data.length - 1;
				}
				if (selectedIndex >= offset + maxItemCount && offset < data.length - maxItemCount) {
					offset += 1;
				}
				showList();
			}
			break;
		
		case 38: // Arrow up.
			if (data.length > 0) {
				selectedIndex -= 1;
				if (selectedIndex <= -1 && offset <= 0) {
					selectedIndex = -1;
					hideList();
				} else {
					if (selectedIndex <= -1) {
						selectedIndex = offset + maxItemCount - 1;
					}
					if (selectedIndex < offset) {
						offset -= 1;
					}
					
					showList();
				}
			}
			break;
		
		default:
			scheduleDataUpdate();
			break;
		}
	}
	
	function onKeyPress(evnt) {
		var e = evnt || window.event,
			keyCode = e.keyCode || e.which;

		if (keyCode === 13) {
			// Enter.
			// Opera can only prevent default on keypress (not on keydown)
			stopEvent(e);
		}
	}

	function setupElement() {
		try {
			var item = null,
				i = 0;

			popup = document.createElement('div');
			hideList();
		
			popup.id = 'ACPopup' + acPopupID;
			acPopupID += 1;
		
			popup.className = 'ACPopup';
			popup.style.width = (p_width ? p_width : element.offsetWidth) + 'px';
			popup.style.zIndex = 100000;
			document.body.appendChild(popup);
		
			upButton = document.createElement('div');        
			upButton.className = 'ACUpButton';
			upButton.onclick = onButtonUp;
			popup.appendChild(upButton);      
		
			for (i = 0; i < maxItemCount; i += 1) {
				item = document.createElement('div');
				listItems[i] = item;
			
				item.className = 'ACItem';            
				item.setAttribute('index', i);
			
				item.onclick = onItemClick;
				item.onmouseover = onItemOn;
				item.onmouseout = onItemOff;
			
				popup.appendChild(item);
			}
		
			downButton = document.createElement('div');        
			downButton.className = 'ACDownButton';
			downButton.onclick = onButtonDown;
			popup.appendChild(downButton);      

			element.onkeydown = function (e) {
				onKeyDown(e);
			};
			element.onkeypress = function (e) {
				onKeyPress(e);
			};
		} catch (ex) {
			throw new Error('AutoComplete/setupElement()\n' + ex.message);
		}
	}

	this.showList = showList;
	this.hideList = hideList;
	this.selectItem = selectItem;
	setupElement();
} // end of AutoComplete constructor function


function setupSzirenAutoComplete(elementID, p_searchTermType, urlBase)
{
	var ac = new AutoComplete(elementID, urlBase, null, null, 10, null, false, p_searchTermType, 10);
	
	acFields[acFields.length] = ac;
	document.onclick = function () {
		if (acCloseEnabled) {
			onCloseAutoCompletes();
		}
	};
}

