﻿var comboWidth = '223px';
var aDisallowedSites = new Array();

var departAirport  = __departAirport;
var arrivalAirport = __arrivalAirport;
var selectAirport  = __selectAirport;


// IsValidSite
function IsValidSite()
{
    var i, length, pub;
    
    for (i = 0, length = aDisallowedSites.length; i < length; i++)
    {
        pub = document.location.pathname;
        pub = pub.substr(0, aDisallowedSites[i].length);
        pub = pub.toLowerCase();
        
        if (pub == aDisallowedSites[i])
        {
            return false;
        }    
    }
    
    return true;
}

// CreateSuggest
//
// Create a suggestion control for an existing HTML dropdown
//
// elementID:   HTML element ID for the dropdown to be wrapped
// sDefault:    Default text to show
function CreateSuggest(elementID, sDefault)
{
    
    // Check if this site is disabled for predictive search
    if (!IsValidSite())
        return;    
    var oDropdown, oProvider, oSuggest;    
    var oDropdown = document.getElementById(elementID);        
    if (oDropdown)
    {   
        oProvider = new EKDropdownProvider(oDropdown, sDefault);               
        oSuggest = new EKSuggest(oProvider, false, true, true);        
    }    
}
/*AJ - Predicitive Search*/
function From_Enter(idFrom, idTo, idTd)
{    
    if(document.getElementById(idFrom + '-suggest') !=null)
    {
        var from = document.getElementById(idFrom + '-suggest').value;			    
        if(from!="")
        {
            var start = from.lastIndexOf('(');
            var end   = from.lastIndexOf(')');
            
            var combo_box = document.createElement('select');
            combo_box.name = idTo.replace(/_/g,"$");
            combo_box.id = idTo;
            combo_box.style.display = 'none';
            combo_box.width= comboWidth; //'224px'
            combo_box.className = 'formField';
            document.getElementById(idTd).replaceChild(combo_box,document.getElementById(idTo));
            document.getElementById(idTd).appendChild(combo_box);                  
            populateDataPre(from.substring(start+1, end),idTo,'');    			    
            document.getElementById(idTd).removeChild(document.getElementById(idTo+ '-suggest'));                        
            CreateSuggest(idTo,arrivalAirport);
        }
    }
}
function ReCreateDropDown(id, idTd)
{
    if(document.getElementById(id + '-suggest') !=null)
    {   
        document.getElementById(idTd).removeChild(document.getElementById(id+ '-suggest'));             
        var combo_box = document.createElement('select');
        combo_box.name = id.replace(/_/g,"$");        
        combo_box.id = id ;        
        combo_box.width= comboWidth;//'224px'
        combo_box.className = 'formField';        
        document.getElementById(idTd).replaceChild(combo_box,document.getElementById(id));        
        document.getElementById(idTd).appendChild(combo_box);
        
    }
}
function ReCreateSuggest(id, text, prevVal)
{   
    if(prevVal.indexOf('|')!=-1)
    {
        prevVal = prevVal.substring(0,prevVal.indexOf('|'));
    }
    var _assignText = '';    
    if(prevVal !='')
    {
        _assignText = GetMeTextFromValue(id,prevVal);
    }
    CreateSuggest(id,text);
    if(_assignText!='')
    {
        document.getElementById(id).value = prevVal;
        document.getElementById(id + '-suggest').value = _assignText;
    }
}

function GetAndPutValues(idSource, idDest, defaultText)
{
    var _assignText = ''; 
    var val = document.getElementById(idSource).value;
    if(val!='')
    {
        _assignText = GetMeTextFromValue(idDest,val)
        if(_assignText !='')
        {
            document.getElementById(idDest).value = val;
            document.getElementById(idDest + '-suggest').value = _assignText;
        }
        else
        {
            document.getElementById(idDest).value = '';
            document.getElementById(idDest + '-suggest').value = defaultText;
        }
    }
}
function EmptyToFromFrom(idSource, idDest, defaultText)
{
    if(document.getElementById(idSource)!=null)
    {
        var val = document.getElementById(idSource).value;
        if(val=='')
        {
            document.getElementById(idDest).value = '';
            document.getElementById(idDest + '-suggest').value = defaultText;            
        }
    }
}


function GetMeTextFromValue(id,val)
{
    var length = 0;
    var retval = '';
    if(document.getElementById(id) !=null)    
        length = document.getElementById(id).length;    
    for(i=0;i<length;i++)
    {   
        if(document.getElementById(id).options[i].value == val)
        {   
            retval = document.getElementById(id).options[i].text;
            break;
        }
    }
    return retval;
}


function Populate_ToHidden(idTo)
{   
    if(document.getElementById(idTo+'-suggest')!=null)
	{   
	    var to = document.getElementById(idTo+'-suggest').value;			    
	    if(to!="")
	    {
	        var s = to.lastIndexOf('(');
	        var e = to.lastIndexOf(')');    			    
	        document.getElementById(idTo).value = to.substring(s+1, e);			        	
	    }
	}	
}


function To_Enter(idFrom, idTo)
{   
    if(document.getElementById(idTo).value!='')
    {   
        var ret = document.getElementById(idTo).value;        
        if(document.getElementById(idTo).value.indexOf('|')== -1)
        {
            ret = GiveMeWithInterline(document.getElementById(idFrom).value,idTo,document.getElementById(idTo).value);            
            if(ret !='')
                IsEkOperated(ret);            
        }
        else
        {
            IsEkOperated(ret);            
        }
    }
    else
    {
        IsEkOperated('BAH');
    }    
}


/*AJ Predictive Search Block Ends*/



/*****************************************************/
/* EKSuggest Class                                   */
/*****************************************************/

// EKSuggest Constructor
//
// Setup the EKSuggest class
//
//  oProvider:      EKSuggest compatible suggestion data provider
//  bTypeAhead:     AutoComplete typed values automatically, matching always begins from start of string
//                  Note that some providers might not support this                
//  bPhoneticMatch: Match strings phonetically i.e. u also matches ü.
//                  Note that some providers might not support this
//  bAnyMatch:		Match the given value anywhere in the match string.
//					Note that some providers might not support this
function EKSuggest(oProvider, bTypeAhead, bPhoneticMatch, bAnyMatch)
{   
    // Default values
    this.showItems      = 10;

    this.cur            = -1;
    this.layer          = null;    
    this.iframe         = null;
    this.provider       = oProvider;
    
    this.textbox        = oProvider.suggestionElement();       
     
    this.doTypeAhead      = bTypeAhead;
    this.doPhoneticMatch  = bPhoneticMatch;
	this.doAnyMatch		  = bAnyMatch;
    
    this.keyEvent       = false;
    this.mouseEvent     = false;
	this.IMEEvent		= false;
    
    // Initialize the control
    
    this.init();
}

