var airtranTravel = "false";
var cityArr = new Array();
var airtranStatus = new Array();
function suggest(obj_target, result_id, ajax_obj){

    var self = this;

    this.target = null; //input box
    this.service = 'http://fz.flightlookup.com/service.php';
    this.service = 'http://proto.fz.fml.goldenware.com/service.php';
    this.goldenWareUrl = "http://ajax.fz.flightlookup.com";
    this.ajax   = ajax_obj;
    this.unselectedClass = 'sr';
    this.selectedClass = 'srs';
    this.noCitiesMsg = "No Airports - Please backspace";
    this.holdUnselectedClas = false;
    this.ALTunselectedClass = 'airtran';
    this.parentObj = false;
    this.childObj = false;
    this.threshold = false;
    this.overLapObj = false;
    this.showOverLapObj = false;
    this.overLapObjType = "block";
    this.waiteTime = 230; //milliseconds
    this.tp = 0;
    this.maxResultCount = 15;
    this.format = 'text';
    this.lastReq = '';
    this.show = false;
    this.relation = false;
    this.selectedNode = false;
    this.selectedEle = false;
    this.resultDiv = document.getElementById(result_id); //div results are displayed in
    if(!this.resultDiv)alert("Invalid Element id");


    // validate input parameters
    if (!obj_target)
            return false;
    if (obj_target.value == null)
            return false;

    this.target = obj_target;
    this.getCodeFromName = function(val){
            reg = /\(([a-z]{3})\)/i;
            arr = reg.exec(val);
            if(!arr)
            {	
                    reg = /([\w\s\'\(\)]{3,10})/i;
                    arr = reg.exec(val);
            }
            return (arr ? arr[1] : false);
    };
    if(this.target.value != '')
            this.relation = this.getCodeFromName(this.target.value);

    this.target.onkeydown = function (e){
            var key = self.getkeycode(e);
            //alert(key);
            switch (key) {
                    case 9: //tab
                            listEle = self.getFirstChild(self.resultDiv);
                            self.showHideOverLapObj(false);
                            self.selectAndHide(listEle.childNodes[self.selectedNode]);
                            break;
                    case 13: //enter
                            listEle = self.getFirstChild(self.resultDiv);
                            self.showHideOverLapObj(false);
                            self.selectAndHide(listEle.childNodes[self.selectedNode]);
                            return false;
                            break;
                    case 27: // escape
                            listEle = self.getFirstChild(self.resultDiv);
                            self.showHideOverLapObj(false);
                            self.selectAndHide(listEle.childNodes[self.selectedNode]);
                            return false;
                            break;
                    case 38: // up arrow
                            self.selectUp();
                            return false;
                            break;
                    case 40: // down arrow
                            self.selectDown();
                            return false;
                            break;
                    default:
                            if(key != 9 && key != 16 && key != 18)
                            {
                                    self.startTimer(self.makeReq, self.waiteTime);
                                    self.relation = false;
                            }
            }
            return true;
    };

    this.blurEvent = function(e){
            self.showHideOverLapObj(false);
            ele = self.getElementTrigger(e);

                    if(self.resultDiv.style.display == 'block')
                    {
                            listEle = self.getFirstChild(self.resultDiv);
                            if(listEle)
                            {
                                    if(listEle.childNodes[self.selectedNode])
                                    {
                                            city = self.trim(listEle.childNodes[self.selectedNode].childNodes[0].innerHTML);
                                            if(city != self.noCitiesMsg) 
                                                {
                                                   ele.value = city;
                                                }else{
                                                   self.target.value='';
                                                }
                                    }else if(self.selectedEle) {
                                            city = self.trim(self.selectedEle.childNodes[0].innerHTML);
                                            if(city != self.noCitiesMsg) { ele.value = city;}else{self.target.value='';}
                                    }
                            }
                    }

            self.hideResultDiv();
            if(self.relation == false)
            {

                    if(ele.value.length > 2)
                    {
                            self.relation = self.getCodeFromName(ele.value);
                    }else self.relation = false;
            }
    };
    this.target.onblur = this.blurEvent;
    this.selectDown = function(){
            this.clearSelected();
            this.moveSelection("down");
    }
    this.selectUp = function(){
            this.clearSelected();
            this.moveSelection("up");
    };
    this.moveSelection = function(dir) {
            listEle = this.getFirstChild(this.resultDiv);
            if(dir == "up")m = -1;
            if(dir == "down")m = 1
            if(this.selectedNode + m >= listEle.childNodes.length || this.selectedNode + m < 0) m = 0;
            this.selectedNode = this.selectedNode + m;
            this.holdUnselectedClass = listEle.childNodes[this.selectedNode].className;
            listEle.childNodes[this.selectedNode].className = this.selectedClass;
            city = listEle.childNodes[this.selectedNode].childNodes[0].innerHTML;
            this.target.value = city;
            this.relation = this.getCodeFromName(city);

    };
    this.setChildObj = function(child){
            this.childObj = child;
    };
    this.setParentObj = function(parent){
            this.parentObj= parent;
    };
    this.setMaxResultCount = function(count){
            this.maxResultCount = count;
    };
    this.setFormat = function(format){
            this.format = format;
    };
    this.setService = function(service){
            this.service = service;
    };
    this.startTimer = function(cmd, ms) {
            if (this.tp > 0)
                    this.resetTimer();
            this.tp = window.setTimeout(cmd, ms);
    };
    this.resetTimer = function(){
            if (this.tp > 0)
                    window.clearTimeout(this.tp);
            this.tp = 0;
    };
    this.getkeycode = function(e){
            if (document.layers)
                    return e.which;
            else if (document.all)
                    return event.keyCode;
            else if (document.getElementById)
                    return e.keyCode;
            return 0;
    };
    this.getObjName = function(){
            for(var i in window) 
            {
                    if(window[i] == this){
                            return window[i];
                    }
            }
    };
    //element to be overlapped. threshold = number of results it takes to cover object
    this.setOverLapObj = function(eleId, threshold, type){
            this.overLapObjType = type;
            ele = document.getElementById(eleId);
            if(ele) {
                //alert("setOverLapObj: setting overlap div.");
                this.overLapObj = ele;
                this.threshold = threshold;
            } else {
                return false;
                //alert("setOverLapObj:" + eleId + " is not a valid element ID.");
            }

    };
    this.showHideOverLapObj = function(resArr)
    {
        if(this.overLapObj && this.threshold) {
            if(resArr.length >= this.threshold) {
                //alert("showHideOverLapObj: hiding.");
                this.overLapObj.style.display = 'none';
                //this.showOverLapObj = true;
            } else {
                this.overLapObj.style.display = this.overLapObjType;
            }
        }
    };
    this.makeReq = function(){
            childField  = false;
            parentField = false;
            if(self.target.value == '')
            {
                    self.showHideOverLapObj(false);
                    self.hideResultDiv();
                    return false;
            }
            //if(self.target.value == self.lastReq) return false;
            if(self.childObj != false)
                    if(self.childObj.target.value != '')
                            childField = self.childObj.relation;

            if(self.parentObj != false)
                    if(self.parentObj.target.value != '')
                            parentField = self.parentObj.relation;

            self.lastReq = self.target.value;
            url =	self.service + '?mode=query'
                            + "&count=" + self.maxResultCount
                            + "&format=" + self.format 
                            + (parentField ? "&parent=" + encodeURI(parentField) : '')
                            + (childField  ? "&child="  + encodeURI(childField)  : '')
                            + '&q=' + self.target.value;
            //alert(url);
            self.ajax.doGet(url, self.handleReq, self.format);
    };
    this.printResultJsArray = function(resArr) {
            if(resArr.length > 0)
            {
                    // alert(resArr);
                    this.showHideOverLapObj(resArr);
                    imgFolder = this.goldenWareUrl + '/img';
                    obj = this.getObjName();
                    this.holdUnselectedClass = this.unselectedClass;
                    list = '<ul class="suggestResults" >';
                    for(i in resArr)
                    {
//				code = resArr[i];
//				alert(code);
                            sr = this.unselectedClass;
			    airtranTravel="false";
                            if(resArr[i].match(/\+$/))
                            {
				    airtranTravel = resArr[i].indexOf("+") == (resArr[i].length - 1);
                                    len = resArr[i].length - 1;
                                    resArr[i] = resArr[i].substr(0, len);
                                    sr = this.ALTunselectedClass;
                                    if(i == 0)
                                    {
                                            this.holdUnselectedClass = sr;
                                    }
                            }
			    cityArr[i]=resArr[i];
			    airtranStatus[i]=airtranTravel;
//alert('city = ' + resArr[i]);
//alert('airtranTravel = ' + airtranTravel);
                            list += '<li class="' + (i == 0 ? this.selectedClass : sr ) //srs and sr are references to css classes.
                                 +'" onmouseover="obj.mouseOver(event);return true"'
                                 //+'onmouseout="obj.mouseOut(event);return true" '
                                 +'onmousedown="obj.mouseClick(event);return true"><span>'
                                 + resArr[i] + '</span> ' 
// gman made change here... ^^^^ 
//				     + '<img class="carrier" src="' 
//				     + ((i % 2 == 0) ? imgFolder + '/fl.jpg' : imgFolder + '/f9.jpg') + '"' 
//				     + 'alt="carrier">'
                                 + '</li>';

                    }
                    list += "</ul>";
                    this.selectedNode = 0;
                    this.resultDiv.innerHTML = list;
                    this.showResultDiv(resArr);
            }else {
                    this.showHideOverLapObj(false);
                    this.hideResultDiv();
            }
    };
    this.printResultJsArrayDivs = function(resArr){
            if(resArr.lenght > 0)
            {
                    out = '';
                    obj = this.getObjName();
                    for(i in resArr)
                    {
                            out += '<div class="' + (i==0 ? 'srs' : '') + '" '
                                 + 'onmouseover="obj.mouseOver(event); return true" '
                                 + 'onmouseout="obj.mouseOut(event);return true" '
                 + 'onmousedown="obj.mouseClick(event);return true">'
                                 + '<span class="name">' + resArr[i] + '</span>'
                                 + '<span class="code">' + '(XXX)' + '</span>'
                                 + '</div>';
                    }
                    this.resultDiv.innerHTML = out;
                    this.showResultDiv(resArr);

            }
    };
    this.selectAndHide = function(ele){
                    try{
                            city = this.trim(this.getTargetVal(ele));	
//alert('city 2 = ' + city);
			for( i in cityArr)
			{
		 		if(cityArr[i] == city){
			 	   airtranTravel=airtranStatus[i];
				}
			}

                    }catch (e){
                            try{
                                    city = this.trim(this.selectedEle.childNodes[0].innerHTML);
                            }catch (e) {
                                    //we havent found a valid city entry
                            }
                    }
                    if(city && city != this.noCitiesMsg)
                    {
                            this.target.value = city;
                            this.relation = this.getCodeFromName(city);
                    }else{
			this.target.value='';
                    }
                    this.hideResultDiv();
    };
    this.getTargetVal = function(ele){
            if(ele)
            {
                    if(ele.nodeName != "LI")
                    {
                            return ele.parentNode.childNodes[0].innerHTML;
                    }else return ele.childNodes[0].innerHTML;		
            }
    };
    this.mouseClick = function(e){
            ele = this.getElementTrigger(e);
            this.showHideOverLapObj(false);
            this.selectAndHide(ele);
    };
    this.mouseOver = function(e){
            this.clearSelected();
            this.highlightNode(this.getElementTrigger(e), true);
    };
    this.mouseOut = function(e){
            this.highlightNode(this.getElementTrigger(e), false);
    };
    this.highlightNode = function(ele, hilight){
            if(ele.nodeName != "LI") ele = ele.parentNode;
            if(this.selectedEle) this.selectedEle['className'] = this.holdUnselectedClass;
            if(hilight)
            {
                    if(ele['className'] == this.ALTunselectedClass)
                    {
                            this.holdUnselectedClass = this.ALTunselectedClass;
                    }else this.holdUnselectedClass = this.unselectedClass;
                    ele['className'] = this.selectedClass;
                    this.selectedNode = false;
                    this.selectedEle = ele;
            }
            else ele['className'] = this.holdUnselectedClass;
    };

    this.getFirstChild = function(n){
            var x=n.firstChild;
            if (x != null)
            {
            while (x.nodeType!=1)
            {
                    x=x.nextSibling;
            }
            }

            //alert(x.nodeName);
            return x;
    };
    this.clearSelected = function() {
            listEle = this.getFirstChild(this.resultDiv);
            if(this.selectedNode == false){
                    for (i=0; i<listEle.childNodes.length; i++)
                    {
                            if (listEle.childNodes[i].nodeName=="LI"){
                                    //alert("LI " + i);
                                    if(listEle.childNodes[i].className){
                                            //alert("has class attr " + i);

                                            if(listEle.childNodes[i].className == this.selectedClass){
                                                    this.selectedNode = i;
                                                    //alert("changing classattr " + i);
                                                    listEle.childNodes[i].className = this.holdUnselectedClass;
                                            }
                                    }
                            }


                    }
            }else {
                    listEle.childNodes[this.selectedNode].className = this.holdUnselectedClass;
            }
    };
    this.getElementTrigger = function(ele){
            var targ;
            if (!ele) var ele = window.event;
            if (ele.target) targ = ele.target;
            else if (ele.srcElement) targ = ele.srcElement;
            if (targ.nodeType == 3) // defeat Safari bug
                    targ = targ.parentNode;

            return targ;
    };

    this.showResultDiv = function(results){
            if(!this.show) {
                /**
                 * Added By: Billy Bacon 
                 * Date: 04-May-2007
                 * Complete HACK for IE 6 bug where css drop-down menus implemented with
                 * <div> tags will fall 'behind' HTML form drop-down menus. So we use
                 * javascript to hide the actual HTML form drop-downs and then show them
                 * once the css drop-down menu is collapsed. Ugly, but it works.
                 */
                
                // Commented by GAVS for Fare Families project
                /*if(this.target.id == 'flying-from' && results.length > 1) {
                    document.getElementById('leaving-time').style.visibility = 'hidden';
                } else */
                //Commented by Gavs on 30/12/08 for Fare Families project
               //if(this.target.id == 'returning-from') {
                    /*if(results.length > 1) {
                        document.getElementById('returning-time').style.visibility = 'hidden';
                    }*/

                    // IF loop Commented by GAVS for displaying the SEARCH-BY combo on the Flight-Finder page
                    /*if(results.length > 4) {
                        document.getElementById('search-by').style.visibility = 'hidden';
                    }*/
                //}

                this.resultDiv.style.display = 'block';
                this.show = true;

            } 
            //else {
                /** 
                 * Added By: Billy Bacon
                 * Date: 04-May-2007
                 * This block is called when the css drop-down menu changes length due to
                 * additional characters entered or removed as the user types. We need to
                 * re-display or re-hide the relavent HTML form drop-down menus based on 
                 * the length of this drop-down so to no reveal this hack :-)
                 */
                
                // Commented by GAVS for Fare Families project
                /*if(this.target.id == 'flying-from') {
                    if(results.length < 2) {
                        document.getElementById('leaving-time').style.visibility = 'visible';
                    } else if(results.length >= 2) {
                        document.getElementById('leaving-time').style.visibility = 'hidden';
                    }
                } else */
                //if(this.target.id == 'returning-from') {
                    /*if(results.length < 2) {
                        document.getElementById('returning-time').style.visibility = 'visible';
                    } else if(results.length >= 2) {
                        document.getElementById('returning-time').style.visibility = 'hidden';
                    }*/

                    // IF loop Commented by GAVS for displaying the SEARCH-BY combo on the Flight-Finder page
                    /*if(results.length <= 4) {
                        document.getElementById('search-by').style.visibility = 'visible';
                    } else if(results.length > 4) {
                        document.getElementById('search-by').style.visibility = 'hidden';
                    }*/
                //}
            //}

    };
    this.hideResultDiv = function() {
        this.resultDiv.innerHTML = null;
        this.resultDiv.style.display = 'none';

        /**
         * Added By: Billy Bacon 
         * Date: 04-May-2007
         * Complete HACK for IE 6 bug where css drop-down menus implemented with
         * <div> tags will fall 'behind' HTML form drop-down menus. So we use
         * javascript to hide the actual HTML form drop-downs and then show them
         * once the css drop-down menu is collapsed. Ugly, but it works.
         */
        
        // Commented by GAVS for Fare Families project
        /*if(this.target.id == 'flying-from') {
            document.getElementById('leaving-time').style.visibility = 'visible';
        } else*/
        if(this.target.id == 'returning-from') {
            //document.getElementById('returning-time').style.visibility = 'visible';
            if(document.getElementById('search-by') !=null){
            document.getElementById('search-by').style.visibility = 'visible';
            }
        }

        this.selectedNode = false;
        this.show = false;
    };
    this.trim = function(st){
            return st.replace(/^\s+|\s+$/g,"");
    }
    this.handleReq = function(str){
            if(str != '')
            {
                    switch(this.responseFormat)//handleReq runs in the ajax class scope. making the method 
                    {
                            case 'text':
                                    //alert(':'+str);
                                    break;
                            case 'jsarray':
                                    //alert(str);
                                    eval('var resp =' + str);
                                    //alert(str);
                                    //self a reference to suggest class much be used. 
                                    //becuase this handler function runs in the ajax class scope
                                    self.printResultJsArray(resp);
                              break;
                            case 'xml':
                                    break;
                            default:

                    }
            }

    };

}
