
var DoubleEvtForArrow = false;
var UseAppleWebKit = false;
var FireFoxOnMac = false;
var ShownEntries = new Array(MAX_SHOWN);
var KEY_DELIMITER = ',';
var EXCH_DELIMITER = ':';
  
function initCache(m_cache,MyNextCachePos)
{
    for (var i=0; i<m_cache.length; i++) 
    {
        m_cache[i] = null;
        MyNextCachePos[i] = 0;
    }
    //alert('init cache done.');
}

function CheckOSBrowser()
	{  
		   
		    var agent = navigator.userAgent;
		    if (agent != null) 
		    {
		        //alert(agent);
		    	var start = agent.indexOf("AppleWebKit/");
		    	if (start > 0) 
		    	{
		    	   UseAppleWebKit = true;
		    	   var awk_ver = agent.substr(start + 12, 3);
		    	   if (awk_ver < 500) 
		    	   {
		    	   	DoubleEvtForArrow = true;
		    	   }
		    	} else {
		    	    // special handleing needed for firefox on mac
		    	    start = agent.indexOf("Mac OS");
		    	    if (start > 0) {
		    	        start = agent.indexOf("Firefox");
		    	        if (start > 0) {
		    	            FireFoxOnMac = true;
		    	        }
		    	    }
		    	}
		    }
	}
	
function initExchArray()
{
    ExchDisplayArray['NYSE'] = 'NYSE';
    ExchDisplayArray['XNYS'] = 'NYSE';
    ExchDisplayArray['NAS'] = 'Nasdaq';
    ExchDisplayArray['XNAS'] = 'Nasdaq';
    ExchDisplayArray['ASE'] = 'Amex';
    ExchDisplayArray['XASE'] = 'Amex';
    ExchDisplayArray['OTUS'] = 'OTCBB';
    ExchDisplayArray['XOTC'] = 'OTCBB';
    ExchDisplayArray['OTC'] = 'OTC';
    ExchDisplayArray['PINX'] = 'OTC';
    ExchDisplayArray['XLON'] = 'LSE';
    ExchDisplayArray['TSE'] = 'Toronto';
    ExchDisplayArray['XTSE'] = 'Toronto';
    ExchDisplayArray['TSX'] = 'TSX Venture';
    ExchDisplayArray['XTSX'] = 'TSX Venture';
    ExchDisplayArray['XETR'] = 'Xetra';
    ExchDisplayArray['XPAR'] = 'Euronext Paris';
    ExchDisplayArray['XLIS'] = 'Euronext Lisbon';
    ExchDisplayArray['XBRU'] = 'Euronext Brussels';
    ExchDisplayArray['XAMS'] = 'Euronext Amesterdam';    
    ExchDisplayArray['XMLI'] = 'XMLI Paris';
    ExchDisplayArray['XSWX'] = 'SWX';
    ExchDisplayArray['XHKG'] = 'Hong Kong';
    ExchDisplayArray['ALXA'] = 'ALXA Amsterdam';
    ExchDisplayArray['TNLB'] = 'TNLB Brussels';
    ExchDisplayArray['ALXB'] = 'ALXB Brussels';
    ExchDisplayArray['WQXL'] = 'WQXL Lisbon';
    ExchDisplayArray['MLXB'] = 'MLXB Brussels';
    ExchDisplayArray['IXUS'] = 'US Indices';
    ExchDisplayArray['TNLA'] = 'TNLA Amsterdam';
    ExchDisplayArray['XMOD'] = 'Montreal';   
    ExchDisplayArray['ALXP'] = 'ALXP Paris'; 
    ExchDisplayArray['XFRA'] = 'Frankfurt'; 
    ExchDisplayArray['XMIL'] = 'Milan';
    ExchDisplayArray['XMCE'] = 'Madrid';
    ExchDisplayArray['XLAT'] = 'XLAT Madrid';
    ExchDisplayArray['XSHG'] = 'Shanghai';
    ExchDisplayArray['XSHE'] = 'Shenzhen';
    ExchDisplayArray['XSIM'] = 'Singapore';
}