// EKSuggest.findPos
//      Calculate the position of an element on a page in a cross-browser compatible way
//
//      element:    DOM object to calculate the position of
// 
//      Returns:    Coordinates object containing X and Y position in pixels of the element
EKSuggest.prototype.findPos = function(element)
{
    var coordinates = function() {};
	coordinates.x = 0;
	coordinates.y = 0;
	
	while (element.offsetParent)
	{
		coordinates.x += element.offsetLeft;
		coordinates.y += element.offsetTop;
		
        element = element.offsetParent;
	}
	
	return coordinates;
};

// EKSuggest.autoSuggest
//
// Autosuggests one or more suggestions for what the user has typed.
// If no suggestions are passed in, then no autosuggest occurs.
//
//  aSuggestions:   An array of suggestion strings from the linked provider
//  bTypeAhead:     If the control should provide a type ahead suggestion.
//
EKSuggest.prototype.autosuggest = function(aSuggestions, bTypeAhead) 
{
    // Make sure there is at least one suggestion
    if (aSuggestions.length > 0) {
        if (bTypeAhead) {
           this.typeAhead(aSuggestions[0].text);
        }
        
        this.showSuggestions(aSuggestions);
    } else {
        this.hideSuggestions();
        
        // Clear contents of the layer
		if (this.layer)
			this.layer.innerHTML = "";        
    }
};



// EKSuggest.createDropdown
//
// Initialize the dropdown DIV layer to display multiple suggestions
EKSuggest.prototype.createDropDown = function() 
{
    var oThis, IE6;
    
    oThis = this;

    // Create the layer and assign styles
    this.layer = document.createElement("DIV");
    this.layer.className = "suggestions";
    
    // When the user clicks on the a suggestion, get the text (innerHTML)
    // and place it into a textbox
    this.layer.onmousedown =     
    this.layer.onmouseup = 
    this.layer.onmouseover = function(oEvent) { oEvent = oEvent || window.event; return oThis.handleMouseEvents(oEvent); };
    
    // Detect IE6 and below
    IE6 = false /*@cc_on || @_jscript_version < 5.7 @*/;
    
    if (IE6)
    {
        this.iframe = document.createElement("IFRAME");
        this.iframe.className = "suggestions";
        this.iframe.border = "0";
    
		document.body.appendChild(this.iframe);
    }

	document.body.appendChild(this.layer);
};

// EKSuggest.handleMouseEvents
//
// When the user clicks an item from the list, place it into the input.
// Ignore any scrollbar interaction
//
//  oEvent: The event object for the mouse event.
EKSuggest.prototype.handleMouseEvents = function(oEvent)
{    
    var oTarget = oEvent.target || oEvent.srcElement;
    
    switch (oEvent.type)
    {
        case "mousedown" :  while (oTarget.parentNode != null)
                            {
                                if (oTarget.parentNode.tagName == "DIV" && oTarget.parentNode.className == "suggestions")
                                {
                                    this.textbox.value = oTarget.attributes.getNamedItem("text").nodeValue;
                                    this.hideSuggestions();
                                    this.textbox.focus();                                    
                                    
                                    // Prevent mouse down from bubbling down
                                    // and causing the textbox to lose focus
                                    if ('function' == typeof oEvent.preventDefault)
                                    {
                                        oEvent.preventDefault();
                                    }
                                    else
                                    {
                                        oEvent.returnValue = false;
                                    }
                                    /*AJ Code*/			
			
			                        this.FilterFromTo('ctl00_c_CtWNW_ddlFrom','ctl00_c_CtWNW_ddlTo','ctl00_c_CtWNW_tddTo');			
			                        this.HandleAdvTo();
			                        
			                        /*AJ Code Ends*/    
                                    return false;
                                }

                                oTarget = oTarget.parentNode;
                            }                            
                            
                            // No valid node was picked, make sure we maintain focus
                            this.mouseEvent = true;
                            this.textbox.focus();
                            break;
        case "mouseover" :  if (!this.keyEvent)        
                            {
                                while (oTarget.parentNode != null)
                                {
                                    if (oTarget.parentNode.tagName == "DIV" && oTarget.parentNode.className == "suggestions" && oTarget.className != "separator")
                                    {
                                        this.highlightSuggestion(oTarget);                                        
                                    }

                                    oTarget = oTarget.parentNode;
                                }
                            }
                            break;        
    };
}


//function FilterFromTo(idFrom, idTo)
EKSuggest.prototype.FilterFromTo = function (idFrom, idTo,idTd) 
{   
//    alert(document.getElementById(idFrom).value);
//    alert(document.getElementById(idFrom + '-suggest').value);
//    alert(this.textbox.value);
    // From-Enter - Populate To	    
	if(this.textbox.value!='' && this.textbox.id == idFrom + '-suggest')
	{   
	    From_Enter(idFrom, idTo,idTd);	    
	}		
	// To - Populate Hidden			
	Populate_ToHidden(idTo);		
	// To_Enter		
	
	if(this.textbox.value!='' && this.textbox.id == idTo+'-suggest')	   
	    To_Enter(idFrom, idTo);		
	else if(document.getElementById('ctl00_c_CtSrchPref_preferredConnecting')!=null)
	    IsEkOperated('BAH');

};

EKSuggest.prototype.HandleAdvTo = function () 
{   
    var tabVal = MM_findObj('ctl00_hdnTabValue').value;
	if(this.textbox.id!='ctl00_c_CtWNW_ddlTo10-suggest' && tabVal == 3)
	{   
        var idNum = this.textbox.id.replace('ctl00_c_CtWNW_ddlTo','').replace('-suggest','');
        if(document.getElementById('ctl00_c_CtWNW_ddlTo' + idNum + '-suggest')!=null)
        {   
            var destNum = parseInt(idNum) + 1;
            Populate_ToHidden('ctl00_c_CtWNW_ddlTo' + idNum);
            document.getElementById('ctl00_c_CtWNW_ddlFrom' + destNum ).value = document.getElementById('ctl00_c_CtWNW_ddlTo' + idNum ).value ;
            if(document.getElementById('ctl00_c_CtWNW_ddlTo' + idNum).value!='')
                document.getElementById('ctl00_c_CtWNW_ddlFrom' + destNum + '-suggest').value = document.getElementById('ctl00_c_CtWNW_ddlTo' + idNum + '-suggest').value;
            else
                document.getElementById('ctl00_c_CtWNW_ddlFrom' + destNum + '-suggest').value = departAirport;
            //alert(document.getElementById('ctl00_c_CtWNW_ddlTo' + idNum ).value);
        }    
	}
};

