var mouseX, mouseY, linkPos, listPos, ie6bugDivs;
var shownCountryDivs, shownCountryTimeout, mainDivPos, openingTimesDiv;
var autoCompleteEntries, autoCompleteSelected, suggDiv, destBox, suggestionSelected;


function init()
{
	suggDiv = document.getElementById('suggestionBox');
	destBox = document.getElementById('destInput');
	shownCountryDivs = new Array();
	calibrateLayout();
	
	destBox.onkeyup = autoComplete;
	destBox.onkeydown = autoComplete;
	document.onmousemove = getMouseXY;
	window.onresize = calibrateLayout;
}



function calibrateLayout()
{
	var pos = getObjPosition('destInput');
	var pixPat = /^(\d+)px$/;
	var destBoxWidth = Number(destBox.style.width.replace(pixPat, '$1'));
	suggDiv.style.left = pos.x + 'px';
	suggDiv.style.top = (pos.y + pos.h) + 'px';
	suggDiv.style.width = (destBoxWidth + 4) + 'px';
	mainDivPos = getObjPosition('main');
	positionCountryLists();
}



function positionCountryLists()
{
	var countryListDiv = document.getElementById('countryList');
	var countryLinks = countryListDiv.getElementsByTagName('div');
	var el, elId, x, y, ie6bug, linkDiv;
	ie6bugDivs = new Array();
	for (var i=0; i<countryLinks.length; i++)
	{
		el = countryLinks[i];
		if (el.className=='countryCityList')
		{
			elId = el.id;
			linkPos = getObjPosition(elId + '_link');
			ie6bug = ((x && y) && (linkPos.x < x) && (linkPos.y <= y));
			y = (ie6bug) ? linkPos.y + linkPos.h : linkPos.y;
			x = linkPos.x;
			el.style.left = x + 'px';
			el.style.top = (y + linkPos.h) + 'px';
			listPos = getObjPosition(elId);
			if ((listPos.x+listPos.w) > (mainDivPos.x+mainDivPos.w))
			{
				el.style.left = (mainDivPos.x + mainDivPos.w - listPos.w + 4) + 'px';
			}
			if (ie6bug)
			{
				ie6bugDivs.push(elId + '_link');
			}
		}
	}
}



function showCountryCities(elId)
{
	hideCountryCities();
	listPos = getObjPosition(elId);
	linkPos = (ie6bugDivs.length > 0) ? ie6AdjustedPos(elId + '_link') : getObjPosition(elId + '_link');
	var el = document.getElementById(elId);
	el.style.visibility = 'visible';
	shownCountryDivs.push(el);
	shownCountryTimeout = window.setTimeout(checkCountryMousePos, 350);
	suggDiv.style.visibility = 'hidden';
}



function ie6AdjustedPos(linkId)
{
	var pos = getObjPosition(linkId);
	for (var i=0; i<ie6bugDivs.length; i++)
	{
		if (linkId == ie6bugDivs[i])
		{
			pos.y += pos.h;
			break;
		}
	}
	return pos;
}



function checkCountryMousePos()
{
	if ((shownCountryDivs.length > 0 ) && (shownCountryDivs[0].style.visibility=='visible'))
	{
		if ( mouseWithinBounds(linkPos.x, linkPos.y, linkPos.x + linkPos.w, linkPos.y + linkPos.h)
			|| mouseWithinBounds(listPos.x, listPos.y, listPos.x + listPos.w, listPos.y + listPos.h) )
		{
			shownCountryTimeout = window.setTimeout(checkCountryMousePos, 350);
			return true;
		}
	}
	hideCountryCities();
	return false;
}


function mouseWithinBounds(minX, minY, maxX, maxY)
{
	return ( (mouseX > minX) && (mouseY > minY)
				&& (mouseX < maxX) && (mouseY < maxY) );
}