function AutoCompleteBox(InputBoxId, DropdownId,
    MyQuoteServer, 
    //MySearchURL, MyFormId, 
    MyCache, MyNextCachePos, //MySubmitCallback, 
    useAutoPosition)
{   
  var HIDE_DELAY_MS = 200;
  var REFOCUS_DELAY_MS = 50;
  
  var ENTRY_SELECT_COLOR = '#B1D9F0';
  var ENTRY_COLOR = 'white';
	   
  var IgnoreFuncKey = false;
  var IgnoreAppleArrowKey = false;
  
  var NumShownEntries=0;
  var SelectedIndex = -1;
  var Current_Value = '';
  
  var DataPrefix = "ACDEntry_";
  var DPLen =DataPrefix.length;
  
  //var FormId = MyFormId;
  var FormId = null;
  var boxId = InputBoxId;
  var self = this;
  var IsSubmit = true;
  
  var QUOTE_SERVER = 'http://quote.morningstar.com/switch.html?pgid=hetopquote&ticker=';
  //var SearchURL = 'http://search.morningstar.com/MstarSrch/MstarSrch2.aspx?pgid=hetopsearch';
 
   if(MyQuoteServer!=null&&MyQuoteServer.length != 0)
   {
   	  QUOTE_SERVER = MyQuoteServer;
   }
   
//   if(MySearchURL != null&&MySearchURL.length != 0)
//   {
//   	  SearchURL = MySearchURL;
//   }
  
  this.ACINPUT_ID = InputBoxId;
  this.ACDROPDOWN_ID = DropdownId;
   
  this.AutoPosition = useAutoPosition;
  //this.SubmitCallback = MySubmitCallback;
  this.SubmitCallback = null;
  this.EntryChosenCallback = null;
  
  this.IdleDisplayMsg = null;
  this.IdleMsgColor = '#CCCCCC';
  this.FocusMsgColor = '#333333';  	    

  this.ShowAll = null;
  var Oracle = new AutoCompleteOracle(MyCache, MyNextCachePos, boxId, null, this);
//  (function(){
//        var funcString = "AutoCompleteBox.CB"+boxId+" = function(p){this.displayRecord(p);}";
//        eval(funcString);
//    })();
  this.SetACQServer = function(server)
  {
    if (Oracle != null) Oracle.SetACQServer(server);
  }
  this.SetProxyWrap = function(proxy)
  {
    if (Oracle != null)
    {
        Oracle.ProxyWrap = proxy;
    }   
  };	
  function initInputBox(boxId)
	{  	 
	    try 
	    {   
	        //alert('init');
	    	var input_box = document.getElementById(boxId);
	        AutoCompleteBox.addListener(input_box,"keydown",checkFuncKey);
	        AutoCompleteBox.addListener(input_box,"keyup",self.j_sendQuery);
	        
	        // MUST RECOVER, COMMENTED OUT FOR DEBUG ONLY
	        AutoCompleteBox.addListener(input_box,"blur",loseFocus);
	        AutoCompleteBox.addListener(input_box,"focus",getFocus);
	        //alert(FormId);
	        if (FormId != null) {
	        	AutoCompleteBox.addListener(document.getElementById(FormId),"submit",self.trySubmit);
	        }
	        
	        //alert('initInputBox done.');
	    } 
	    catch (ae)
	    {
	    	//alert('exception' + ae);
	    }
	}

  function getFocus()
  {
  	//alert('getfocus');
  	var input_box = document.getElementById(self.ACINPUT_ID);  	
  	if (self.IdleDisplayMsg != null)
  	{
  		if (input_box != null)
  		{
  			if (input_box.value == self.IdleDisplayMsg)
  			{
  				//alert('replace idle msg');
  				input_box.value = '';
  			}
  			//alert('chg color ' + self.FocusMsgColor);
  		}
  	}
  	if (input_box != null) {
  	    input_box.style.color = self.FocusMsgColor;  	
  	}
  };
   
  this.j_sendQuery = function ()
	{ 
	    //debugger;
	    var key = '';
	    var ret = false;
	    
	    //alert(IgnoreFuncKey);
	    if (IgnoreFuncKey) {
	        IgnoreFuncKey = false;
	        return ret;
	    }
	    	    
	    if (IgnoreAppleArrowKey) {
	    	IgnoreAppleArrowKey = false;
	    	return ret;
	    }
	    
        var input_box = document.getElementById(self.ACINPUT_ID);
        key = input_box.value;   
	    key = key.toLowerCase();
	        
	    if (key == Current_Value)
	    {
	        // same value, nothing to be done.
	        return ret; //ret;
	    }
	    	    
	    if (key.length == 0) {
	        Current_Value = "";
	        //self.displayRecord(null);
	        self.ProcessResult(null);
	        SelectedIndex = -1;
	        return ret; // ret;
	    }
	
	
	    Current_Value = key;
	    Oracle.SendQuery(key);
	};
	
	function loseFocus(ev)
	{
	       // must use a timed delay in case the mouse clicked the drop down.
		window.setTimeout(delayedHideDropDown, HIDE_DELAY_MS);
		var input_box = document.getElementById(self.ACINPUT_ID);
		if (input_box != null) {
			input_box.style.color = self.IdleMsgColor;
			if (self.IdleDisplayMsg != null) {
				var tmp_str = input_box.value;
				if (tmp_str != null) {
					tmp_str = leftTrim(tmp_str);
				}
				if (tmp_str.length == 0)
				{
					input_box.value = self.IdleDisplayMsg;
				}	
			}
		}
	}
	
	function checkFuncKey(kp)
	{  
		//debugger;
	    var ret = true; // default.
	    //    alert('Check');
	    //    var keyID = (window.event) ? event.keyCode : kp.keyCode;
	    var keyID = (window.event) ? kp.keyCode : kp.which ? kp.which : kp.charCode;
	
	    IgnoreFuncKey = false;
	    IgnoreAppleArrowKey = false;
	
	   switch (keyID) 
	    {
	       case 13:            // Enter key
	            //alert(keyID);
		        if (FormId == null) {
	         	    self.trySubmit();
	         	    IgnoreFuncKey = true;
	         	    return false;
	            }
	            return ret;
	        case 38:            // up arrow
	            self.moveArrow(-1);
	            ret = false;
	            IgnoreFuncKey = true;
	            if (DoubleEvtForArrow) 
	            {
	            	IgnoreAppleArrowKey = true;
	            }
	            return ret;
	        case 40:            // down arrow
	            self.moveArrow(1);
	            ret = false;
	            IgnoreFuncKey = true;
	            if (DoubleEvtForArrow) 
	            {
	            	IgnoreAppleArrowKey = true;
	            }	
	            return ret;
	        case 188:           // comma
	            IgnoreFuncKey = true;
	            ret = true;
	            return ret;
	    }
	
	    return ret;  
	}
	
  this.moveArrow = function (delta)
	{
	    //alert('move arrow' + delta + ' ' + SelectedIndex);
	    var idx = SelectedIndex;
	    
	    if (delta > 0) 
	    {
	        idx++;
	    } 
	    else if (delta < 0) 
	    	{
	        idx--;
	    }
	    if (idx < 0)
	    {
	        if (SelectedIndex == -1) {
	            idx = NumShownEntries - 1;
	        } else {
	            idx = -1;
	        }
	        //idx = NumShownEntries - 1;
	    } 
	    else if (idx >= NumShownEntries)
	    {
	        if (SelectedIndex == NumShownEntries - 1) {
	            idx = -1;
	        } else {
	            idx = 0;
	        }
	        //idx = 0;
	    }
	    //alert(idx);
	    ACDSelectEntry(DataPrefix + idx)();
	    //alert(SelectedIndex);
	    replaceCurrentKey(idx);
	    if (UseAppleWebKit) {
	    	// for apple, we need to manually move the cursor to the end
	    	setCaretToEnd(ACINPUT_ID);
	    }
	};
		
	function replaceCurrentKey(idx)
	{
	    var wholekey;
	    var start = 0;
	    var prefix = '';
	    try 
	    {
	        var input_box = document.getElementById(self.ACINPUT_ID);
	        wholekey = input_box.value;
	        wholekey = removeLastDelimiter(wholekey);
	        start = wholekey.lastIndexOf(KEY_DELIMITER);
	        if (start > 0) 
	        {
	            // if equal to 0, then it's safe to ignore the first part.
	            prefix = wholekey.substr(0, start) + KEY_DELIMITER;
	        }
	        
	        if (idx == -1)
	        {
	            wholekey = prefix + Current_Value;
	            input_box.value = wholekey;
	        } 
	        else if (idx >= 0 && idx < NumShownEntries) 
	        {
	            var entry = ShownEntries[idx];
	            if (entry.Symbol != null && entry.Symbol.length > 0)
	            {
	                if (entry.Exchange != '') {
	                    // Customized for MLE. JLin, 07/06/2009
	                    //wholekey = prefix + entry.Exchange + EXCH_DELIMITER + entry.Symbol + KEY_DELIMITER;
	                    wholekey = prefix + entry.Symbol + KEY_DELIMITER;	                    
	                } else {
	                    wholekey = prefix + entry.Symbol + KEY_DELIMITER;	                
	                }
//	                if (entry.region == 'USA')
//	                {
//				            wholekey = prefix + entry.Symbol + KEY_DELIMITER;                	
//	                } 
//	                else 
//	                {
//	                	wholekey = prefix + entry.exchange + EXCH_DELIMITER + entry.Symbol + KEY_DELIMITER;
//	        	    }
	                  input_box.value = wholekey;
	            } 
	            else if (entry.Name != null && entry.Name.length > 0)
	            {
	                wholekey = prefix + entry.Name + KEY_DELIMITER;
	                input_box.value = wholekey;
	            }
	        }
	    } 
	    catch (ae)
	    {
	        
	    }
	}
		
	function removeLastDelimiter(wholekey)
	{
	    if (wholekey == null) 
	    {
	        return null;
	    }
	    // get rid of the last KEY_DELIMITER if it is the last letter
	    if (wholekey.length > 0) 
	    {
	        var pos = wholekey.length - 1;
	        if (wholekey.charAt(pos) == KEY_DELIMITER) 
	        {
	            wholekey = wholekey.substr(0, pos);
	        }
	    }
	    
	    return wholekey;
	}		
	
	function delayedHideDropDown()
	{
	  if (Current_Value.length != 0) 
	  {
	      Current_Value = "";
	      //self.displayRecord(null);
	      self.ProcessResult(null);
	  }
	}
		
	function resetShownEntries()
	{
	    for (var i=0; i<MAX_SHOWN; i++)
	    {
	        ShownEntries[i] = null;
	    }
	    
	    NumShownEntries = 0;
	    
	    //alert('ShownEntries reset');
	}
	
	//this.displayRecord = function(record)
	//function AutoCompleteBox.displayRecord(record)
    this.ProcessResult = function(record)
    {
        //alert('display record');
        var dropdown = null;
        try 
        {
            dropdown = document.getElementById(self.ACDROPDOWN_ID);

            //alert(dropdown);
            if (dropdown != null) 
            {
                if (record == null) 
                {
                    dropdown.innerHTML = "";
                    SelectedIndex = -1;
                    if (NumShownEntries > 0) {
                        resetShownEntries();
                    }
                } 
                else 
                {
                    resetShownEntries();
                    SelectedIndex = -1;                
                    dropdown.innerHTML = generateContentFromRecord(record.Key, record.Values);
                    //alert('get record');
                }
               
                //alert('here');
                
                if (dropdown.innerHTML.length == 0)
			    {
			      dropdown.visibility = 'hidden';
			      if (typeof showalldrops == 'function') 
			      {
			          showalldrops();
			      }
			      //alert('here a');
			    } 
			    else
			    {
			        if (typeof hidealldrops == 'function') 
			        {
			            hidealldrops();
			        }
			        //alert("here b " + self.AutoPosition);
			        if (self.AutoPosition) {                
			            var txt_box = document.getElementById(self.ACINPUT_ID);
			            if (txt_box != null) 
			            {
			                var coords = AutoCompleteBox.findPosition(txt_box);
			                dropdown.style.left = coords[0] - 10 + 'px';
			                dropdown.style.top = coords[1] + 2 + txt_box.offsetHeight + 'px';
			                //alert(coords[1] + ' ' + txt_box.offsetHeight);
			            }
			        }
			        dropdown.visibility = 'visible';     
			        SelectedIndex = -1;
    			    
			        //attach event
    			    
			        for(var i=0;i<NumShownEntries;i++)
			        { 
			    	    var trId= DataPrefix+i;
			    	    AutoCompleteBox.addListener(document.getElementById(trId),"mouseover",ACDSelectEntry(trId));
			    	    AutoCompleteBox.addListener(document.getElementById(trId),"click",clickEntry(trId));
			        }
			    //                if (SelectedIndex != -1)
			    //                {
			    //                    ACDSelectEntry(DataPrefix + SelectedIndex);
			    //                }
			    }
            }
        } 
        catch (e) 
        {
            alert(e);
        }
        //alert(dropdown.visibility);
    };	    
    function generateContentFromRecord(key, values)
	{
		//alert('generateContentFromRecord called');
	    var content = "";
	    var size = 0;
	    
	    if (values == null) {
	        return content;
	    }
	    
	    size = values.length;	    
	    if (size == 0) 
	    {
	       return content;
	    }
	    
	    var tmpstr = "";
	    var partial = "";
	
	    for (var i=0; i<size; i++) 
	    {
	        if (values[i] != null) {
	            tmpstr += generateContentForRow(key, DataPrefix + i, values[i]);
	            AddNewShownEntry(values[i]);
	        }
	    }
	    
	//    if (SelectedIndex >= NumShownEntries)
	//    {
	//        SelectedIndex = NumShownEntries - 1;
	//    }
	    
	    if (tmpstr.length > 0) {
	    	// Customized for MLE. JLin, 07/06/2009
	    	/*
	        if (self.ShowAll != null) {
	            tmpstr += "<tr><td colspan=3 class='ACDropDownStyle' style='padding: 9px 0px 0px 0px;color:gray;'><a href='" 
	                + self.ShowAll + key + "'>more results for \"" + key + "\" ...</a></td></tr>";
	        }
	        */
	        content += "<table border=1px><tr><td style='border-style:none; padding: 9px 5px 7px 5px;'><table class='ACDropDownStyle'>" + tmpstr + "</table></td></tr></table>"
	    }
	    return content;
	}
	
    function generateContentForRow(key, id, row)
	{
	    //alert('key ' + key + '   row ' + row);
	    var ret = "";

        var myid = id;
        //+ "')\" onmouseout=\"ACDUnSelectEntry('" + myid 
        //ret = "<tr id='" + myid + "' style='' onmouseover=\"ACDSelectEntry('" + myid + "')\" onclick=\"clickEntry('" + myid + "')\">"
        ret = "<tr id='" + myid + "' >"
        if (row == null) {
            return ret;
        }
        var exch_prefix = '';
//        if (row.Exchange != '')
//        {
//            exch_prefix = row.Exchange + ':' ;
//        }
        var pos = row.MatchPos;

        var match_col = Math.floor(pos / IDX_BASE);
        pos = pos % IDX_BASE;
        if (match_col == 0)
        {
            // match symbol
            ret += AutoCompleteBox.generateMatchTd(row.Symbol, key, pos, exch_prefix, false)
            ret += "<td></td>";
            ret += "<td class='ACDropDownStyle'>" + row.Name + "</td>";
            
        } else if (match_col == 1) {
            ret += "<td class='ACDropDownStyle'>" + exch_prefix + row.Symbol + "</td>";
            ret += AutoCompleteBox.generateMatchTd(row.Key2, key, pos, exch_prefix, true)
            ret += "<td class='ACDropDownStyle'>" + row.Name + "</td>";            
        }else {
            // match name
            ret += "<td class='ACDropDownStyle'>" + exch_prefix + row.Symbol + "</td>";
            ret += "<td></td>";
            ret += AutoCompleteBox.generateMatchTd(row.Name, key, pos, '', false)
        }
        // add exchange info
        var exch_display = '';
        if (row.Type == 'FO')
        {
            exch_display = 'Fund';
        }
        else if (row.Type == 'FC')
        {
            exch_display = 'Fund (Closed-End)';
        }
        else if (row.Type == 'XI')
        {
            exch_display = 'Index';
        }
        else if (row.Exchange != null) 
        {
            if (ExchDisplayArray[row.Exchange] != null)
            {
                exch_display = ExchDisplayArray[row.Exchange];
            } else {
                exch_display = row.Exchange;
            }
        }

        var width_str = '';
        if (exch_display.length > 0)
        {
            width_str = 'padding-left:6;'
            //width_str = ' width=130';
        }
        
        // Customized for MLE. JLin, 07/06/2009
        //ret += "<td class='ACDropDownStyle'" + "align=right style='color:gray;" + width_str +"' >" + exch_display + "</td>";	        
        ret += "<td class='ACDropDownStyle'" + "align=right style='color:gray;" + width_str +"' >&nbsp;</td>";	        
        
        ret += "</tr>";

        //alert(ret);
	    
	    
	    return ret;
	}

  function AddNewShownEntry(data)
	{
			    //alert('AddNewShownEntry');
			    //var entry = data.split(ACQ_COL_DELIMITER);
			    //alert('after split ' + NumShownEntries + ' ' + ShownEntries);
			    //ShownEntries[NumShownEntries] = new DataEntry(entry[0], entry[1], entry[2], entry[3], entry[4], entry[5], entry[6]);
			    ShownEntries[NumShownEntries] = data;
			    NumShownEntries++;
	}
	
	function clickEntry(myID)
	{  
		return function()
		{
	    var sid = myID.substr(DPLen);
	    //chooseEntry(sid);
	    SelectedIndex = sid;
	     //replaceCurrentKey(SelectedIndex);
	    self.trySubmit();
	  }
	}

    function ACDSelectEntry(myID)
    {   
	    return function()
	    {
        var entry;
        var sid = myID.substr(DPLen);
        if (sid != SelectedIndex && SelectedIndex >= 0 && SelectedIndex < NumShownEntries)
        {
            // unselect the existing one.
            var cur_entry = document.getElementById(DataPrefix+SelectedIndex);
            if (cur_entry != null) 
            {
                cur_entry.style.backgroundColor = ENTRY_COLOR;
            }
        }
        
        if (sid >= 0) 
        {
            entry = document.getElementById(myID);
            if (entry != null) 
            {
                entry.style.backgroundColor = ENTRY_SELECT_COLOR;
                //replaceCurrentKey(sid);
            }
        } 
    //    else {
    //        replaceCurrentKey(-1); // recover
    //    }
        
        SelectedIndex = sid;
        }
    }
		
	this.trySubmit = function ()
	{
	    if (SelectedIndex >= 0 && SelectedIndex < NumShownEntries) 
	    {
	        replaceCurrentKey(SelectedIndex);
	        if (self.EntryChosenCallback != null)
	        {
	            var entry = ShownEntries[SelectedIndex];
	            var func_str = self.EntryChosenCallback + '(entry)';
	            delayedHideDropDown();
	            try {
	            eval(func_str);
	            } catch (e)
	            {
	            }
	            
	            delayedHideDropDown(); // hide it now.
	            return false;
	        }	        
	    } else {
	        SelectedIndex = -1;
	    }
	    
	    // not entry chosen or there is no EntryChosenCallback set
	    var quoteInput = document.getElementById(self.ACINPUT_ID);
	    if (quoteInput != null)
	    {
    	    var line = quoteInput.value;
	        line = removeLastDelimiter(line);
	        //alert(line);
            if (line != null)
	        {
	            var str = leftTrim(line);
	            if (str != '')
	            {
                    // treat as multiple tickers.
                    // still submit the whole line, not the trimmed string
                    commonSearch(QUOTE_SERVER,line);
                    
	            }
	        }
	    }
	    
	    delayedHideDropDown(); // hide it now.
	    return false; // make sure the original event is cancelled
	};
		  
  function commonSearch(actionURL, content)
	{   
	    //alert(self.SubmitCallback); 
	    if (self.SubmitCallback != null) {
	        // do user callback
	        var tmpstr = self.SubmitCallback + "('" + content + "')";
	        delayedHideDropDown();
	        //alert('leaving');
	        eval(tmpstr);	        
	        //loseFocus();
	    }
	    else {
	        location.href = actionURL + escape(content);
//	        var st = document.getElementById("SrchTerm");
//	    	if(st != null)
//	    	{
//	    		st.value = content;
//	    	}
//	    	var f = document.getElementById(FormId);
//	    	f.action = actionURL+escape(content);
//	    	if(IsSubmit)
//	    	{
//	    	    f.submit();   	
//	        }
	    } 
	}
	
	
	this.set_ENTRY_SELECT_COLOR = function(color)
	{
		ENTRY_SELECT_COLOR = color;

	}  
	
	this.set_ENTRY_COLOR = function(color)
	{
		ENTRY_COLOR = color;
	}
    this.set_IsSubmit = function(isSub)
	{
		IsSubmit = isSub;
	}
    
    this.SetPreference = function(Region, PreferredLanguage, SecurityType)
    {
        Oracle.SetPreference(Region, PreferredLanguage, SecurityType);
    };
    

    
	{ 
		initExchArray();
		resetShownEntries();		
		initInputBox(self.ACINPUT_ID);	
	}
}

