var predictiveTextReady = false;
var DELAY_betweenTypingCalls = 0, REQUIRED_chars = 3, IFRAME_width_Max = 250, IFRAME_width = 250, DIV_width = 250, UL_width = 250, MAX_SHOW = 8, DIV_HEIGHT = 134, SCROLL_INCR = 17;
var YOFFSET_applicationTabsContentClass = 16;
var YOFFSET_MSIE = 18;
var NAME_tabsClassForOffset = 'applicationTabsContent';
var handleKeyPressedRef = null, eventHandle = null;
var lastSent = '';
var itemCount = 0, currentSelection = -1, prevSelection = -1, LastSentTime = 0, lastKeyCode = 0
var WriteToIFrame, WriteToDiv, SourceInput;
var isStopped = false, isReallyOut = true, isOutLastKeyEnter = false, hasBlurred = false;
var ObjectHash = new Object;
var CurrentMatches = new Array();
var ExceptionCodes = {NYC:'New York-All Airports, NY, US (NYC)',CHI:'Chicago-All Airports, IL, US (CHI)',WAS:'Washington-All Airports, DC, US (WAS)',PAR:'Paris-All Airports, France, FR (PAR)',LON:'Londong-All Airports, United Kingdom, GB (LON)'}
var includeAwards = false;

function initPredictiveText() {
  predictiveTextReady = true;
}        

function returnURI() {
	var URIBegin = window.location.href.lastIndexOf('.delta.com') + 10;
	var URIEnd = (window.location.href.lastIndexOf('?') > URIBegin) ? window.location.href.lastIndexOf('?') : window.location.href.length;
	return window.location.href.substring(URIBegin, URIEnd)
}

function setIsreallyOut(value) { isReallyOut = value; }

function checkPTBlur() { if(isReallyOut) { cancelBox(); } hasBlurred = true;}

function airportLocator(Definition) {
	includeAwards = exists(Definition.inclAwd) ? Definition.inclAwd : false;
	var counter = 0;
	DELAY_betweenTypingCalls = 0;
	cancelBox();
	setIsreallyOut(false);
	initOnKeyDownHandler(keypressed);
	SourceInput = Definition.TargetInput;
	Definition.TargetInput.autocomplete = 'off';
	Definition.TargetInput.setAttribute('autocomplete', 'off');
	SourceInput.onblur = checkPTBlur;
	SourceInput.onmouseout = function() { setIsreallyOut(true); }
	isOutLastKeyEnter = false;
	hasBlurred = false;
	if (eventHandle) {
		clearTimeout(eventHandle);
		eventHandle = '';
	}
	lastSent = '';
	currentSelection= -1;
	prevSelection = -1;
	isStopped = false;
	CurrentMatches.length = 0;
}

function cancelBox() {
	if(exists(SourceInput) && exists(SourceInput.value)) { setAirportCodeAndDisplay(currentSelection); }
	initOnKeyDownHandler(null);
	setIsreallyOut(true);
	closeBox();
	SourceInput = null;
	isStopped = false;
}

function cancelEnter() {
	var v = (isStopped == null || isStopped != true);
    isStopped = false;
	if(isOutLastKeyEnter) return true;
	return (v ? true: isLastKeyEnter());
}

function checkMatch(Value, ObjectInstance, Dictionary, AddToArray) {
	if(!Dictionary[ObjectInstance.airportCode]) {
		switch(true) {
			case ObjectInstance.airportCode.toUpperCase() == Value.toUpperCase():
				AddToArray.unshift(ObjectInstance);
				break;
			case ObjectInstance.cityName.substr(0, Value.length).toUpperCase() == Value.toUpperCase():
				AddToArray.push(ObjectInstance);
				break;
			default:
				for(var i=0, j=ObjectInstance.aliases.length; i<j; i++) {
					if(ObjectInstance.aliases[i].substr(0, Value.length).toUpperCase() == Value.toUpperCase()) {
						AddToArray.push(ObjectInstance);
						break;
					}
				}
				break;
		}
		Dictionary[ObjectInstance.airportCode] = true;
	}
}

function closeBox() {
    if (WriteToDiv != null) {
        hide(WriteToDiv.id);
        WriteToDiv.innerHTML = '';
    }
    if (WriteToIFrame!= null) { hide(WriteToIFrame.id); }
    isStopped = true;
}

function continueTyping(input) {
	if (isLastKeyEnter()) {
		var now = new Date().getTime();
		if (now - LastSentTime > DELAY_betweenTypingCalls) {
			clearTimeout(eventHandle);
			takeTypingInput();
		} else {
			clearTimeout(eventHandle);
			eventHandle = self.setTimeout('continueTyping()', DELAY_betweenTypingCalls);
		}
	}
}