// EKSuggest.handleKeyDown
//
//  oEvent: The event object for the keydown event.
EKSuggest.prototype.handleKeyDown = function (oEvent) 
{
    var sDefault, cSuggestionNodes, oNode;
	
    this.keyEvent = true;
	
    switch (oEvent.keyCode) 
    {
        case 38: // Up arrow
            this.previousSuggestion();
            return false;            
            break;
            
        case 40: // Down arrow 
            this.nextSuggestion();
            return false;
            break;
            
        case 13: // Enter			               
			if (!this.IMEEvent && this.layer && this.layer.childNodes)
			{
			     
				// If there is only 1 result, immediately highlight it
				if (this.layer.childNodes.length == 1)
				{
					this.nextSuggestion();
				}
				else
				{
					cSuggestionNodes = this.layer.childNodes;

					if (this.cur >= 0 && cSuggestionNodes.length > 0 && this.cur < cSuggestionNodes.length)
					{
						oNode = cSuggestionNodes[this.cur];
						this.textbox.value = oNode.attributes.getNamedItem("text").nodeValue;
					}
					else
						this.textbox.value = this.provider.defaultValue();
				}
			
				this.hideSuggestions();
				
				// Blur to parse the new value
				this.textbox.blur();
				
				/*AJ Code*/
		        this.FilterFromTo('ctl00_c_CtWNW_ddlFrom','ctl00_c_CtWNW_ddlTo','ctl00_c_CtWNW_tddTo');			
		        this.HandleAdvTo();
		        				
				this.FilterFromTo('ctl00_c_CtrlSrchFlWgt_ddlFrom','ctl00_c_CtrlSrchFlWgt_ddlTo','ctl00_c_CtrlSrchFlWgt_tddTo');			
				/*AJ Code Ends*/
				// Re-focus to not disturb the tab order
				this.textbox.focus();
			}			
			
			
			return false;
            break;            
			
        case 27: // Escape
            this.hideSuggestions();
            
            sDefault = this.provider.defaultValue();
            
            // Request the default value from the provider
            this.textbox.value = sDefault;
            
            // Select the full text so the user can immediately type
            this.selectRange(0, sDefault.length);
            
            return false;
            break;
		case 229: // IME Event
			this.IMEEvent = true;
			break;
		
		    
    }
};

// EKSuggest.handleKeyUp
//
// oEvent: The event object for the keyup event.
EKSuggest.prototype.handleKeyUp = function(oEvent)
{
    this.keyEvent = false;

    var iKeyCode = oEvent.keyCode;
	
    // For backspace (8) and delete (46), shows suggestions without typeahead
    if (iKeyCode == 8 || iKeyCode == 46) 
    {        
        this.provider.resetSuggestionCache();
        this.provider.requestSuggestions(this, false, this.doPhoneticMatch, this.doAnyMatch);
    }
    // For arrow left (37) and arrow right (39), reset the suggestion cache to prevent
    // problems with inserting characters
    else if (iKeyCode == 37 || iKeyCode == 39)
    {
        this.provider.resetSuggestionCache();
    }
	// Handle enter (13) for entering data using the Microsoft IME (Unicode) interface)
	else if (iKeyCode == 13)
	{
		if (this.IMEEvent)
		{
			// Request suggestions from the suggestion provider with typeahead
			this.provider.requestSuggestions(this, this.doTypeAhead, this.doPhoneticMatch, this.doAnyMatch);
		}
		
		this.IMEEvent = false;
		
		return false;
	}
    // Ignore non-character keys
    else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123)) 
    {
        // No action
    }
    else 
    {
        // Request suggestions from the suggestion provider with typeahead
        this.provider.requestSuggestions(this, this.doTypeAhead, this.doPhoneticMatch, this.doAnyMatch);
    }
};

// EKSuggest.handleBlur
//
// oEvent: The event object for the blur event.
EKSuggest.prototype.handleBlur = function(oEvent)
{
    if (!this.mouseEvent)
    {
        this.hideSuggestions();
    
        // If there is only 1 result, immediately highlight it
        if (this.layer && this.layer.childNodes && this.layer.childNodes.length == 1)
        {
            this.nextSuggestion();
        }
           
        if (!this.provider.validateValue())
        {        
            // Request the default value from the provider
            this.textbox.value = this.provider.defaultValue();
        }        
        /*AJ Code*/
        
        
        this.FilterFromTo('ctl00_c_CtWNW_ddlFrom','ctl00_c_CtWNW_ddlTo','ctl00_c_CtWNW_tddTo');			        
        this.HandleAdvTo();        
        EmptyToFromFrom('ctl00_c_CtrlCUGOWgt_ddlFrom','ctl00_c_CtrlCUGOWgt_ddlTo',arrivalAirport);
        /*AJ Code Ends*/
    }
    
    this.mouseEvent = false;        
}

// EKSuggest.handleFocus
//
// oEvent: The event object for the focus event.
EKSuggest.prototype.handleFocus = function(oEvent)
{
    if (!this.mouseEvent)
    {
        // If the value is not a valid selection, supply an empty input
        if (!this.provider.validateValue())
        {
            this.provider.resetSuggestionCache();
            this.clearValue();
        }
    }
    else
    {
        // Ensure IE sets the caret position to the end
        this.textbox.value = this.textbox.value;        
    }
}

// EKSuggest.hideSuggestions
// 
// Hides the suggestion dropdown.
EKSuggest.prototype.hideSuggestions = function() 
{
    // Reset the cache for a new search
    this.provider.resetSuggestionCache();

	if (this.layer)
	{
		this.layer.style.display = "none";
    
		// Reset the height to prevent the layer from overlapping inputs in Firefox 2.x
		this.layer.style.height = "0px"
    
		if (this.iframe)
			this.iframe.style.display = "none";
	}
};

// EKSuggest.clearValue
//
// Clear existing text 
EKSuggest.prototype.clearValue = function()
{
    this.textbox.value = "";
};

// Highlights the given node in the suggestions dropdown, deselecting the previous highlighted node
//
// oSuggestionNode: The node representing a suggestion in the dropdown.
EKSuggest.prototype.highlightSuggestion = function(oSuggestionNode) 
{
    var i, length, oNode;

    for (i = 0, length = this.layer.childNodes.length; i < length; i++) 
    {
        oNode = this.layer.childNodes[i];
        
        if (oNode == oSuggestionNode && oNode.className != "separator") 
        {
            oNode.className = "current"
        }
        else if (oNode.className == "current") 
        {
            oNode.className = "";
        }
    }
};

// EKSuggest.init
//
// Initializes the textbox with event handlers for auto suggest functionality.
EKSuggest.prototype.init = function() 
{
    // Get a reference to the current instance
    var oThis = this;

    if (this.textbox)
    {
        // Assign the events to the input textbox
        this.textbox.onkeyup = function(oEvent) { oEvent = oEvent || window.event; return oThis.handleKeyUp(oEvent); };
        this.textbox.onkeydown = function(oEvent) { oEvent = oEvent || window.event; return oThis.handleKeyDown(oEvent); };
        this.textbox.onblur = function(oEvent) { oEvent = oEvent || window.event; return oThis.handleBlur(oEvent); };
        this.textbox.onfocus = function(oEvent) { oEvent = oEvent || window.event; return oThis.handleFocus(oEvent); };
    }
};

