window.SuggestionBox = window.SuggestionBox || {
    AdvancedSearchUrl: '/system/asset?cmsid=P-2038159',
    CharRegex: /([\,\(\)\[\]\*\+\?\#\:\\\.\$\%])/g,
    CssHref: '/Domestic/SymbolLookupWeb/css/SuggestionBox.css',
    DataDirectory: '/symlup/ALL',
    SelectedIndex:0, 
    PageSize:10,
    Request:{},
    SearchCriteria:'',
    AttachTextField: function(textField) {
        if (!this.Initialized) {        
            var v = navigator.appVersion;
            var parentWin = this.GetTopWindow();
            try {
                parentWin.document.createStyleSheet(this.CssHref);
            } catch (e) {
                var link = parentWin.document.createElement("link");
                link.setAttribute("type", "text/css");
                link.setAttribute("href", this.CssHref);
                link.setAttribute("rel", "Stylesheet");
                parentWin.document.documentElement.childNodes[0].appendChild(link);
            }
            var hideResults = function () {
                SuggestionBox.HideResults();
            }
            
            if(document.addEventListener){ 
                document.addEventListener("click", hideResults, false);
            } else {
                document.attachEvent("onclick",hideResults);
            }
            
            this.RequiresMatting = (v.indexOf("MSIE ") > 0 && v.indexOf("MSIE 7") == -1);  
            if (this.RequiresMatting) {
                this.GetPanelMatting();
            }
        }
        
        textField.setAttribute("autocomplete", "off");
        textField.onblur = function () {
            if (SuggestionBox.SelectedIndex > -1 && SuggestionBox.FilteredData != null && SuggestionBox.FilteredData.length > SuggestionBox.SelectedIndex)  {
                SuggestionBox.SetSymbol(SuggestionBox.FilteredData[SuggestionBox.SelectedIndex][0]);
            };
            //SuggestionBox.HideResults();
            
            setTimeout("SuggestionBox.HideResults()", 500);   
        };
        textField.onkeydown = function (evt) {
            if (evt == null)
                evt = window.event;
            var win = SuggestionBox.GetTopWindow();
            var divResults = SuggestionBox.GetResultsPanel();
            var keyCode = evt.keyCode;
            if (SuggestionBox.IsKeyIgnored(keyCode)) {
                switch (keyCode) {
                    case 38://Arrow Up
                        if (divResults.style.display != 'none') {
                            if (SuggestionBox.SelectedIndex != SuggestionBox.Data.length -1 && SuggestionBox.SelectedIndex < SuggestionBox.PageSize -1 && SuggestionBox.SelectedIndex < SuggestionBox.FilteredData.length-1) {
                                SuggestionBox.SelectedIndex++;
                                SuggestionBox.RepaintResults();
                            }
                        } else if (this.value.length > 0){
                            SuggestionBox.MakeRequest(this.value, this.id);
                            return;
                        }
                        break;
                    case 40://Arrow down
                        if (divResults.style.display != 'none') {
                            if (SuggestionBox.SelectedIndex < 0) {
                                SuggestionBox.SelectedIndex = SuggestionBox.FilteredData.length -1;
                                SuggestionBox.RepaintResults();
                            } else if (SuggestionBox.SelectedIndex != 0) {
                                SuggestionBox.SelectedIndex--;
                                SuggestionBox.RepaintResults();
                            }
                        } else if (this.value.length > 0){
                            SuggestionBox.MakeRequest(this.value, this.id);
                            return;
                        }
                        break;
                }
            }
            
            if(this.value.length == 0) {
                SuggestionBox.HideResults();
                return;
            } 
            if (keyCode == 13) {
                if (SuggestionBox.SelectedIndex > -1 && SuggestionBox.FilteredData != null && SuggestionBox.FilteredData.length > SuggestionBox.SelectedIndex)  {
                    SuggestionBox.SetSymbol(SuggestionBox.FilteredData[SuggestionBox.SelectedIndex][0]);
                } 
                //Hide results and do submit form data;
                if (SuggestionBox.IsVisible) {
                    SuggestionBox.HideResults();
                    return;
                }
            }
        };        
        textField.onkeyup = function (evt) {
            if (evt == null)
                evt = window.event;
            var win = SuggestionBox.GetTopWindow();
            var keyCode = evt.keyCode;
            
            if(this.value.length == 0) {
                
                SuggestionBox.Data = null;
                SuggestionBox.HideResults();
                return;
            } 
            if (!SuggestionBox.IsKeyIgnored(keyCode)) {
                SuggestionBox.SelectedIndex = -1;
                //Hide if the data is empty and the length is greater than 5
                if (!evt.ctrlKey && keyCode != 8 && keyCode != 46 && SuggestionBox.Data == null && this.value.length > 3) {
                    SuggestionBox.HideResults();
                } else {
                    //Filter currentData
                    SuggestionBox.FilterCurrentData(this.value);
                    if (keyCode ==8 || keyCode == 46 || this.value.length < 3 || SuggestionBox.FilteredData.length < SuggestionBox.PageSize && this.value.length < 5) {
                        //if keyCode is delete or backspace make new request
                        SuggestionBox.MakeRequest(this.value,this.id);
                    } if (SuggestionBox.SearchCriteria.length >= 3 && SuggestionBox.FilteredData.length == 0) {
                        SuggestionBox.HideResults();
                    } else {
                        SuggestionBox.DisplayResults(this.id);
                    }
                }
            } 
        };

    },
    DisplayResults: function (id) {
        var textField = document.getElementById(id);
        var data = this.FilteredData;
        if (data == null)
            data = this.Data;
        if (data == null || data.length == 0) {
            return;
        }
        var win = this.GetTopWindow();
        
        var divResults = this.GetResultsPanel();
        divResults.innerHTML = '';
        var table;
        
        table = win.document.createElement("table");
        table.cellSpacing = 0;
        table.cellpadding = 0;
        table.border = 0;
        table.appendChild(win.document.createElement("tbody"));
        table.id = 'resultsTable_qq';
        divResults.appendChild(table);
        
        var tr2 = win.document.createElement("tr");
        var td2 = win.document.createElement("td");
        td2.setAttribute("colSpan","2");
        td2.setAttribute("align","right");
        tr2.appendChild(td2);
        
        var link = win.document.createElement("a");
        link.setAttribute("href", "javascript:void(0);");
        if(win.location.href.indexOf('/chinese') > -1 || win.location.href.indexOf('/schwab-us-zh') > -1) {
        	link.innerHTML = "§ó¦h..";
		}
		else {
			link.innerHTML = "More..";
		}
        link.onclick = function() {
            SuggestionBox.ShowAdvancedSearch(textField);
        }
        td2.appendChild(link);
        table.firstChild.appendChild(tr2)
        
        
        for (var i=(data.length-1); i > -1; --i) {
            var tr = win.document.createElement("tr");
            tr.index = i;
            tr.onmouseover = function() {
                SuggestionBox.SelectedIndex = this.index;
                SuggestionBox.RepaintResults();
            }
            tr.onmouseout = function() {
                this.className = '';
                SuggestionBox.SelectedIndex = -1;
            }
            tr.onclick = function() {
                SuggestionBox.SetSymbol(SuggestionBox.FilteredData[SuggestionBox.SelectedIndex][0]);
                SuggestionBox.HideResults();
            }
            var tmp = textField.value.split(' ');
            var tmp2 = '';
            for (var k=0; k < tmp.length; k++ ){
                if (k == tmp.length-1)
                    tmp2 += tmp[k]
                else
                    tmp2 += tmp[k] + '|';
            }
            var matchFound = false;
            
            for (var j=0; j < data[i].length; ++j) {
                var td = win.document.createElement('td');
                td.className = 'ResultColumn' + j;
                var text = data[i][j];
                
                var pattern = "("+tmp2.replace(SuggestionBox.CharRegex,'\\$1')+")";
                var re = new RegExp(pattern,"ig");
                
                
                if (text.match(re) && matchFound == false) {
                    if (tmp.length == 1 || j != 0) {
                        matchFound = true;
                        text = text.replace(re, "<b>$1</b>");
                    }
                }
                td.innerHTML = text;
                tr.appendChild(td);
            }
            
            table.firstChild.appendChild(tr);
        }
    
        divResults.style.display = '';
        divResults.style.width = '';
        var pos = ClientUtil.GetXY(textField);
        divResults.style.left = pos.X + 'px';
        divResults.style.bottom = (40 - pos.Y) + 'px';
        divResults.style.zIndex = 99999;
        
        if (textField.offsetWidth > divResults.offsetWidth) {
            divResults.style.width = (textField.offsetWidth + 10) + 'px';
            table.style.width = '100%';
        } else {
            divResults.style.width = '';
            table.style.width = '';
        }
        divResults.style.height = '';
        this.IsVisible = true;
        this.ActiveTextFieldId = id;
        this.RenderPanelMatting();
    },
    
    FilterCurrentData: function (criteria) {
        var filteredData = new Array();
        var exactSymbolMatchFound = -1;
        if (this.Data != null) {
            var keywords = criteria.replace(SuggestionBox.CharRegex,'\\$1').split(' ');
            var pattern = '';
            if (keywords.length > 1) {
                pattern = '(' + keywords.join(').*(') + ')';
            } else if (criteria.indexOf('$') > -1) {
                pattern = "\\$("+criteria.substring(1,criteria.length).replace(SuggestionBox.CharRegex,'\\$1')+")";
            } else {
                pattern = "("+criteria.replace(SuggestionBox.CharRegex,'\\$1')+")";
            }
            var re = new RegExp(pattern,"ig");
            for (var i=0; i < this.Data.length; ++i) { //Loop Rows
                if (exactSymbolMatchFound == -1) {
                    exactSymbolMatchFound = (this.Data[i][0] == criteria.toUpperCase())?filteredData.length:-1;
                }
                for (var j=0; j < this.Data[i].length; ++j) { //Loop Columns
                    if (this.Data[i][j].match(re)) {
                        filteredData[filteredData.length] = this.Data[i];
                        break;
                    } 
                }
                if (filteredData.length == this.PageSize) {
                    break;
                }
            }
            if (keywords.length == 1) { 
                //look for an exact match user types in single word
                if (exactSymbolMatchFound > 0){
                    //Match not on top. re-organize array
                    var arr = new Array();
                    arr[0] = filteredData[exactSymbolMatchFound];
                    for (var i=0; i < filteredData.length; i++) {
                        if (i!= exactSymbolMatchFound) {
                            arr[arr.length] = filteredData[i];
                        }
                    }
                    this.FilteredData = arr;
                    return 0;
                } else if (exactSymbolMatchFound < 0) {
                    //not found so do regex search on entire text data
                    var ptrn = '(\\["'+keywords[0].replace(SuggestionBox.CharRegex,'\\$1')+'",.*\\"])(?:,{0,1})';
                    var regex = new RegExp(ptrn,"ig");
                    var result = regex.exec(this.TextData);
                    if (result) {
                        filteredData.pop();
                        var newArr = new Array();
                        newArr[0] = eval(result[1]);
                        for (var i=0; i < filteredData.length; i++) {
                            newArr[newArr.length] = filteredData[i];
                        }
                        this.FilteredData = newArr;
                        return 0;
                    }
                    
                }
            }
        }
        this.FilteredData = filteredData;
        return exactSymbolMatchFound;
    },
    
    FilteredData: {},
    
    
    GetPanelMatting: function() {
        var win = this.GetTopWindow();
        if (this.iframeMask == null) {
            var iframe = win.document.getElementById('resultsPanelMatting_qq');
            if (iframe == null) {
                iframe = win.document.createElement("iframe");
                iframe.id = 'resultsPanelMatting_qq';
                iframe.setAttribute("frameborder","0");
                iframe.style.display = 'none';
                iframe.src = '/Domestic/SymbolLookupWeb/blank.htm';
                win.document.body.appendChild(iframe);
            }
            this.iframeMask = iframe;
        }
        return this.iframeMask;
    },
    
    GetResultsPanel: function() {
        var win = this.GetTopWindow();
        if (this.divResults == null) {
            var div = win.document.getElementById('divResults_qq');
            if (div == null) {
                div = win.document.createElement("div");
                win.document.body.appendChild(div);
                div.id = 'divResults_qq';
                div.style.display = 'none';
                div.style.padding = '2px';
            }   
            this.divResults = div;
            
        }
        return this.divResults;
    },
    
    GetTopWindow: function () {
        if (this.win == null) {
            this.win = window;
            var i=0;
            while(this.win.parent != this.win) {
                this.win = this.win.parent;
                try {
                    if (this.win.frames.length > 0 &&  this.win.frames["CCBodyi"]) {
                        break;
                    }
                } catch (e) {
                }
                i++;
            }
        }
        return this.win;
    },
    
    HidePanelMatting: function() {
        var matting = this.GetPanelMatting();
        matting.style.display = 'none';
    },
    
    HideResults: function() {
        var divResults = this.GetResultsPanel();
        divResults.style.display = 'none';
        //this.Data = null;
        this.FilteredData = null;
        this.IsVisible = false;
        if (this.RequiresMatting)
            this.HidePanelMatting();
    },
    
    IsKeyIgnored: function (keyCode) {
        if ((keyCode == 9) || (keyCode == 13)  || // tab, enter
        (keyCode == 16) || (keyCode == 17) || // shift, ctl
        (keyCode >= 18 && keyCode <= 20) || // alt,pause/break,caps lock
        (keyCode == 27) || // esc
        (keyCode >= 33 && keyCode <= 35) || // page up,page down,end
        (keyCode >= 36 && keyCode <= 40) || // home,left,up,right,down
        (keyCode >= 44 && keyCode <= 45)) { // print screen,insert
            return true;
        }
        return false;
    },
    
    IsVisible: false,
    
    RenderPanelMatting: function () {
        if (SuggestionBox.IsVisible && this.RequiresMatting) {
            var matting = this.GetPanelMatting();
            var divResults = this.GetResultsPanel();
            matting.style.display = '';
            matting.style.width = divResults.offsetWidth + 'px';
            matting.style.height = divResults.offsetHeight + 'px';
            matting.style.bottom = divResults.style.bottom;
            matting.style.left = divResults.style.left;
            matting.style.border = 'none';
            matting.style.zIndex = 999;
        }
    },
    
    MakeRequest: function (symbol, id){
        
        symbol = symbol.toLowerCase();
        if (symbol.length > 3) {
            symbol = symbol.substring(0,4);
        } 
        this.SearchCriteria = symbol;
        var url;
        
        //Check for reserved system file names
        switch (symbol)
        {
            case "aux":
            case "prn":
            case "con":
            case "com2":
            case "nul":
                url = this.DataDirectory + '/' + symbol + '__.txt';
                break;
            default:
                url = this.DataDirectory + '/' + symbol.replace('*','_2a_').replace(':','_3a_').replace('.','_2e_').replace('&','_26_').replace('/','_2f_').replace('\\','_5c_') + '.txt';
                break;
        }
         
        
        if (symbol.length == 0)
            return;
        var callback = {   
            success: function(o) {
                var text = o.responseText;
                SuggestionBox.TextData = text;
                if (text.length > 2) {
                    try {
                        eval("SuggestionBox.Data = " + text);
                        var textField = document.getElementById(id);
                        SuggestionBox.FilterCurrentData(textField.value);
                        SuggestionBox.DisplayResults(id);
                    } catch (e) {
                        this.failure(0);
                    }
                } else {
                    SuggestionBox.HideResults();
                }
            },   
            failure: function(o) {
                //If 4char file does not exist then request 3 char file.
                if (symbol.length >= 4) {
                    SuggestionBox.MakeRequest(symbol.substring(0,3),id);
                } else {
                    SuggestionBox.HideResults();
                }
            }
        }
        
        if (this.Request != null && Connection.IsCallInProgress(this.Request))
            Connection.AbortRequest(this.Request);
        this.Request = Connection.SendRequest(url, callback);
    },

    OnSymbolSelected: function () {
        //Implemented by invoking page
    },
    
    RepaintResults: function () {
        var win = this.GetTopWindow();
        var divResults = this.GetResultsPanel();
        var table = win.document.getElementById("resultsTable_qq");
        var rows = table.getElementsByTagName('tr');
        var index = SuggestionBox.SelectedIndex;
        for (var i=0; i < rows.length; ++i) {
            if (rows[i].index == index) 
                rows[i].className = 'HoverRow';
            else
                rows[i].className = '';
        }
    },
    
    SetSymbol: function (symbol) {
        var textField = document.getElementById(this.ActiveTextFieldId);
        textField.value = symbol;
        if (typeof(textField.OnSymbolSelected) == 'function') {
            textField.OnSymbolSelected();
        } else {
            this.OnSymbolSelected();
        }
    },
    
    ShowAdvancedSearch: function(textField) {
        this.ActiveTextFieldId = textField.id;
        var sUrl = this.AdvancedSearchUrl + "&criteria=" + textField.value;

        if (this.DataDirectory.toUpperCase().indexOf('/') > -1)
            type = this.DataDirectory.toUpperCase().substring(this.DataDirectory.lastIndexOf('/')+1);
        else
            type = this.DataDirectory.toUpperCase();
        var typeFilter = 'STK,MFD,ETF,BND,PFD,IDX';
        switch (type) {
            case 'STK':
                typeFilter = 'STK,ETF,PFD';
                break;
            case 'ETF':
                typeFilter = 'ETF';
                break;
            case 'MF':
                typeFilter = 'MFD';
                break;
            case 'BND':
                typeFilter = 'BND';
                break;
            case 'EUK':
                typeFilter = 'STK,BND,PFD';
                break;
            case 'STK_PFD':
                typeFilter = 'STK,PFD';
                break;
        }

        sUrl += '&filter=' + typeFilter;

        var win = this.GetTopWindow();
		if(win.location.href.indexOf('/chinese') > -1 || win.location.href.indexOf('/schwab-us-zh') > -1) {
        	sUrl += '&site=CWT';
		}
		else if(win.location.href.indexOf('/europe') > -1 || win.location.href.indexOf('/schwab-uk-en') > -1) {
        	sUrl += '&site=EUK';
		}
		else {
        	sUrl += '&site=DWT';
		}
    	var popup = window.open(sUrl, "symbolLookup", "width=500,height=600,status=no,toolbar=no,menubar=no,location=no,scrollbars=no,resizable=yes");
    	if (popup) {
    	    popup.TextID = textField.id;
    	    popup.IsQQ = true;
    	    popup.focus();
    	}
    }
}