function createPTextHTMLElement(Definition) {
	var Element = document.createElement(Definition.elementType);
	Element.id = Definition.id;
	if(Definition.className) { Element.className = Definition.className; }
	if(Definition.position) { Element.style.position = Definition.position; }
	if(Definition.width) { Element.style.width = Definition.width; }
	if(Definition.zIndex) { Element.style.zIndex = Definition.zIndex; }
	if(Definition.frameborder) { Element.setAttribute('frameborder', Definition.frameborder); }
	if(Definition.scrolling) { Element.setAttribute('scrolling', Definition.scrolling); }
	if(Definition.src) { Element.setAttribute('src', Definition.src); }
	Definition.appendChildTo.appendChild(Element);
	return Element;
}

function displayPTResults() {
	if(itemCount > MAX_SHOW) {
		WriteToDiv.style.height = DIV_HEIGHT + 'px';
		WriteToDiv.style.overflow = 'auto';
		if(isShowIframe()) { WriteToIFrame.style.width = IFRAME_width_Max; }
	} else {
		WriteToDiv.style.height = '';
		WriteToDiv.style.overflow = 'hidden';	
	}
    show(WriteToDiv.id, 'block');
    if (isShowIframe() && WriteToIFrame != null) {
		show(WriteToIFrame.id, 'block');
		WriteToIFrame.style.height = (WriteToDiv.offsetHeight) + "px";
		WriteToIFrame.style.top = WriteToDiv.style.top;
		WriteToIFrame.style.left = WriteToDiv.style.left;
	}
}

function drawPTChoices(isUseObjectHash) {
	hidePTResults();
	var Matches = (isUseObjectHash) ? ObjectHash[lastSent] : CurrentMatches;
	setInnerHTML(WriteToDiv.id, '');
	if(exists(Matches) && Matches.length > 0) {
		var HTML = new Array();
		HTML.push('<!-- mp_trans_disable_start -->');
		HTML.push('<ul class="AirportList" style="width: ' + (UL_width) + 'px;">');
		for(var i=0, j=Matches.length; i<j; i++) {
			var uri = returnURI();
			if(exists(ExceptionCodes[Matches[i].airportCode])) {
				if(uri.toLowerCase().indexOf('/awards/') == -1) {
					HTML.push('<li style="width: ' + UL_width + 'px" id="' + Matches[i].airportCode + '" class="AirportList">' + returnPTDisplayString(Matches[i]) + '</li>');
				}
			} else {
				HTML.push('<li style="width: ' + UL_width + '" id="' + Matches[i].airportCode + '" class="AirportList">' + returnPTDisplayString(Matches[i]) + '</li>');
			}
		}
		HTML.push('</ul>');
		HTML.push('<!-- mp_trans_disable_end -->');
		setInnerHTML(WriteToDiv.id, HTML.join(''))
		var List = getAirportBoxList();
		itemCount = List.childNodes.length
		for (var i=0, j=List.childNodes.length; i<j; i++) {
			li = List.childNodes[i];
			li.onmousedown = handleOnMouseDown;
			li.onmouseover = hanldeOnMouseOver;
			li.onmouseout = handleOnMouseOut;
		}
		WriteToDiv.scrollTop = 0;
		displayPTResults();
		currentSelection=0;
		prevSelection=0;
		selPTChoice(0);
	} else {
		itemCount = 0;
		if(SourceInput.value != '') {
			WriteToDiv.innerHTML = '';
			hidePTResults();
		} else {
			hidePTResults();
		}
	}
}

function findAirport() {
   try{
         if(!predictiveTextReady) { return; }
	      var TotalFixed = fixPTString(SourceInput.value);
	      var TruncatedFixed = fixPTString(SourceInput.value.substr(0, REQUIRED_chars))
	      switch(true) {
         case (SourceInput.value.length >= REQUIRED_chars && lastSent != SourceInput.value.substr(0, REQUIRED_chars).toUpperCase() && !isInObjectHash(TruncatedFixed)):
	      		lastSent = TruncatedFixed;
				hasBlurred = false;

	      		PredictiveText.getPredictiveCities(lastSent, includeAwards,
                                                  {callback:handlePTCallback,
                                                   errorHandler:handlePTError,
                                                   timeout:6000
                                                   });

	      		break;
	      	case isInObjectHash(TruncatedFixed):
	      			setPTDisplay();
	      			fineTuneMatches(TotalFixed);
	      			if(exists(SourceInput)) { drawPTChoices(false); }
	      			currentSelection=0;
	      			prevSelection=0;
	      			selPTChoice(0);
	      		break;
	      	default:
	      		hidePTResults();
	      		break;
	      }
   } catch (e) {
      handlePTError();
   }
}