// EKSuggest.nextSuggestion
//
// Highlights the next suggestion in the dropdown and places the suggestion into the textbox.
EKSuggest.prototype.nextSuggestion = function()
{
    if (this.layer && this.layer.childNodes)
    {
        var cSuggestionNodes, oNode;

        cSuggestionNodes = this.layer.childNodes;

        if (cSuggestionNodes.length > 0 && this.cur < cSuggestionNodes.length - 1)
        {
            oNode = cSuggestionNodes[++this.cur];
    		
		    if (oNode.className == "separator" && this.cur < cSuggestionNodes.length - 1)
			    oNode = cSuggestionNodes[++this.cur];
            
            this.highlightSuggestion(oNode);
		    this.ensureVisible(oNode);
            this.textbox.value = oNode.attributes.getNamedItem("text").nodeValue;
        }
    }        
};

// EKSuggest.previousSuggestion
//
// Highlights the previous suggestion in the dropdown and places the suggestion into the textbox.
EKSuggest.prototype.previousSuggestion = function()
{
    if (this.layer && this.layer.childNodes)
    {
        var cSuggestionNodes, oNode;

        cSuggestionNodes = this.layer.childNodes;

        if (cSuggestionNodes.length > 0 && this.cur > 0) 
        {
            oNode = cSuggestionNodes[--this.cur];
    		
		    if (oNode.className == "separator" && this.cur > 0)
			    oNode = cSuggestionNodes[--this.cur];
    		        
            this.highlightSuggestion(oNode);
		    this.ensureVisible(oNode);
            this.textbox.value = oNode.attributes.getNamedItem("text").nodeValue;
        }
    }        
};

// EKSuggest.ensureVisible
//
// Ensures the current node is visible within the suggestion layer
//
// oNode: Node to ensure visibility of
EKSuggest.prototype.ensureVisible = function(oNode)
{
	var oItem, iOffset;
	
	iOffset = 0;
	oItem = oNode;
	
	// Calculate the offset of the current node in the list
	while (oItem.previousSibling != null)
	{
		iOffset += oItem.offsetHeight;
		oItem = oItem.previousSibling;		
	}
	
	iOffset += oItem.offsetHeight;
	
	// Check if the curret node is out of the visible area on the top
	if (iOffset < (this.layer.scrollTop + 2))
	{
		this.layer.scrollTop = iOffset - oNode.offsetHeight;
	}
	
	// Check if the current node is out of the visible area on the bottom
	if ((iOffset - this.layer.scrollTop) > this.layer.offsetHeight)
	{
		this.layer.scrollTop += (oNode.offsetHeight + 2);
	}	
}

// EKSuggest.selectRange
//
// Selects a range of text in the textbox.
//
// iStart:  The start index (base 0) of the selection.
// iLength: The number of characters to select.
EKSuggest.prototype.selectRange = function (iStart, iLength) 
{
    var oRange;

    // Text ranges for Internet Explorer
    if (this.textbox.createTextRange) 
    {
        oRange = this.textbox.createTextRange(); 
        oRange.moveStart("character", iStart); 
        oRange.moveEnd("character", iLength - this.textbox.value.length);      
        oRange.select();
        
    // Use setSelectionRange() for compliant browsers
    } 
    else if (this.textbox.setSelectionRange) 
    {
        this.textbox.setSelectionRange(iStart, iLength);
    }     

    // Set focus back to the textbox
    this.textbox.focus();
};

// EKSuggest.showSuggestions
//
// Builds the suggestion layer contents, moves it into position, and displays the layer.
//
// aSuggestions:    An array of suggestions for the control.
EKSuggest.prototype.showSuggestions = function (aSuggestions) 
{
    var oDiv, oAttr, i, length, iCount, pos, height;

    oDiv = null;
	
	// Initialize the layer if it has not been previously initialized
	if (!this.layer)
	{
		// Create the suggestions dropdown
		this.createDropDown();	
	}
    
    // Clear contents of the layer
    this.layer.innerHTML = "";  
    
    for (i = 0, length = aSuggestions.length; i < length; i++) 
    {
        oDiv = document.createElement("DIV");

		// Check if this is a seperator, if so set a CSS class
		if (aSuggestions[i].value == "---")
		{
			// Prevent bug with Internet Explorer 6
			oDiv.innerHTML = "<hr />";
			
			oAttr = document.createAttribute("class");
			oAttr.value = "separator";
			oDiv.attributes.setNamedItem(oAttr);
		}
		else
		{
			oDiv.innerHTML = aSuggestions[i].display;
                
			oAttr = document.createAttribute("text");
			oAttr.value = aSuggestions[i].text
			oDiv.attributes.setNamedItem(oAttr);			
		}
	
        this.layer.appendChild(oDiv);
    }
    
    // Reset the current selection
    this.cur = -1;

    // Maximum amount of items visible without scrollbar
    iCount = aSuggestions.length > this.showItems ? this.showItems : aSuggestions.length;
    
    if (this.iframe)
    {
        this.iframe.style.zIndex = -1000;
        this.iframe.style.display = "block";
        
    }
    
    this.layer.style.zIndex = -900;
    this.layer.style.display = "block";
        
    var height = 3;
    
    for (i = 0; i < iCount; i++)
    {
        height += this.layer.childNodes[i].offsetHeight;
		
		if (this.layer.childNodes[i].className == "separator")
			height += 5;
    }

    this.layer.style.width = this.textbox.offsetWidth + "px";
    this.layer.style.height = height + "px";	
	
	// Position the layer
	pos = this.findPos(this.textbox);
	
    this.layer.style.top = (pos.y + this.textbox.offsetHeight) + "px";
	this.layer.style.left  = pos.x + "px";
	this.layer.style.zIndex = 1000;

	if (this.iframe)
    {
		this.layer.style.width = this.textbox.offsetWidth - 3 + "px";
    
        this.iframe.style.left  = this.layer.style.left;
        this.iframe.style.top   = this.layer.style.top;
        this.iframe.style.width = this.layer.style.width;
        this.iframe.style.height = this.layer.style.height;
        this.iframe.style.zIndex = 900;
    }
    
/*	
    var coord = this.findPos(this.layer);
    var scroll = this.getScrollPosition();    
    var size = this.getWindowSize();
    
    var ourLeft = coord.x;  
    var ourTop = coord.y + this.layer.offsetHeight;
 
    // If we are out of view vertically, scroll it into view
    if (ourTop > (scroll.y + size.height))
    {        
        window.scrollTo(scroll.x, (ourTop - size.height) + 10);
    }
*/	
};

// EKSuggest.typeAhead
//
// Inserts a suggestion into the textbox, highlighting the suggested part of the text.
//
// sSuggestion: The suggestion for the textbox.
EKSuggest.prototype.typeAhead = function (sSuggestion) 
{
    var iLen;

    // Check for support of typeahead functionality
    if (this.textbox.createTextRange || this.textbox.setSelectionRange)
    {
        iLen = this.textbox.value.length; 
        this.textbox.value = sSuggestion; 
        this.selectRange(iLen, sSuggestion.length);
    }
};