function hideCountryCities()
{
	var numShownDivs = shownCountryDivs.length;
	if (numShownDivs > 0)
	{
		window.clearTimeout(shownCountryTimeout);
		var shownDiv;
		for (var i=0; i<numShownDivs; i++)
		{
			shownDiv = shownCountryDivs.pop();
			shownDiv.style.visibility = 'hidden';
		}
	}
}



function showOpeningTimes(isVisible)
{
	if (isVisible)
	{
		document.onmousemove = moveOpeningTimes;
		openingTimesDiv.style.visibility = 'visible';
	}
	else
	{
		openingTimesDiv.style.visibility = 'hidden';
		document.onmousemove = getMouseXY;
	}
	return true;
}



function moveOpeningTimes(e)
{
	getMouseXY(e);
	var offsetX = mouseX - 320;
	var offsetY = mouseY - 25;
	openingTimesDiv.style.left = offsetX + 'px';
	openingTimesDiv.style.top = offsetY + 'px';
}



/***************************************************

	AUTOCOMPLETE AND RELATED EVENT HANDLING FUNCTIONS

 ***************************************************/


function autoComplete(e)
{
	if (document.all)
	{
		e = window.event;
	}
	var k = e.keyCode;
	
	if (e.type=='keydown')
	{
		switch (k)
		{
			case 38: return navigateAutoComplete('up'); break; // up arrow key
			case 40: return navigateAutoComplete('down'); break; // down arrow key
			case 13: // return key
				if ((autoCompleteEntries.length > 0) && (autoCompleteSelected <= autoCompleteEntries.length))
				{
					destBox.value = autoCompleteEntries[autoCompleteSelected];
					setSelectionRange(destBox, destBox.value.length, destBox.value.length);
					suggDiv.style.visibility = 'hidden';
					autoCompleteEntries = new Array();
				}
			doSiteRedirect();
			default : null;
		}
		return true;
	}
	else if ( (e.type=='keyup') && (((k>=65) && (k<=90)) || (k==32) || (k==8) || (k==46)) )
	{
		// is key a space, backspace, delete or a letter?
		switch (k)
		{
			case 46 :
			case 8 : return handleDeletion(k);
			default : return showSuggestions();
		}
	}
	return false;
}


function doSiteRedirect()
{
	if (websites[destBox.value])
	{
		window.location = websites[destBox.value];
	}
}


function handleDeletion()
{
	suggDiv.style.visibility = 'hidden';
	if (!suggestionSelected || (autoCompleteEntries.length > 1))
	{
		return showSuggestions();
	}
	suggestionSelected = false;
	return false;
}


function navigateAutoComplete(direction)
{
	if ((autoCompleteEntries.length > 0) && (suggDiv.style.visibility == 'visible'))
	{
		var pos = autoCompleteSelected;
		switch (direction)
		{
			case 'up' :
				if ((pos < autoCompleteEntries.length) && (pos > 0))
				{
					autoCompleteSelected--;
				}
				break;
			case 'down' :
				if (pos == autoCompleteEntries.length)
				{
					autoCompleteSelected = 0;
				}
				else if ((pos+1) < autoCompleteEntries.length)
				{
					autoCompleteSelected++;
				}
				break;
			default : return false;
		}
		if (document.getElementById('ac_dd_pos' + pos))
		{
			document.getElementById('ac_dd_pos' + pos).className = 'dd_unselected';
		}
		document.getElementById('ac_dd_pos' + autoCompleteSelected).className = 'dd_selected';
		putInputSuggestion(autoCompleteSelected);
	}
	return false;
}



function putInputSuggestion(i)
{
	var selStart = getSelectionPos(destBox, 'start');
	destBox.value = autoCompleteEntries[i];
	setSelectionRange(destBox, selStart, destBox.value.length);
	suggestionSelected = true;
}



