var currentElement;			// currently selected input element
var selectedIndex = -1;		// selected item in menu
var airports;				// list of airport nodes
var resultQuery;			// query used for airports above
var showMenu = false;		// is menu visible?
var DELAY = 2000; //2000		// 2 second delay for ajax call
var requestReady = true; 	// mark http request as available
var delayedQuery = false;
var browserName=navigator.appName; 

/*

	print("Size of DITAG: \n", sizeofDITAG);
    print("Number of Sequences : \n", numOfSequences);
    //memorySize = (sizeofDITAG * numOfSequences);
    memorySize = 2147483648; //maximum amount of memory required
    print("Total Memory : \n", memorySize);
    print("Total Memory : \n", memorySize);  
    ditag = malloc(memorySize);  //allocates memory from request

*/

// function to call ajax object and retrieve xml feed from the link
function showHint(e, val){
	if( filterKeys(e) == true )
		return;
	clearTable();
	var query = val.value;
	currentElement = val;
	if ( query == null || query.length < 3){
		return;
	} 
	query = query.toUpperCase();
	if(resultQuery && resultQuery.length > 0){
		if(query.match(resultQuery)){
			filterXML(query);
			parseMessages();
			return;
		}
		resultQuery = null;
	}
	// do not make request if not available
	if(!requestReady){
		delayedQuery = true;
		return;
	}
	
	req = GetXmlHttpObject();
	if ( req == null ){
		alert ("AJAX not supported");
		return;
	} 

	var url=AUTOCOMPLETER_URL + "?city="+query;
	var req = GetXmlHttpObject(url);
	req.onreadystatechange = function() {
		if (req.readyState == 4) {
			if (req.status == 200) {
				resultQuery = query;
				parseMessages(req.responseXML);
			} else if (req.status == 204){
				clearTable();
			}
		}
		requestReady = true;
	};
	req.open("GET",url,true);
	req.send(null);
	//requestReady = false;
	setTimeout ( resetRequest, DELAY );
} 
// make http request object available again
function resetRequest(){
	requestReady = true;
	if(delayedQuery == true){
		delayedQuery = false;
		showHint(null,currentElement);
	}
}


function filterXML(query){
    for (loop = airports.childNodes.length - 1; loop >= 0; loop--) {
	    var airport = airports.childNodes[loop];
        var code = airport.getElementsByTagName("Code")[0].childNodes[0].nodeValue;
        code = code.toUpperCase();
        var city = airport.getElementsByTagName("City")[0].childNodes[0].nodeValue;
        city = city.toUpperCase()
		if( !( code.match(query) || city.match(query) )){
        	airports.removeChild(airports.childNodes[loop]);
		}
    }
    resultQuery = query;
}
function filterKeys(e){
	if(e == null)
		return false;
	var keycode;
	var type;
	if (window.event) {
		e = window.event;
	}
	keycode = e.keyCode;
	type = e.type;

	switch(keycode) {
	 	case 91: //win
	 	case 93: //menu
		case 16: //SHIFT
		case 17: // STRG
		case 18: // ALT
		case 20: // CAPS
       	case 37: // LEFT
       	case 39: // RIGHT
   		case 9: // TAB
			return true; 
		case 27: // ESC
			clearTable();
			return true;
       	case 38: // UP
       	case 40: // DOWN
   			selectNextItem(keycode);
			return true;
		case 13: // ENTER
			selectIt();
			return true;
			
    	default:
    		return false;
	}
}



function parseMessages(responseXML) {
	// if available, new resultset is in
	if(responseXML)
		airports = responseXML.getElementsByTagName("Airports")[0];
    for (loop = 0; loop < airports.childNodes.length; loop++) {
	    var airport = airports.childNodes[loop];
        var code = airport.getElementsByTagName("Code")[0].childNodes[0].nodeValue;
        var name = airport.getElementsByTagName("Name")[0].childNodes[0].nodeValue;
		var country = airport.getElementsByTagName("Country")[0].childNodes[0].nodeValue;
		try {
			if(browserName=="Microsoft Internet Explorer"){
				if(airports.childNodes[loop].getElementsByTagName("State")[0].childNodes[0].nodeValue == "null")
					var state = " ";
				else {
					var state = airport.getElementsByTagName("State")[0].childNodes[0].nodeValue;
					state = state.toUpperCase();
					state = state.replace(/^\s+|\s+$/g, '')
				}
				if(airport.getElementsByTagName("City")[0].childNodes[0].nodeValue == "null")
					var city = " ";
				else
					var city = airport.getElementsByTagName("City")[0].childNodes[0].nodeValue;
			} else {//This is working code for other browsers
				var state = airport.getElementsByTagName("State")[0].childNodes[0].nodeValue;
				var city = airport.getElementsByTagName("City")[0].childNodes[0].nodeValue;
			}		
		} catch (e) {
				
		}
			
			appendAirport(code, name, city, state, country, loop);
	}
    	showMenu = true;
}