AutoCompleteBox.addListener = function(pElement,type,fn)
{
    if (pElement.attachEvent) 
    {
        //FIXME: We ignore cancle_bubble for IE... could be a problem?
        pElement.attachEvent("on" + type, fn);
    }
    else if(pElement.addEventListener)
    {
        pElement.addEventListener(type, fn, false);
    }
}

AutoCompleteBox.findPosition = function(pElement) 
{
    var curleft = curtop = 0;
    if (pElement.offsetParent) 
    {
        curleft = pElement.offsetLeft
        curtop = pElement.offsetTop
        while (pElement = pElement.offsetParent) 
        {
            curleft += pElement.offsetLeft
            curtop += pElement.offsetTop
        }
    }
    return [curleft,curtop];
}

AutoCompleteBox.generateMatchTd = function(str, key, pos, exch, secondary)
{
   var prefix = exch;
   var suffix = "";
   
   if (pos > 0) 
   {
      prefix += str.substring(0, pos);
   }
   if (pos + key.length <str.length) 
   {
      suffix = str.substring(pos + key.length);
   }

   //alert(str + ',' + prefix + ',' + key + ',' + suffix);
   var style = "<td class='ACDropDownStyle'>";
   if (secondary)
   {
        style = "<td class='ACDropDownStyle' style='color:gray;'>";
   }
   var ret = style + prefix
    + "<b>" + str.substring(pos, pos+key.length)
    + "</b>" + suffix + "</td>";
   
 
   return ret; 
}

function setCaretToEnd(objid) 
{
    var obj = document.getElementById(objid);
    if (obj == null) 
    {
    	return;
    }
    var pos = obj.value.length;
    if(obj.createTextRange) 
    {   
        /* Create a TextRange, set the internal pointer to  
           a specified position and show the cursor at this  
           position  
        */  
        var range = obj.createTextRange();   
        range.move("character", pos);   
        range.select();   
    } 
    else if(obj.selectionStart) 
    {   
        /* Gecko is a little bit shorter on that. Simply  
           focus the element and set the selection to a  
           specified position  
        */ 
        obj.focus();   
        obj.setSelectionRange(pos, pos);   
    }   
} 