// EKSuggest.getScrollPosition
//      Calculate the scroll position of the browsers scrollbar in a cross-browser compatible way
//
//      Returns:    Coordinates object containing the X and Y positions of both scrollbars in pixels.
EKSuggest.prototype.getScrollPosition = function()
{
    var coordinates = function() {};
    coordinates.x = 0;
    coordinates.y = 0;

    if (typeof(window.pageYOffset) == "number")
    {
        // Mozilla (and compliant) browsers
        coordinates.x = window.pageXOffset;
        coordinates.y = window.pageYOffset;
    } 
    else if (document.body && (document.body.scrollLeft || document.body.scrollTop))
    {
        // DOM compliant
        coordinates.x = document.body.scrollLeft;
        coordinates.y = document.body.scrollTop;        
    } 
    else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop))
    {
        // IE6 standards compliant mode
        coordinates.x = document.documentElement.scrollLeft;
        coordinates.y = document.documentElement.scrollTop;        
    }
    
    return coordinates;
};

// EKSuggest.getWindowSize
//      Calculate the visible window size of a browser in a cross-browser compatible way
//
//      Returns:    Size object containing the width and height of the window in pixels
EKSuggest.prototype.getWindowSize = function()
{
    var size = function() {};
    size.width = 0;
    size.height = 0;
    
    if (typeof( window.innerWidth ) == "number") 
    {
        // Mozilla (and compliant) browsers
        size.width = window.innerWidth;
        size.height = window.innerHeight;
    } 
    else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight))
    {
        //IE 6+ in 'standards compliant mode'
        size.width = document.documentElement.clientWidth;
        size.height = document.documentElement.clientHeight;
    }
    else if (document.body && (document.body.clientWidth || document.body.clientHeight))
    {
        //IE 4 compatible
        size.width = document.body.clientWidth;
        size.height = document.body.clientHeight;
    }
    
    return size;
};


/*****************************************************/
/* EKSuggestData Class                               */
/*****************************************************/

// EKSuggestData
//
// text:    Text to be displayed
// value:   Value to be submitted
// match:   Value to be matched against
function EKSuggestData(text, display, value, match, cleanMatch)
{ 
    this.text = text; 
    this.display = display;
    this.orgDisplay = display;
    this.value = value; 
    this.match = match;
	this.cleanMatch = cleanMatch;
}

// EKSuggestData.toString
//
// Allow JavaScript to convert this object to a string
EKSuggestData.prototype.toString = function()
{
    return this.text;
}

// EKSuggestData.valueOf
//
// Allow JavaScript to obtain the comparison value of this object
EKSuggestData.prototype.valueOf = function()
{
    return this.match;
}

/*****************************************************/
/* EKSuggestProvider Baseclass                       */
/*****************************************************/

// EKSuggestProvider
//
// Initialize the suggestion provider
//
// oElement: HTML Element to replace with the suggestion box
function EKSuggestProvider(oElement, sDefaultValue)
{   
    var aLabels, i, length;
	
    if (!oElement)
        return;    
    this.defaultVal = sDefaultValue;
    
    // Replace the given element with our own HTML INPUT element
    this.suggestElement = document.createElement("INPUT");
    this.suggestElement.type = "text";
    this.suggestElement.id = oElement.id + "-suggest";        
    this.suggestElement.name = oElement.name + "-suggest";
    this.suggestElement.className = oElement.className;    
    //alert(oElement.width);
    //if(oElement.offsetWidth>=3)
    //   this.suggestElement.style.width= oElement.offsetWidth - 3 + "px";    // Added by AJ    
    this.suggestElement.style.width= comboWidth; //"224px";    // Added by AJ        
    
    this.suggestElement.tabIndex = oElement.tabIndex;
    this.suggestElement.autosuggest = true;
    
    // Disable autocomplete
    this.suggestElement.setAttribute("autocomplete", "off");
    
    this.suggestElement.value = this.defaultVal;
    
    //alert(document.getElementById('ctl00_c_CtWNW_ddlTo').value);
    
    // Create a hidden HTML input element for submitting the selected value
    this.submitElement = document.createElement("INPUT");
    this.submitElement.type = "hidden";
    this.submitElement.id = oElement.id;
    this.submitElement.name = oElement.name;
    this.submitElement.value = "";
    
    // Build the initial suggestion cache
    this.resetSuggestionCache();    
    // Replace the existing HTML element in the DOM hierarchy    
    oElement.parentNode.replaceChild(this.suggestElement, oElement);    
    this.suggestElement.parentNode.insertBefore(this.submitElement, this.suggestElement);
	
	// Update any labels pointing to the old element
	var aLabels = document.getElementsByTagName("LABEL");
	
	if (aLabels.length > 0)
	{
		for (i = 0, length = aLabels.length; i < length; i++)
		{
				if (aLabels[i].htmlFor == oElement.id)
				{
					aLabels[i].htmlFor = this.suggestElement.id;
				}			
		}
	}
}

// EKSuggestProvider.suggestionElement
//
// Retrieve the HTML input element used to display suggestions in
EKSuggestProvider.prototype.suggestionElement = function()
{
    return this.suggestElement;
}

// EKSuggestProvider.submitInput
//
// Retrieve the HTML input element used to submit the actual value
EKSuggestProvider.prototype.submitInput = function()
{
    return this.submitElement;
}

// EKSuggestProvider.defaultValue
//
// Retrieve the default value to be displayed in the suggestion element
EKSuggestProvider.prototype.defaultValue = function()
{
    return this.defaultVal;
}

// EKSuggestProvider.validateValue
//
// Validate the current value of the suggestion element
EKSuggestProvider.prototype.validateValue = function()
{
    var i, length;

    for (i = 0, length = this.suggestCache.length; i < length; i++)
    {
        if (this.suggestElement.value == this.suggestCache[i].text)
        {
            if (this.submitElement.value != this.suggestCache[i].value)
            {
                this.submitElement.value = this.suggestCache[i].value;
                
                if (this.submitElement.onChange)
                    this.submitElement.onChange();                
            }
                    
            return true;
        }
    }
   
    this.submitElement.value = "";
    return false;
}

// EKSuggestProvider.resetSuggestionCache
//
// Reset the suggestion cache to start a new or widen an existing search
EKSuggestProvider.prototype.resetSuggestionCache = function()
{
    var i, length;

    // Create an independent array copy
    this.suggestCache = new Array();
    
    for (i = 0, length = this.suggestData.length; i < length; i++)
    {
        this.suggestCache[i] = this.suggestData[i];
    }
}

