function _init()
{
	iTimeoutDelay = 100;
	oSuggestTimer = false;
	parseSuggestions();
	_u_suggest = '/classes/module/website/cities.php';
	return;
}
function addText(oAttach, sText)
{
	var oText = document.createTextNode(sText);
	oAttach.appendChild(oText);
	return;
}
function safeRegExp(sText)
{
	return sText.replace(/([\^$(){}|?\\\/*+\[\].])/g, '\\$1');
}
function containsClass(oElement, sClass)
{
	var _regex = new RegExp("(^| )" + safeRegExp(sClass) + "( |$)");
	return ( _regex.test(oElement.className) ) ? true : false;
}
function addClass(oElement, sClass)
{
	var _regex = new RegExp("(^| )" + safeRegExp(sClass) + "( |$)");
	if ( oElement.className.length > 0 )
	{
		if ( !(_regex.test(oElement.className)) )
		{
			oElement.className += ' ' + sClass;
		}
	}
	else
	{
		oElement.className = sClass;
	}
	return;
}
function removeClass(oElement, sClass)
{
	var _regex = new RegExp("(^| )" + safeRegExp(sClass) + "( |$)", "g");
	oElement.className = oElement.className.replace(_regex, '');
	return;
}
function insertAfter(oNew, oTarget)
{
	var oParent = oTarget.parentNode;
	if ( oParent.lastChild == oTarget )
	{
		oParent.appendChild(oNew);
	}
	else
	{
		oParent.insertBefore(oNew, oTarget.nextSibling);
	}
	return;
}
function clearNode(oNode)
{
	while (oNode.childNodes[0])
	{
		oNode.removeChild(oNode.childNodes[0]);
	}
	return;
}
function keyStroke(evt)
{
	var charCode = (evt.charCode || evt.keyCode || evt.which || 0);
	
	switch ( charCode )
	{
		case 3:
		case 13:
			return 13;	//	enter
		
		case 9:
		case 25:
			return 9;	//	tab
		
		case 33:
		case 63276:
			return 33;	//	page up
		
		case 34:
		case 63277:
			return 34;	//	page down
		
		case 35:
		case 63275:
			return 35;	//	end
		
		case 36:
		case 63273:
			return 36;	//	home
		
		case 28:
		case 37:
		case 63234:
			return 37;	//	left arrow
		
		case 30:
		case 38:
		case 63232:
			return 38;	//	up arrow
		
		case 29:
		case 39:
		case 63235:
			return 39;	//	right arrow
		
		case 31:
		case 40:
		case 63233:
			return 40;	//	down arrow
		
		case 45:
		case 63302:
			return 45;	//	insert
		
		case 46:
		case 63272:
			return 46;	//	delete
		
		case 144:
		case 63289:
			return 144;	//	num lock
		
		default:
			break;
	}
	
	return charCode;
}
function normalCharCode(charCode)
{
	switch ( charCode )
	{
		case 8:
		case 9:
		case 16:
		case 33:
		case 34:
		case 35:
		case 36:
		case 37:
		case 38:
		case 39:
		case 40:
		case 45:
		case 46:
		case 144:
			return false;
		
		default:
			break;
	}
	return true;
}
function cancelEvent(evt)
{
	if ( evt.preventDefault || evt.stopPropagation )
	{
		if ( evt.preventDefault )
		{
			evt.preventDefault();
		}
		if ( evt.stopPropagation )
		{
			evt.stopPropagation();
		}
	}
	else
	{
		evt.keyCode = 0;
		evt.returnValue = false;
	}
	return;
}
function placeCursorAtEnd(sName, sDelay)
{
	if ( sDelay != true )
	{
		window.setTimeout("placeCursorAtEnd('" + sName + "', true);", 1);
	}
	else
	{
		var oText = $(sName);
		if (oText.setSelectionRange)
		{
			oText.setSelectionRange(oText.value.length, oText.value.length);
		}
		else if (oText.createTextRange)
		{
			var range = oText.createTextRange();
			range.collapse(true);
			range.moveEnd('character', oText.value.length);
			range.moveStart('character', oText.value.length);
			range.select();
		}
	}
	return;
}
function suggestKeyDown(evt)
{
	evt = ( evt || window.event );
	evt.key = keyStroke(evt);
	evt.targetNode = ( evt.srcElement || evt.target );
	var sName = evt.targetNode.name;
	
	//	clear pending requests
	window.clearTimeout(oSuggestTimer);
	
	switch ( evt.key )
	{
		case 9:		//	tab
			if ( $('s_' + sName) )
			{
				if ( !(evt.shiftKey) )
				{
					selectSuggestion(sName);
				}
				clearSuggestions(sName);
			}
			break;
		
		case 38:	//	up
		case 40:	//	down
			var oCells = $('s_' + sName).getElementsByTagName('td');
			for (var i = 0, sIndex = false; i < oCells.length; i++)
			{
				if ( oCells[i].className == 'selected' )
				{
					sIndex = i;
					break;
				}
			}
			if ( sIndex === false )
			{
				sIndex = ( evt.key == 38 ) ? 0 : -1;
			}
			sIndex = ((( evt.key == 38 ) ? --sIndex : ++sIndex) + oCells.length) % oCells.length;
			for (var i = 0; i < oCells.length; i++)
			{
				oCells[i].className = ( i == sIndex ) ? 'selected' : '';
			}
			break;
	}
	return;
}
function suggestKeyPress(evt)
{
	evt = ( evt || window.event );
	evt.key = keyStroke(evt);
	evt.targetNode = ( evt.srcElement || evt.target );
	var sName = evt.targetNode.name;
	
	if ( evt.key == 13 )	//	enter
	{
		if ( $('s_' + sName) )
		{
			selectSuggestion(sName);
			cancelEvent(evt);
			clearSuggestions(sName);
		}
	}
	return;
}
function suggestKeyUp(evt)
{
	evt = ( evt || window.event );
	evt.key = keyStroke(evt);
	evt.targetNode = ( evt.srcElement || evt.target );
	var sName = evt.targetNode.name;
	
	//	clear pending requests
	window.clearTimeout(oSuggestTimer);
	
	switch ( evt.key )
	{
		case 13:	//	enter
			placeCursorAtEnd(sName);
			break;
		
		case 38:	//	up
		case 40:	//	down
			placeCursorAtEnd(sName);
			break;
		
		case 8:		//	backspace
		case 46:	//	delete
			if ( evt.targetNode.value.length == 0 )
			{
				clearSuggestions(sName);
			}
			else
			{
				delayRequest(sName);
			}
			break;
		
		default:
			if ( normalCharCode(evt.key) == true )
			{
				delayRequest(sName);
			}
			break;
	}
	return;
}
function suggestBlur(evt)
{
	evt = ( evt || window.event );
	evt.targetNode = ( evt.srcElement || evt.target );
	var sName = evt.targetNode.name;
	
	window.clearTimeout(oSuggestTimer);
	oSuggestTimer = window.setTimeout("clearSuggestions('" + sName + "');", iTimeoutDelay);
}
function delayRequest(sName)
{
	oSuggestTimer = window.setTimeout("suggestRequest('" + sName + "');", iTimeoutDelay);
	return;
}
function suggestRequest(sName)
{
	var sParams, oText = $(sName);
	if ( oText )
	{
		sParams  = 'name=' + encodeURIComponent(sName);
		sParams += '&value=' + encodeURIComponent(oText.value);
		var sForm = oText.form.getAttribute('id');
		if ( sForm )
		{
			sParams += '&form=' + encodeURIComponent(sForm);
		}
		
		ajax(_u_suggest, 'get', 'receiveSuggestions', sParams);
	}
	return;
}
function getPosition(oNode, bBelow)
{
	var sHorz = 0;
	var sVert = ( bBelow ) ? oNode.offsetHeight : 0;
	if ( oNode.offsetParent )
	{
		while ( oNode.offsetParent )
		{
			sHorz += oNode.offsetLeft;
			sVert += oNode.offsetTop;
			oNode  = oNode.offsetParent;
		}
		sHorz += oNode.offsetLeft;
		sVert += oNode.offsetTop;
	}
	else if ( oNode.x && oNode.y )
	{
		sHorz += oNode.x;
		sVert += oNode.y;
	}

	return [sHorz.toString() + 'px', sVert.toString() + 'px'];
}
function createSuggestionBox(sData, sName)
{
	clearSuggestions();
	var oContainer = document.createElement('table');
	var oSuggestions = document.createElement('tbody');
	oContainer.appendChild(oSuggestions);
	oContainer.className = 'suggestions';
	oContainer.id = 's_' + sName;
	for (var i = 0; i < sData[1].length; i++)
	{
		addSuggestion(oSuggestions, sData[0], sData[1][i], (( i ) ? false : true), sName);
	}
	appendSuggestionBox(oContainer, sName);
	hideSelects(true);
}
function addSuggestion(oSuggestions, sOriginal, sDatum, sSelected, sName)
{
	var oRow = document.createElement('tr');
	var oCell = document.createElement('td');
	
	var sSplit = splitText(sOriginal, sDatum, false);
	if ( sSplit[0].length )
	{
		addText(oCell, sSplit[0]);
	}
	if ( sSplit[1].length )
	{
		var oBold = document.createElement('span');
		oBold.className = 'bold';
		oCell.appendChild(oBold);
		addText(oBold, sSplit[1]);
	}
	if ( sSplit[2].length )
	{
		addText(oCell, sSplit[2]);
	}
	oRow.appendChild(oCell);
	oSuggestions.appendChild(oRow);
	oCell.onmousedown = function() { selectSuggestion(sName, true); };
	oCell.onmouseover = function() { deselectRows(sName); this.className = 'selected'; };
	oCell.onmouseout = function() { this.className = ''; };
	if ( sSelected )
	{
		oCell.className = 'selected';
	}
	return;
}

function splitText(sOriginal, sDatum, sLoose)
{
	var sRegex = (( sLoose == true ) ? '^(.*?)' : '(^|.+?\\s)') + '(' + safeRegExp(sOriginal) + ')(.*?)$';
	var sPattern = new RegExp(sRegex, 'i');
	if ( sPattern.test(sDatum) )
	{
		var sSplit = sPattern.exec(sDatum);
		return [sSplit[1], sSplit[2], sSplit[3]];
	}
	return [sDatum, '', ''];
}
function deselectRows(sName)
{
	var oCells = $('s_' + sName).getElementsByTagName('td');
	for (var i = 0; i < oCells.length; i++)
	{
		oCells[i].className = '';
	}
	return;
}
function appendSuggestionBox(oContainer, sName)
{
	var oInput = $(sName);
	var sPosition = getPosition(oInput, true);
	oContainer.style.left = sPosition[0];
	oContainer.style.top = sPosition[1];
	oContainer.setAttribute('width', oInput.offsetWidth);
	oContainer.style.position = 'absolute';
	oContainer.setAttribute('cellPadding', 0);
	oContainer.setAttribute('cellSpacing', 0);
	var sTagName = oInput.parentNode.tagName.toLowerCase();
	var oNode = ( /^(body|form|td|th)$/i.test(sTagName) ) ? oInput : oInput.parentNode;
	insertAfter(oContainer, oNode);
	return;
}
function selectSuggestion(sName, bClose)
{
	var oCells = $('s_' + sName).getElementsByTagName('td');
	for (var i = 0; i < oCells.length; i++)
	{
		if ( oCells[i].className == 'selected' )
		{
			$(sName).value = getSuggestionText(oCells[i]);
			break;
		}
	}
	if ( bClose == true )
	{
		clearSuggestions(sName);
	}
	return;
}
function getSuggestionText(oCell)
{
	var sText = '';
	var oTexts = oCell.childNodes;
	for (var i = 0; i < oTexts.length; i++)
	{
		var oText = oTexts[i];
		while ( oText.nodeType != 3 )
		{
			oText = oText.firstChild;
		}
		sText += oText.nodeValue;
	}
	return sText;
}
function clearSuggestions(sName)
{
	if ( sName == null )
	{
		var oContainers = getElementsByClass('suggestions');
		var i = oContainers.length;
		while ( (i--) > 0 )
		{
			var oParent = oContainers[i].parentNode;
			oParent.removeChild(oContainers[i]);
		}
	}
	else
	{
		var oContainer = $('s_' + sName);
		if ( oContainer )
		{
			var oParent = oContainer.parentNode;
			oParent.removeChild(oContainer);
		}
	}

	hideSelects(false);

	return;
}
function receiveSuggestions(sResponse)
{
	eval("var jResponse = " + sResponse + ";");
	var sName = jResponse[jResponse.length-1].name;
	var sForm = jResponse[jResponse.length-1].form;
	var oText = $(sName);
	var oForm = null;
	if ( sForm )
	{
		oForm = document.forms[sForm];
	}
	if ( oText )
	{
		if ( oForm )
		{
			if ( oText.form != oForm )
			{
				return false;
			}
		}
		if ( jResponse[1].length )
		{
			createSuggestionBox([jResponse[0], jResponse[1]], sName);
		}
		else
		{
			clearSuggestions(sName);
		}
	}
	return;
}
function parseSuggestions()
{
	var oSuggests = getElementsByClass('suggest', document, 'input');
	for (var i = 0; i < oSuggests.length; i++)
	{
		xAddEventListener(oSuggests[i], 'keydown', suggestKeyDown);
		xAddEventListener(oSuggests[i], 'keypress', suggestKeyPress);
		xAddEventListener(oSuggests[i], 'keyup', suggestKeyUp);
		xAddEventListener(oSuggests[i], 'blur', suggestBlur);
		oSuggests[i].setAttribute('autocomplete', 'off');
	}
	
	return;
}
function hideSelects(bHide)
{
	if ( /msie [56]/i.test(navigator.userAgent) )
	{
		var oSelects = document.getElementsByTagName('select');
		for (var i = 0; i < oSelects.length; i++)
		{
			if ( bHide == true )
			{
				//	create table
				var oHideTable = document.createElement('table');
				var oHideTbody = document.createElement('tbody');
				var oHideTrow  = document.createElement('tr');
				var oHideTcell = document.createElement('td');
				//	set sizing
				oHideTable.style.margin = oSelects[i].style.margin;
				oHideTable.style.padding = oSelects[i].style.padding;
				oHideTable.style.height = oSelects[i].offsetHeight + 'px';
				oHideTable.style.width  = oSelects[i].offsetWidth + 'px';
				oHideTable.style.borderCollapse = 'collapse';
				oHideTable.style.verticalAlign = 'middle';
				oHideTable.style.display = 'inline';
				//	add table
				oHideTrow.appendChild(oHideTcell);
				oHideTbody.appendChild(oHideTrow);
				oHideTable.appendChild(oHideTbody);
				//	hide and add
				oSelects[i].style.display = 'none';
				insertAfter(oHideTable, oSelects[i]);
				oHideTable.className = 'delete_me';
			}
			else if ( getElementsByClass('suggestions', document, 'table').length == 0 )
			{
				//	remove table
				if ( oSelects[i].nextSibling )
				{
					if ( oSelects[i].nextSibling.className == 'delete_me' )
					{
						oSelects[i].parentNode.removeChild(oSelects[i].nextSibling);
					}
				}
				//	show select box
				oSelects[i].style.display = 'inline';
			}
		}
	}
	return;
}
function isAncestor(oNode, oParent)
{
	var oParentCheck = oNode.parentNode;
	
	while ( !(/^(body|html)$/i.test(oParentCheck.tagName)) )
	{
		if ( oParent == oParentCheck )
		{
			return (true);
		}
		oParentCheck = oParentCheck.parentNode;
	}
	return ( oParent == document.body ) ? true : false;
}
/*----------------------------------------*/
function xAddEventListener(oElement, sType, fListener)
{
	if ( oElement.addEventListener )
	{
		oElement.addEventListener(sType, fListener, false);
	}
	else if ( oElement.attachEvent )
	{
		oElement.attachEvent('on' + sType, fListener);
	}
	else if ( typeof oElement['on' + sType] == 'function' )
	{
		var fOld = oElement['on' + sType];
		oElement['on' + sType] = function()
		{
			fOld();
			fListener();
		}
	}
	else
	{
		oElement['on' + sType] = fListener;
	}
	return;
}
function $()
{
	var oElements = new Array();
	for (var i = 0; i < arguments.length; i++)
	{
		var oNode = arguments[i];
		if (typeof oNode == 'string')
		{
			oNode = document.getElementById(oNode);
		}
		if (arguments.length == 1)
		{
			return oNode;
		}
		oElements.push(oNode);
	}
	return oElements;
}
function getElementsByClass(sClass, oNode, sTag)
{
	var oFinal = new Array();
	if ( oNode == null )
	{
		oNode = document;
	}
	if ( sTag == null )
	{
		sTag = '*';
	}
	var oPotential = oNode.getElementsByTagName(sTag);
	var sPattern = new RegExp('(^|\\s)' + sClass + '(\\s|$)');
	for (var i = 0, j = 0; i < oPotential.length; i++)
	{
		if ( sPattern.test(oPotential[i].className) )
		{
			oFinal[j] = oPotential[i];
			j++;
		}
	}
	return oFinal;
}
function createRequestObject()
{
	var ro;
	if ( window.XMLHttpRequest )
	{
		try
		{
			ro = new XMLHttpRequest();
		}
		catch(e)
		{
			ro = null;
		}
	}
	else if ( window.ActiveXObject )
	{
		try
		{
			ro = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch(e)
		{
			try
			{
				ro = new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch(e)
			{
				ro = null;
			}
		}
	}
	return ro;
}
function ajax(sAction, sMethod, sHandler, sParams, bAbort)
{
	bAbort = ( bAbort != true ) ? false : true;
	sParams = ( sParams == null ) ? '' : sParams;
	var sData = ( sMethod == 'get' ) ? '' : sParams;

	var sURI = sAction;
	if ( sMethod == 'get' )
	{
		sURI += ( /\?/.test(sAction) ) ? '&' + sParams : '?' + sParams;
	}
	
	if ( bAbort )
	{
		if ( http )
		{
			if ( http.readyState != 0 )
			{
				http.abort();
			}
		}
	}
	var http = createRequestObject();
	
	if ( http )
	{
		http.onreadystatechange = function()
		{
			if ( http.readyState == 4 )
			{
				try
				{
					var iStatus = http.status;
				}
				catch (e)
				{
					var iStatus = 0;
				}
				if ( iStatus == 200 )
				{
					var sResponse = http.responseText.replace(/(\\|')/g, '\\$1');
					eval(sHandler + "('" + sResponse.replace(/[\n\r]/g, '\\n') + "');");
				}
				else if ( iStatus != 0 )
				{
					ajaxFail();
				}
			}
		};
		
		http.open(sMethod, sURI);
		http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
		http.setRequestHeader('Content-length', sData.length);
		http.setRequestHeader('Connection', 'close');
		http.send(sData);
	}
	
	return;
}
function ajaxFail()
{
	return;
}
/*----------------------------------------*/
xAddEventListener(window, 'load', _init);