function fineTuneMatches(Value) {
	CurrentMatches.length = 0;
	var Dictionary = new Array();
	for(var obj in ObjectHash) {
		var Matches = ObjectHash[obj];
		for(var i=0, j=Matches.length; i<j; i++) {
			if(Value.length == 3) {
				if(obj == Value) { CurrentMatches.push(Matches[i]); }
			} else {
				checkMatch(Value, Matches[i], Dictionary, CurrentMatches);
			}
		}
	}
}

function fixPTString(Value) {
    var strSound = Value;
	strSound = strSound.replace(/^FOR /gi, 'FORT ');
    return strSound.toUpperCase();
}

function getAirportBoxList() {
    var ul;
    for (var i=0; i < WriteToDiv.childNodes.length; i++) {
       var node = WriteToDiv.childNodes[i];
       if (node.nodeName == 'UL') {
           ul = node;
           break;
       }
    }
    return ul;
}

function getPTIndex(elem) {
    var list = getAirportBoxList();
    var currentIndex = 0;
    for (var i=0, j=list.childNodes.length; i < j; i++) {
        if (elem == list.childNodes[i]) {
            return i;
		}
    }
    return currentIndex;
}

function handlePTCallback(data) { 
	try {
		DELAY_betweenTypingCalls = 100;
		CurrentMatches.length = 0;
		setPTDisplay();
		if(data.citiesDWR != null && lastSent != '') {
			ObjectHash[lastSent] = new Array();
			for(var i=0, j=data.citiesDWR.length; i<j; i++) {
				ObjectHash[lastSent].push(data.citiesDWR[i])
			}
			if(hasBlurred) { throw {desc:'Exited before callback',num:1001}; }
			if(exists(SourceInput)) { drawPTChoices(true); }
		} else  {
			hidePTResults();
		}
	} catch (e) { handlePTError(); }
}


function handlePTError() {
	try {
		hidePTResults();
	} catch (e) {}
}

function handleOnKeyDown(e) {
	var eventKeyCode = (document.all) ? window.event.keyCode : e.which;
	var eventString = String.fromCharCode(eventKeyCode).toLowerCase();
	lastKeyCode = eventKeyCode;
	if(handleKeyPressedRef != null) { handleKeyPressedRef(eventKeyCode, eventString); }
}

function handleOnMouseDown(event) {
    var obj = event ? event.target : this;
    currentSelection = getPTIndex(obj);
    setAirportCodeAndDisplay(currentSelection);
	setIsreallyOut(true);
    cancelBox();
}

function handleOnMouseOut(event) {
    var obj = event ? event.target : this;
    currentSelection = -1;
    selPTChoice(-1);
}

function hanldeOnMouseOver(event) {
    var obj = event ? event.target : this;
    currentSelection = getPTIndex(obj);
    selPTChoice(currentSelection);
	setIsreallyOut(false);
}

function hidePTResults() {
	if(exists(WriteToDiv)) {
		hide(WriteToDiv.id);
		if(isShowIframe()) { hide(WriteToIFrame.id); }
	}
}

function initOnKeyDownHandler(keyPressedRef) {
	document.onkeydown = handleOnKeyDown;
	handleKeyPressedRef = keyPressedRef;
	if (document.layers) { document.captureEvents(Event.KEYPRESS); }
}

function isInObjectHash(Value) {
	return exists(ObjectHash[Value]);
}

function isLastKeyEnter() { if(lastKeyCode == 13 && isReallyOut == true) { isOutLastKeyEnter = true } return lastKeyCode != 13; }

function isShowIframe() { return ( !exists(window.opera) && exists(window.ActiveXObject) && exists(document.all) ) ? true : false; }

function keypressed(keycode, keyvalue) {
    clearTimeout(eventHandle);
    LastSentTime = new Date().getTime();
    switch (keycode) {
		case 37: //left
		case 38: //up
	        currentSelection --;
			setIsreallyOut(false);
			if (currentSelection < 0) { currentSelection = 0; }
			selPTChoice(currentSelection);
			if(itemCount > MAX_SHOW) {
				var presentVisible = parseInt((currentSelection) * SCROLL_INCR);
				WriteToDiv.scrollTop = presentVisible;
			}
	        break;
		case 39: //right
		case 40: //down
	        currentSelection++;
			setIsreallyOut(false);
			if (currentSelection >= itemCount) { currentSelection = itemCount-1; }
			selPTChoice(currentSelection);
			if(itemCount > MAX_SHOW) {
				var presentVisible = parseInt((currentSelection) * SCROLL_INCR);
				WriteToDiv.scrollTop = presentVisible;
			}
	        break;
		case 13: //enter 
			if (itemCount>0) {
				setIsreallyOut(true);
				setAirportCodeAndDisplay(currentSelection);
				closeBox();
			}
			break;
		case 27: //esc
			setIsreallyOut(true);
			closeBox();
			break;
		case 9: //tab
			if (currentSelection >= 0 && currentSelection < itemCount) {
				setIsreallyOut(true);
				setAirportCodeAndDisplay(currentSelection);
			}
			break;
		case 18: //alt
		case 16: //shift
			break;
		default:
			setAirportCodeAndDisplay(-1);
			eventHandle = self.setTimeout('continueTyping()', DELAY_betweenTypingCalls);
    }
}