// EKSuggestProvider.requestSuggestions
//
// Request suggestions for the given autosuggest control. 
//
// oAutoSuggestControl: The autosuggest control to provide suggestions for.
// bTypeAhead:          AutoComplete typed values automatically, matching always begins from start of string
//                      Note that some providers might not support this
// bPhoneticMatch:      Match strings phonetically i.e. u also matches ü.
//                      Note that some providers might not support this
// bAnyMatch:			Match the given value anywhere in the match string.
//						Note that some providers might not support this
EKSuggestProvider.prototype.requestSuggestions = function (oSuggestControl, bTypeAhead, bPhoneticMatch, bAnyMatch) 
{
    var aSuggestions, iCount, sValue, oSuggestion, oRegExp, i, length, sDisplay, oRegCSS;   
    aSuggestions = new Array();
        
    if (this.suggestElement.value.length > 0)
    {    
        iCount = 0;
        
		sValue = this.prepareSearchValue(this.suggestElement.value.toLowerCase(), bPhoneticMatch);
		
        // When doing type ahead, match only from string start
        if (bTypeAhead)
            sValue = "^" + sValue;

		// Default behaviour
		if (!bAnyMatch && !bTypeAhead)
		{
			// Case-insensitive text or value starting match
			oRegExp = new RegExp("^" + sValue + "|(\\(" + sValue + ")", "i");
		}
		// Match any data or type ahead
		else
		{
			oRegExp = new RegExp(sValue + "(\|)", "i");
		}
        
		// Apply the CSS class to the value if present in the string 
		oRegCSS = new RegExp("(\\(.*?\\))", "i");
		
        // Search for matching suggestion data (starting at the suggestion data offset)
        for (i = 0, length = this.suggestCache.length; i < length; i++)
        {                 
            sMatch = this.suggestCache[i].match;
        
            if (sMatch.match(oRegExp) != null)
            {                   
                aSuggestions[iCount] = this.suggestCache[i];
				oSuggestion = aSuggestions[iCount];
                
                sDisplay = oSuggestion.orgDisplay;
                
				// Bold any matched data in the display string
				sDisplay = sDisplay.replace(oRegExp, "<b>$1$2</b>");
				
				// Apply CSS class to the airport code
				sDisplay = sDisplay.replace(oRegCSS, "<span>$1</span>");

                oSuggestion.display = sDisplay;
                
                iCount++;
            }
        }
        
        // Update the cache with the new (narrowed) search results
        this.suggestCache = aSuggestions;
    }
    
    // Provide suggestions to the control
    oSuggestControl.autosuggest(aSuggestions, bTypeAhead);
};

// EKSuggestProvider.prepareSearchValue
//
// Format the given search value for use in regular expressions
//
// bPhoneticMatch:      Match strings phonetically i.e. u also matches ü.
//                      Note that some providers might not support this
EKSuggestProvider.prototype.prepareSearchValue = function(sValue, bPhoneticMatch)
{	
    // Escape any magic regular expression characters
    sValue = sValue.replace(/([\.\^\$\*\+\?\{\}\\\[\]\|\(\)])/gi, "\\$1");
        
	// When doing phonetic match, replace extended character with grouped matches
	if (bPhoneticMatch)
	{        
		sValue = sValue.replace(/a/gi, "[aàáâãäå]");
		sValue = sValue.replace(/u/gi, "[uùúûü]");
		sValue = sValue.replace(/e/gi, "[eèéêë]");
		sValue = sValue.replace(/i/gi, "[iìíîï]");
		sValue = sValue.replace(/n/gi, "[nñ]");
		sValue = sValue.replace(/c/gi, "[cç]");     
		sValue = sValue.replace(/b/gi, "[bß]");
		sValue = sValue.replace(/s/gi, "[sß]");
	}
    
	// Apply result grouping
	return sValue = "(" + sValue + ")";
}

/*****************************************************/
/* EKDropdownProvider Class                          */
/*****************************************************/

// EKDropdownProvider
//
// Provides suggestions for pre-populated dropdowns
//
// oDropdown:   Existing HTML select element to supply auto-suggestion for
// sDefault:    Default text to display
function EKDropdownProvider(oDropdown, sDefault)
{
    
    //alert(oDropdown.options.length);
    var iCount, i, length, option;
    
    if (!oDropdown || !oDropdown.options || oDropdown.options.length == 0)
        return;
    
    this.suggestData = new Array();
    
    // Skip the first item by default
    iCount = 1;
    
    // Scan the first 10 items for a disabled item offset
    for (i = 1, length = oDropdown.options.length; i < 15 && i < length; i++)
    {
        if (oDropdown.options[i].value == "")
        {
            iCount = i + 1;
            break;
        }
    }
    
    for (i = iCount, length = oDropdown.options.length; i < length; i++)
    {
        option = oDropdown.options[i];            
        this.suggestData[i - iCount] = new EKSuggestData(option.text, option.text, option.value, option.text, option.text);
    }    
    
    // Call the inherited class
    EKSuggestProvider.call(this, oDropdown, sDefault);
    
    
    // If a previously selected value is returned, pre-select it
    if (oDropdown.selectedIndex > 0)
    {   
        option = oDropdown.options[oDropdown.selectedIndex];
        this.suggestElement.value = option.text;
        this.submitElement.value = option.value;    
    }
    //alert('Options Printing - EKDropdownProvider - Ending')
    //alert(oDropdown.options.length);
    //alert('testing a thing');//AJ
}

// Inherit from EKSuggestProvider
EKDropdownProvider.prototype = new EKSuggestProvider();
EKDropdownProvider.prototype.constructor = EKDropdownProvider;

/*****************************************************/
/* EKDropdownFilterProvider Class                    */
/*****************************************************/

// EKDropdownFilterProvider
//
// Provides suggestions for pre-populated dropdowns while filtering against 
// a XML HTTP query
//
// oDropdown:   Existing HTML select element to attach to
// sDefault:    Default text to display
// oFilter:     HTML input element to filter against using XML HTTP
// sQuery:      XML HTTP query url to append the current filter to
function EKDropdownFilterProvider(oDropdown, sDefault, oFilter, sQuery)
{
    var oThis;
    
    if (!oDropdown)
        return;

    this.filterElement = oFilter;
    this.triggerElement = oTrigger;
    this.filterUrl = sQuery;
    this.filter = null;
    this.oldFilter = "";
        
    oThis = this;

    // Register an onChange handler for the filter element    
    this.filterElement.onChange = function() { oThis.triggerChange(); };
    
    // XMLHTTP Object to retrieve filter results
    this.XMLHTTP = this.createXMLHttpRequest();
    
    // Call the inherited class
    EKDropdownProvider.call(this, oDropdown, sDefault);
}

// Inherit from EKDropdownProvider
EKDropdownFilterProvider.prototype = new EKDropdownProvider();
EKDropdownFilterProvider.prototype.constructor = EKDropdownFilterProvider;

// EKDropdownFilterProvider.CreateXMLHttpRequest
//
//  Create a XMLHttpRequest object in a cross-browser compatible manner by falling back to different factories.
//
//  Returns: Instantiated XMLHttpRequest, in case of error a JavaScript exception is thrown.
EKDropdownFilterProvider.prototype.createXMLHttpRequest = function()
{
    if (typeof XMLHttpRequest != "undefined") 
    {
        return new XMLHttpRequest();
    }
    else if (typeof ActiveXObject != "undefined") 
    {
        return new ActiveXObject("Microsoft.XMLHTTP");
    }
    else 
    {
        throw new Error("XMLHttpRequest not supported");
    }
}