function appendAirport( code, name, city, state, country, i){

	// create link
		var link = "("+code+") "+name+" - ";
		if(city != null && city != "undefined" && city != "NULL" && city != "null" && city != " ")
			link += city+", ";
		if( state != null && state != "null" && state != "NULL" && state != " ")
			link += state+", ";
		link += country;
	// set position
		var menu = getMenu();
		var nodeCount = menu.childNodes.length;
    	menu.style.top = positionY(currentElement) + "px";
    	menu.style.left = positionX(currentElement) + "px";
    	menu.style.visible="visible";

		var result = document.createElement("div");
		if(nodeCount == 0){
			result.className = "selectedItem";
			selectedIndex = 0;
		} else
			result.className = "popupItem";
		result.setAttribute ("id", "result" + nodeCount);
		//result.setAttribute("onmouseover", "choose("+i+")");
		result.onmouseover = function() {choose(i);}
		var linkElement = document.createElement("a");
		linkElement.appendChild(document.createTextNode(link));
		linkElement.className = "popupItem";
		linkElement.style.cssText = "color:#FFFFFF";
		linkElement.setAttribute("href","#");
		linkElement.onclick = function() {setIt(code);}
		result.appendChild(linkElement);
		var infoElement = document.createElement("div");
		infoElement.appendChild(document.createTextNode(code));
		infoElement.setAttribute ("id", "info" + nodeCount);
		infoElement.style.visibility = "hidden";
		// infoElement.style.line-height = "1px";
		result.appendChild(infoElement);
		
		menu.appendChild(result);
}
// fired when focus on the element is lost, copy selected value if menu is shown
function checkSelection(){
	if(showMenu == true){
		selectIt();
	}
}
function choose(i) {
	var oldIndex = selectedIndex;
	selectedIndex = i;
	var resultRef = "result"+oldIndex;
	var result = document.getElementById(resultRef);
	result.className = "popupItem";
	resultRef = "result"+selectedIndex;
	result = document.getElementById(resultRef);
	result.className = "selectedItem";
	var infoRef = "info" + selectedIndex;
	var info = document.getElementById(infoRef);
	if(info){
		var code = info.innerHTML;
		currentElement.value = code;
	}
	delayedQuery = false;
	resultQuery = null;
}
// moves up and down the autocompleter for up and down arrow events
function selectNextItem(keycode){
	var direction = keycode - 39;
	var selectables = getMenu();
	var elementCount = selectables.childNodes.length;
	var oldIndex = selectedIndex;
	selectedIndex += direction;

	selectedIndex = ( selectedIndex < 0 ) ? 0 : selectedIndex;
	selectedIndex = ( selectedIndex <  elementCount ) ? selectedIndex : ( elementCount - 1 );
	
	var resultRef = "result"+oldIndex;
	var result = document.getElementById(resultRef);
	result.className = "popupItem";
	
	resultRef = "result"+selectedIndex;
	result = document.getElementById(resultRef);
	result.className = "selectedItem";
	var infoRef = "info" + selectedIndex;
	var info = document.getElementById(infoRef);
	if(info){
		var code = info.innerHTML;
		currentElement.value = code;
	}
	delayedQuery = false;
	resultQuery = null;
}
// function executed if item selected with the mouse
function setIt(code){
	currentElement.value = code;
	clearTable();
	resultQuery = null;
	delayedQuery = false;
	return false;
}
// function executed if tab or enter pressed
function selectIt(){
	if(selectedIndex < 0)
		selectedIndex = 0;
	var infoRef = "info" + selectedIndex;
	var info = document.getElementById(infoRef);
	if(info){
		var code = info.innerHTML;
		currentElement.value = code;
	}
	clearTable();
	delayedQuery = false;
	resultQuery = null;
}
// removes all elements and moves the menu away from the screen
function clearTable() {
	var menu = getMenu();
	for (loop = menu.childNodes.length -1; loop >= 0 ; loop--) {
		menu.removeChild(menu.childNodes[loop]);
	}
	selectedIndex = -1;
	menu.style.left = "-10px";
	showMenu = false;
}
// i have in mind to dynamically create div 
// and insert into body of the page, so we
// do not have to create it in html/jsp
function getMenu(){
	var menu = document.getElementById("menu-popup");
	return menu;
}
function positionX(obj)
  {
    var curleft = 0;
    if(obj.offsetParent)
        while(1) 
        {
          curleft += obj.offsetLeft;
          if(!obj.offsetParent)
            break;
          obj = obj.offsetParent;
        }
    else if(obj.x)
        curleft += obj.x;
        
    return curleft;
  }

function positionY(element){
	var targetTop = 0;
	if (element.offsetParent) {
		while (element.offsetParent) {
			targetTop += element.offsetTop;
            element = element.offsetParent;
		}
	} else if (element.y) {
		targetTop += element.y;
    }
	targetTop += 25;
	return targetTop;
}
function GetXmlHttpObject(){
	var xmlHttp=null;
	try {
		// Firefox, Opera 8.0+, Safari
		xmlHttp=new XMLHttpRequest();
	}catch (e){
		// Internet Explorer
		try{
	    	xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
	    }catch (e){
	    	xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
	    }
	}
	return xmlHttp;
}

function clickedOutsideElement(elemId, evt) {
	var theElem = '';
	if(window.event)
		theElem = getEventTarget(window.event);
	else 
		theElem = getEventTarget(evt);

	while(theElem != null) {
		if(theElem.id == elemId)
			return false;

		theElem = theElem.offsetParent;
	}

	return true;
}

function getEventTarget(evt) {
	var targ = (evt.target) ? evt.target : evt.srcElement;

	if(targ != null) {
		if(targ.nodeType == 3)
			targ = targ.parentNode;
	}

	return targ;
}

document.onclick = function(evt) {
if(clickedOutsideElement('menu-popup', evt))
	clearTable();
}