function returnPTDisplayString(ObjectInstance) {
	return ObjectInstance.cityName + ((exists(ObjectInstance.region)) ? ', ' + ObjectInstance.region : '') + ((exists(ObjectInstance.countryCode)) ? ', ' + ObjectInstance.countryCode : '') + ' (' + ObjectInstance.airportCode + ')';
}

function selPTChoice(ID) {			
	try {
		var list = getAirportBoxList();
		if (typeof(list) != 'undefined' && list.childNodes.length > 0) {
			if (ID >= 0) {
				if(prevSelection >= 0) { list.childNodes[prevSelection].className = 'AirportList';}
				prevSelection = ID;
				list.childNodes[prevSelection].className = 'SelectedAirport';
			}
		}
    } catch(e) { handlePTError(); }
}

function setAirportCodeAndDisplay(ID) {
	switch(true) {
		case ID < 0:
			lastSent = '';
			break;
		case itemCount > 0:
			var AiportList = getAirportBoxList();
			if (AiportList == null || AiportList.childNodes == null) return;
			var Chosen = AiportList.childNodes[ID]
			SourceInput.value = Chosen.id;
			break;
    }
}

function setPTDisplay() {
	try {
			WriteToDiv = get('AirportListDiv');
			if (!WriteToDiv) {
				WriteToDiv = createPTextHTMLElement({elementType:'div', id:'AirportListDiv', zIndex:51, className:'AirportList', position:'absolute', width:DIV_width, appendChildTo:document.body});
				hide(WriteToDiv.id);
			}
			WriteToDiv.onmouseout = function() { setIsreallyOut(true); }
			WriteToDiv.onmouseover = function() { setIsreallyOut(false); }

			if (isShowIframe()) {
				WriteToIFrame = get('AirportListIframe');
				if (!WriteToIFrame) {
					WriteToIFrame = createPTextHTMLElement({elementType:'iframe', id:'AirportListIframe', zIndex:50, className:'AirportList', position:'absolute', frameborder:'0', scrolling:'no', width:IFRAME_width, appendChildTo:document.body,src:'java' + 'script:\'<html></html>\';'});
					hide(WriteToIFrame.id);
				}
			}
			if(exists(SourceInput)) {
				var XY;
				XY = getPTElementXAndYPos(SourceInput);
				if(!isNaN(XY.y)) { WriteToDiv.style.top = XY.y + SourceInput.clientHeight + 'px'; }
				if(!isNaN(XY.x)) { WriteToDiv.style.left = (XY.x) + 'px'; }
			}
	} catch(e) { handlePTError(); }
}
function takeTypingInput() {
    if ( (SourceInput != null ) && SourceInput.value.length > 0) {
		findAirport();
	} else {
		setAirportCodeAndDisplay(-1);
		closeBox();
	}
}


function getPTElementXAndYPos(element) {
	var curLeft = 0, curTop = 0;
	if(element.offsetParent) {
		while (element.offsetParent) {
			var topOffSet = 0;
			// updated to include booking for the full search placement
			var uri = returnURI();
			if(!isShowIframe() && uri.toLowerCase().indexOf('/booking/') == -1 && exists(element.className) && element.className.indexOf(NAME_tabsClassForOffset) !== -1) {
				// the border top for the application tabs class is not accounted for in non-ie browsers when it comes to the offsetTop
				topOffSet = YOFFSET_applicationTabsContentClass;  // this is 16
			}

			var bName = navigator.appName;
			if(uri.toLowerCase().indexOf('/awards/') != -1 && bName == 'Microsoft Internet Explorer' && exists(element.className) && element.className.indexOf(NAME_tabsClassForOffset) !== -1) {
				topOffSet = YOFFSET_MSIE;  // this is 18
			}

			curLeft += element.offsetLeft;
			curTop += element.offsetTop + topOffSet;
			element = element.offsetParent;
		}
	} else if(element.x) {
		curLeft = element.x;
		curTop = element.y;
	}
	return {x:curLeft, y:curTop};
}
                                                                 