// EKDropdownFilterProvider.handleXMLRequest
//
// onreadystatechange event handler for the XML request
EKDropdownFilterProvider.prototype.handleXMLRequest = function()
{
    if (this.XMLHTTP.readyState == 4)
    {
        try
        {
            if (this.XMLHTTP.status == 200)
            {
                this.resetSuggestionCache(this.XMLHTTP.responseText);
            }
            else
            {
                this.resetSuggestionCache();
            }
        }
        catch (err)
        {
            this.resetSuggestionCache();
        }
    }
}

// EKDropdownFilterProvider.triggerChange
//
// Event handler for tracking changes in the filter HTML element
EKDropdownFilterProvider.prototype.triggerChange = function()
{
    var oThis;

    // Check if a new filter value has to be parsed
    if (this.filterElement.value != "" && this.filterElement.value != this.oldFilter)
    {
        this.suggestionElement().readOnly = true;
    
        this.XMLHTTP.open("GET", this.filterUrl + this.filterElement.value, true);
        
        // Register onreadystatechange handler after every open
        // this is required for Internet Explorer
        oThis = this;
        this.XMLHTTP.onreadystatechange = function() { oThis.handleXMLRequest(); };
        
        this.XMLHTTP.send(null);
        
        // Update the last queried filter
        this.oldFilter = this.filterElement.value;
    }
}

// EKDropdownFilterProvider.resetSuggestionCache
//
// Reset the suggestion cache to start a new or widen an existing search
EKDropdownFilterProvider.prototype.resetSuggestionCache = function(sFilter)
{
    var iCount, i, length;

    // Track the last filter result
    if (sFilter)
    {
        this.filter = sFilter;    
    }
    
    // Create an independent array copy
    this.suggestCache = new Array();
    iCount = 0;
    
    for (i = 0, length = this.suggestData.length; i < length; i++)
    {
        // Insert only elements which are in the retrieved filter
        if (this.oldFilter == "" || !this.filter || this.filter.search(this.suggestData[i].value) != -1)
        {
            this.suggestCache[iCount] = this.suggestData[i];
            iCount++;
        }
    }
    
    // Re-enable the suggestion element, in case we were called by a filter query result
    this.suggestionElement().readOnly = false;    
}

/*****************************************************/
/* EKXMLProvider Class                               */
/*****************************************************/

// EKXMLProvider
//
// Provides suggestions based on a XML document
//
// oDropdown:   Existing HTML select element to replace
// sDefault:    Default text to display
// sXML:        XML document url
function EKXMLProvider(oDropdown, sDefault, sXML)
{
    var oXMLHTTP, i, length, oData, sValue, sDisplay, sName, sMatch, oRegExp;
    
    if (!oDropdown)
        return;

    this.documentUrl = sXML;
    
    // XMLHTTP Object to retrieve the xml document
    oXMLHTTP = this.createXMLHttpRequest();
    
    oXMLHTTP.open("GET", this.documentUrl, false);
    oXMLHTTP.send(null);
    
    oData = oXMLHTTP.responseXML.documentElement.childNodes;
    
    this.suggestData = new Array();

	// Filter out all 2 and 3 letter codes (airport, city, country)
	oRegExp = new RegExp("\\s+\\(\\w{2,3}\\)", "gi");
	    
    for (i = 0, length = oData.length; i < length; i++)
    {
        sValue = oData[i].attributes.getNamedItem("v").value;
        sDisplay = oData[i].attributes.getNamedItem("d").value;
        sName = oData[i].attributes.getNamedItem("n").value;
        sMatch = oData[i].attributes.getNamedItem("m").value;
		
        this.suggestData[i] = new EKSuggestData(sName + " (" + sValue + ")", sDisplay, sValue, sMatch, sMatch.replace(oRegExp, ""));
    }

    // Call the inherited class
    EKSuggestProvider.call(this, oDropdown, sDefault);
}

// Inherit from EKDropdownProvider
EKXMLProvider.prototype = new EKSuggestProvider();
EKXMLProvider.prototype.constructor = EKXMLProvider;

// EKXMLProvider.CreateXMLHttpRequest
//
//  Create a XMLHttpRequest object in a cross-browser compatible manner by falling back to different factories.
//
//  Returns: Instantiated XMLHttpRequest, in case of error a JavaScript exception is thrown.
EKXMLProvider.prototype.createXMLHttpRequest = function()
{
    if (typeof XMLHttpRequest != "undefined") 
    {
        return new XMLHttpRequest();
    }
    else if (typeof ActiveXObject != "undefined") 
    {
        return new ActiveXObject("Microsoft.XMLHTTP");
    }
    else 
    {
        throw new Error("XMLHttpRequest not supported");
    }
}

// EKXMLProvider.requestSuggestions
//
// Request suggestions for the given autosuggest control. 
//
// oAutoSuggestControl: The autosuggest control to provide suggestions for.
// bTypeAhead:          AutoComplete typed values automatically, matching always begins from start of string
//                      Note that some providers might not support this
// bPhoneticMatch:      Match strings phonetically i.e. u also matches ü.
//                      Note that some providers might not support this
// bAnyMatch:			Match the given value anywhere in the match string.
//						Note that some providers might not support this
EKXMLProvider.prototype.requestSuggestions = function (oSuggestControl, bTypeAhead, bPhoneticMatch, bAnyMatch) 
{
    var aSuggestions, iStartMatch, iAnyMatch, oSuggestion, sValue, oRegExpText, oRegExpCode, oRegExpAll, i, length, sDisplay, oRegCSS;

    aSuggestions = new Array();
        
    if (this.suggestElement.value.length > 0)
    {    
        iStartMatch = 0;
		iAnyMatch = 0;

		sValue = this.prepareSearchValue(this.suggestElement.value.toLowerCase(), bPhoneticMatch);
		
		// Type ahead and any match are mutually exclusive
		if (bTypeAhead && !bAnyMatch)
		{
			oRegExpText = new RegExp("^" + sValue + "(\|)", "i");
		}
		else
		{
			// Case-insensitive text or value starting match
			oRegExpText = new RegExp("^" + sValue + "|(\\(" + sValue + ")", "i");
		}
		
		// Case-insensitive match against any code (airport, city and country code)
 		oRegExpCode = new RegExp("\\|(.*?\\((" + sValue + ")\\w{0,2}\\))\\|", "gi");
		
		// Case-insensitive match anywhere in string (except airport, city and country codes)
		oRegExpAll = new RegExp(sValue, "gi");
		
		// Apply the CSS class to the value if present in the string 
		oRegCSS = new RegExp("(\\(.*?\\))", "i");

		// First match against all textual values starting from the beginning of the string or against the airport code
		for (i = 0, length = this.suggestCache.length; i < length; i++)
		{
			oSuggestion = null;
		
			// Match  against the text start or value start
			if (this.suggestCache[i].text.match(oRegExpText) != null)
			{
				aSuggestions.splice(iStartMatch, 0, this.suggestCache[i]);
				oSuggestion = aSuggestions[iStartMatch];

				sDisplay = oSuggestion.text;

				// Bold any matched data in the display string
				sDisplay = sDisplay.replace(oRegExpText, "<b>$1$2</b>");
				
				// Apply CSS class to the airport code
				sDisplay = sDisplay.replace(oRegCSS, "<span>$1</span>");
				
				oSuggestion.display = sDisplay;

				iStartMatch++;
			}
			// Match on any airport, city or country code if Any Match is enabled
			else if (this.suggestCache[i].match.match(oRegExpCode) != null && bAnyMatch)
			{
				aSuggestions[iStartMatch + iAnyMatch] = this.suggestCache[i];
				oSuggestion = aSuggestions[iStartMatch + iAnyMatch];				
				sDisplay = oSuggestion.text;
				
				// Apply CSS class to the airport code
				sDisplay = sDisplay.replace(oRegCSS, "<span>$1</span>");
								
				oSuggestion.display = this.formatDisplay(sValue, sDisplay, this.suggestCache[i].match, oRegExpAll);
				
				iAnyMatch++;
			}
			// Match on any text in the long match description if Any Match is enabled
			else if (this.suggestCache[i].cleanMatch.match(oRegExpAll) != null && bAnyMatch)
			{
				aSuggestions[iStartMatch + iAnyMatch] = this.suggestCache[i];
				oSuggestion = aSuggestions[iStartMatch + iAnyMatch];
				sDisplay = oSuggestion.text;
				
				// Apply CSS class to the airport code
				sDisplay = sDisplay.replace(oRegCSS, "<span>$1</span>");

				oSuggestion.display = this.formatDisplay(sValue, sDisplay, this.suggestCache[i].match, oRegExpAll);

				iAnyMatch++;
			}
		}
		
        // If there is only 1 suggestion show the full data
        if (aSuggestions.length == 1)
        {
            aSuggestions[0].display = aSuggestions[0].orgDisplay;                    
        }
		
		// If there were any matches in the second set, add a separator
		if (aSuggestions.length > 1 && iAnyMatch > 0 && iStartMatch > 0)
		{	
			// Add a separator between the initial matches and the any matches
			aSuggestions.splice(iStartMatch, 0, new EKSuggestData("", "", "---", "", ""));
		}

		// EKXMLProvider *cannot* provider narrowing performance caching as it changes the sort order of the results
        // Update the cache with the new (narrowed) search results
        //this.suggestCache = aSuggestions;
    }
    
    // Provide suggestions to the control
    oSuggestControl.autosuggest(aSuggestions, bTypeAhead && !bAnyMatch);
};