function showSuggestions()
{
	suggestionSelected = false;
	autoCompleteEntries = new Array();
	var strpat = /^\s*(([a-z]+ ?)+)\s*$/i;
	if (strpat.test(destBox.value))
	{
		var testpat = new RegExp('^' + destBox.value.replace(strpat, '$1'), 'i');
		for (var i in cities)
		{
			if (cities[i].match(testpat))
			{
				autoCompleteEntries[autoCompleteEntries.length] = cities[i];
			}
		}
	}
	if (autoCompleteEntries.length > 0)
	{
		if (autoCompleteEntries.length==1)
		{
			putInputSuggestion(0);
			suggDiv.style.visibility = 'hidden';
		}
		else
		{
			var html = '';
			for (i=0; i<autoCompleteEntries.length; i++)
			{
				html += '<div id="ac_dd_pos' + i + '" class="dd_unselected">'
							+ '<a href="' + websites[autoCompleteEntries[i]] + '">'
							+ autoCompleteEntries[i] + '</a></div>';
			}
			suggDiv.innerHTML = html;
			autoCompleteSelected = i;
			suggDiv.style.visibility = 'visible';
		}
	}
	else if (destBox.value.length > 0)
	{
		var html = '<div class="dd_warning">No destinations to show...</div>';
		suggDiv.innerHTML = html;
		suggDiv.style.visibility = 'visible';
	}
	else
	{
		suggDiv.style.visibility = 'hidden';
	}
	return true;
}



function setSelectionRange(inputObj, start, end)
{
	if (document.selection)
	{
		var range = inputObj.createTextRange();
		range.collapse(true);
		range.moveEnd('character', end);
		range.moveStart('character', start - 1);
		range.select();
	}
	else
	{
		inputObj.selectionStart = start;
		inputObj.selectionEnd = end;
	}
}



function getSelectionPos(inputObj, pos)
{
	var isSelStart = (pos == 'start');
	if (document.selection)
	{
		inputObj.focus();
		var range = document.selection.createRange();
		if (range.compareEndPoints('StartToEnd', range) != 0)
		{
			var text = range.text;
			return inputObj.value.indexOf(range.text) + 1;
		}
		return range.getBookmark().charCodeAt(2) - 2;
	}
	return (isSelStart) ? inputObj.selectionStart : inputObj.selectionEnd;
}




/***************************************************

		DOM OBJECT AND CURSOR POSITION OBJECT / METHODS

 ***************************************************/


function Position(o)
{
	this.obj = o;
	this.x=0;
	this.y=0;
	this.getSize = getObjSize;
}

function getObjSize()
{
	this.w = this.obj.offsetWidth;
	this.h = this.obj.offsetHeight;
}

function getObjPosition(objId)
{
	var o=document.getElementById(objId);
	var pos=new Position(o);
	var offsetX = 0;
	var offsetY = 0;
	while (o)
	{
		offsetX += o.offsetLeft;
		offsetY += o.offsetTop;
		o = o.offsetParent;
	}
	pos.x = offsetX;
	pos.y = offsetY;
	pos.getSize();
	return pos;
}



function getMouseXY(e) {
  if (document.all)
	{ // grab the x-y pos.s if browser is IE
    mouseX = window.event.clientX + document.documentElement.scrollLeft;
    mouseY = window.event.clientY + document.documentElement.scrollTop;
  }
	else
	{  // grab the x-y pos.s if browser is not IE
    mouseX = e.pageX;
    mouseY = e.pageY;
  }
  return true;
}


function showAtMousePos(content, divObj)
{
	// optional 3rd and 4th arguments : offsetX, offsetY
	var offsetX = (arguments.length > 2) ? mouseX + arguments[2] : mouseX;
	var offsetY = (arguments.length > 3) ? mouseY + arguments[3] : mouseY;
	divObj.innerHTML = content;
	divObj.style.left = offsetX + 'px';
	divObj.style.top = offsetY + 'px';
	divObj.style.visibility = 'visible';
}