// EKXMLProvider.formatDisplay
//
// Formats the matching data string for the current entry
//
// sValue: Value searched for which matches the current match string
// sText:  Text display for the current entry
// sMatch:  Match string to highlight data from
// oRegHighlight: Highlight the search string in the result
EKXMLProvider.prototype.formatDisplay = function(sValue, sText, sMatch, oRegHighlight)
{
	var oRegMatch, oMatch;

	oRegMatch = new RegExp("\\|(.*?" + sValue + ".*?)\\|", "i");
	oMatch = sMatch.match(oRegMatch);
	
	if (oMatch != null && oMatch.length > 0)
	{
	   sDispMatch = oMatch[1];
	   
	   // Obtain the last valid match entry to append
	   if (sDispMatch.indexOf("|") != -1 )
	   {
			aDispMatch = sDispMatch.split("|");
			sDispMatch = aDispMatch[aDispMatch.length - 1];			
	   }
	   
	   return sText + ", <i>" + sDispMatch.replace(oRegHighlight, "<b>$1</b>") + "</i>";	   
	}
}

/*****************************************************/
/* EKXMLFilterProvider Class                         */
/*****************************************************/

// EKXMLFilterProvider
//
// Provides suggestions based on a XML document while filtering against 
// a XML HTTP query
//
// oDropdown:   Existing HTML select element to attach to
// sDefault:    Default text to display
// oFilter:     HTML input element to filter against using XML HTTP
// sXML:        XML document url
// sQuery:      XML HTTP query url to append the current filter to
function EKXMLFilterProvider(oDropdown, sDefault, oFilter, sXML, sQuery)
{
    var oThis;
    
    if (!oDropdown)
        return;

    this.filterElement = oFilter;
    this.filterUrl = sQuery;
    this.filter = null;
    this.oldFilter = "";
    
    oThis = this;    
    
    // Register an onChange handler for the filter element    
    this.filterElement.onChange = function() { oThis.triggerChange(); };
    
    // XMLHTTP object to retrieve filter results
    this.XMLHTTP = this.createXMLHttpRequest();

    this.XMLHTTP.onreadystatechange = function() { oThis.handleXMLRequest(); };
    
    // Call the inherited class
    EKXMLProvider.call(this, oDropdown, sDefault, sXML);
}

// Inherit from EKXMLProvider
EKXMLFilterProvider.prototype = new EKXMLProvider();
EKXMLFilterProvider.prototype.constructor = EKXMLFilterProvider;

// EKXMLFilterProvider.handleXMLRequest
//
// onreadystatechange event handler for the XML request
EKXMLFilterProvider.prototype.handleXMLRequest = function()
{
    if (this.XMLHTTP.readyState == 4)
    {
        try
        {
            if (this.XMLHTTP.status == 200)
            {
                this.resetSuggestionCache(this.XMLHTTP.responseText);
            }
            else
            {
                this.resetSuggestionCache();
            }
        }
        catch (err)
        {
            this.resetSuggestionCache();
        }
    }
}

// EKXMLFilterProvider.triggerChange
//
// Event handler for tracking changes in the filter HTML element
EKXMLFilterProvider.prototype.triggerChange = function()
{
    // Check if a new filter value has to be parsed
    if (this.filterElement.value != "" && this.filterElement.value != this.oldFilter)
    {
        this.suggestionElement().readOnly = true;
    
        this.XMLHTTP.open("GET", this.filterUrl + this.filterElement.value, true);
        
        // Register onreadystatechange handler after every open
        // this is required for Internet Explorer
        oThis = this;
        this.XMLHTTP.onreadystatechange = function() { oThis.handleXMLRequest(); };
        
        this.XMLHTTP.send(null);
        
        // Update the last queried filter
        this.oldFilter = this.filterElement.value;
    }
}

// EKXMLFilterProvider.resetSuggestionCache
//
// Reset the suggestion cache to start a new or widen an existing search
EKXMLFilterProvider.prototype.resetSuggestionCache = function(sFilter)
{
    var iCount, i, length;

    // Track the last filter result
    if (sFilter)
    {
        this.filter = sFilter;    
    }
    
    // Create an independent array copy
    this.suggestCache = new Array();
    iCount = 0;
    
    for (i = 0, length = this.suggestData.length; i < length; i++)
    {
        // Insert only elements which are in the retrieved filter
        if (this.oldFilter == "" || !this.filter || this.filter.search(this.suggestData[i].value) != -1)
        {
            this.suggestCache[iCount] = this.suggestData[i];
            iCount++;
        }
    }
    
    // Re-enable the suggestion element, in case we were called by a filter query result
    this.suggestionElement().readOnly = false;
}