/**
 * @author icebox
 */

/*jslint browser: true */
/*global Jaxer, YAHOO, inputEx,
    getOptimalPortfolio, getKeyStatistics, getMostUsedSymbols, 
    getQuotesFromYahoo */

YAHOO.namespace("Finance.SymbolSuggest");
YAHOO.Finance.SymbolSuggest.ssCallback = function (o) { 
    var callback = YAHOO.util.ScriptNodeDataSource
       .callbacks[YAHOO.util.ScriptNodeDataSource._nId - 1];
    if (typeof callback  === 'function') {
        callback(o);
    }      
};

YAHOO.namespace("proplus.conpa");



YAHOO.proplus.conpa.init = function () {        
    var Dom = YAHOO.util.Dom,
        now, tabView_Main,
        myDataTable, 
        waitPanel, 
        pieChartPanel = null, 
        performanceChartPanel = null,        
        pieDS, pieChart, perfDS, perfChart,
        assetStatsPanel = null,
        graphPanel = null,
        oGetOptimalPortfolioButton, oReferenceDateButton, nTargetReturn;
                 
    now = new Date();
    tabView_Main = new YAHOO.widget.TabView('tab_Main');


    function initAssetSearch() {
        var sUri = "http://d.yimg.com/autoc.finance.yahoo.com/autoc?",
            query = "callback=YAHOO.Finance.SymbolSuggest.ssCallback&query",
            oDS, oAC;
                
        oDS = new YAHOO.util.ScriptNodeDataSource(sUri);
        oDS.responseSchema = {
            resultsList: "ResultSet.Result",
            fields: ["symbol", "name", "exch", "exchDisp", "typeDisp"]
        };
        oDS.scriptQueryParam = query;
    
        oAC = new YAHOO.widget.AutoComplete("q",
            "ysearchcontainer", oDS);
        oAC.useShadow = true;
        oAC.useIFrame = true;


       oAC.formatResult = function (oResultItem, sQuery) {
            if(!oResultItem[4]){oResultItem[4]="";}
	    if(!oResultItem[3]){oResultItem[3]=oResultItem[2];}
	    var exch_type_wrp="";
            if(oResultItem[4]!=""){exch_type_wrp+=oResultItem[4]+" - ";} 
	    exch_type_wrp+=oResultItem[3];
            return "<div style=\"float:left;width:20px;display:inline\">" +oResultItem[0] +
                "</div><div style=\"float:left;display:inline;position:relative;margin-left:52px;align:left;width:220px\">" + oResultItem[1] +  
                "</div><div style=\"float:left;display:inline;position:relative;margin-left:62px;align:left;width:120px\">" + exch_type_wrp + "</div><div style=\"clear: both\">";
        }; 
	

        oAC.doBeforeExpandContainer = function (oTextbox,
            oContainer, sQuery, aResults) {
            var pos = Dom.getXY(oTextbox);
            pos[1] += Dom.get(oTextbox).offsetHeight + 2;
            Dom.setXY(oContainer, pos);
            return true;
        };                
   /*     oAC.itemSelectEvent.subscribe(function (type, args) {
            var data, row;

            data = {};
            data.symbol = args[2][0];
            data.name = args[2][1];
            data.type = args[2][3];
            data.exchDisp = args[2][4];
            data.optimalWeight = 0;
            data.min = 0;
            data.max = 100;
	    
    var myHiddenField = YAHOO.util.Dom.get("myHidden");
    var myHandler = function(sType, aArgs) {
        var myAC = args[0]; // reference back to the AC instance
        var elLI = args[1]; // reference to the selected LI element
        var oData = args[2]; // object literal of selected item's result data
        
        // update hidden form field with the selected item's ID
        myHiddenField.value = oData.name;
    };
    oAC.itemSelectEvent.subscribe(myHandler);
    
    // Rather than submit the form,
    // alert the stored ID instead
    var onFormSubmit = function(e, myForm) {
        YAHOO.util.Event.preventDefault(e);
        alert("Company ID: " + myHiddenField.value);
    };
                data.symbol="";
    YAHOO.util.Event.addListener(YAHOO.util.Dom.get("myFor"), "submit", onFormSubmit);*/
	    
 	return {
	oDS: oDS,
	oAC: oAC
	};   
	

   //         row = YAHOO.widget.DataTable._cloneObject(data);
   //         myDataTable.addRow(row);
            
   //         resetOptimalWeigths(myDataTable);        
    
    //        oReferenceDateButton.set("label", 
    //            labelReferenceDateButton(now));
    //       oReferenceDateButton.date = now;

                
  
        

        function initMostUsedSymbols() {    
            var oMenuSymbolsButton;
                
            try {
                Jaxer.Callback.onfailureAsync = function (error, extra, xhr) {
                    // we can continue the game without mostUsedSymbols
                };
                Jaxer.Callback.ontimeoutAsync = function (error, extra, xhr) {
                    // we can continue the game without mostUsedSymbols
                };
                
                getMostUsedSymbols.async(function (mostUsedSymbols) {
                    var i, key, symbols = [];
                    
                    function onMenuSymbolClick(p_sType, p_aArgs, p_oItem) {
                        var assetInput = p_oItem.cfg.getProperty("text");

                        Dom.get("q").value = assetInput;
                        setTimeout(function () {
                            oAC.getInputEl().focus();
                            oAC.sendQuery(assetInput);
                        }, 0);
                    }
                    
                    for (i = 0; i < mostUsedSymbols.length; i = i + 1) {
                        symbols.push({
                            text: mostUsedSymbols[i][0], // symbol
                            value: mostUsedSymbols[i][1], // usage
                            onclick: {
                                fn: onMenuSymbolClick
                            } 
                        });
                    }    
                    oMenuSymbolsButton = new YAHOO.widget.Button({
                        type: "menu",
                        label: "Most Used Symbols",
                        id: "mostUsedSymbols",
                        name: "mostUsedSymbols",
                        menu: symbols,
                        container: "ysearch"
                    });
                });
            } catch (e) {
                // we can continue the game without mostUsedSymbols
            }
        }
                    
        initMostUsedSymbols();        
    }        

    function initBasketDataTable() { 
        var myColumnDefs, myDataSource, keyStats = [];        
        
        myColumnDefs = [
            {
                key: "remove", 
                label: "", 
                formatter: function (el, oRecord, oColumn, oData) {
                    el.innerHTML = '<img src="images/cancel.png" />';
                    el.style.cursor = 'pointer';                
                }
            },
            {
                key: "symbol", 
                label: "Symbol",
                formatter: function (el, oRecord, oColumn, oData) {
                    el.innerHTML = oData;
                    el.title = oRecord.getData('name');
                    el.style.cursor = 'pointer';                
                },
                sortable: true
            },
            {
                key: "name", 
                label: "Name", 
                width: 256, 
                sortable: true
            },
            {key: "type", label: "T", sortable: true},
            {key: "exchDisp", label: "Market", sortable: true},
            {
                key: "optimalWeight",
                label: "O W %",
                width: 48,
                formatter: function (el, oRecord, oColumn, oData) {                
                    if (!isNaN(oData)) {
                        oData = oData * 100;
                        el.innerHTML = YAHOO.util.Number.format(oData, {
                            prefix: "",
                            decimalPlaces: 2,
                            decimalSeparator: ".",
                            thousandsSeparator: ","
                        });
                        el.align = "right";
                    }
                },
                sortable: true
            },
            {   
                key: "min", 
                label: "Min %", 
                width: 48,
                formatter: function (el, oRecord, oColumn, oData) {
                    if (isNaN(oData) || oData < 0) {
                        oData = 0;
                    } 
                    if (oData > 100) {
                        oData = 100;
                    }
                    el.innerHTML = YAHOO.util.Number.format(oData, {
                        prefix: "",
                        decimalPlaces: 2,
                        decimalSeparator: ".",
                        thousandsSeparator: ","
                    });
                    el.align = "right";
            
                    if (oData > 0) {
                        el.style.backgroundColor = "#FFA0A0";
                    } else {
                        el.style.backgroundColor = "#FFFFFF";
                    }                
                }, 
                sortable: true, 
                editor: "textbox", 
                editorOptions: {
                    disableBtns: true,
                    validator: function (newData, oldData) {
                        if (newData !== oldData) {
                            YAHOO.widget.DataTable.validateNumber(newData);
                        }
                        return newData;
                    }
                }                
            }, 
            {
                key: "max", 
                label: "Max %", 
                width: 48,
                formatter: function (el, oRecord, oColumn, oData) {
                    if (isNaN(oData) || oData > 100) {
                        oData = 100;
                    }
                    if (oData < 0) {
                        oData = 0;
                    }
                    el.innerHTML = YAHOO.util.Number.format(oData, {
                        prefix: "",
                        decimalPlaces: 2,
                        decimalSeparator: ".",
                        thousandsSeparator: ","
                    });
                    el.align = "right";
                    if (oData < 100) {
                        el.style.backgroundColor = "#FFA0A0";
                    } else {
                        el.style.backgroundColor = "#FFFFFF";
                    }                
                },              
                sortable: true, 
                editor: "textbox", 
                editorOptions: {
                    disableBtns: true,
                    validator: function (newData, oldData) {
                        if (newData !== oldData) {
                            YAHOO.widget.DataTable.validateNumber(newData);
                        }
                        return newData;
                    }               
                }
            }
        ];
    
        myDataSource = new YAHOO.util.DataSource([]);
        myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
        myDataSource.responseSchema = {
            fields: ["symbol", "name", "type", "exchDisp"]
        };
    
        myDataTable = new YAHOO.widget.DataTable("basket",
            myColumnDefs, myDataSource, {
            caption: "",
            selectionMode: "single"
        });
    
    
        myDataTable.subscribe("cellMouseoutEvent", function (oArgs) {
            graphPanel.hide();
        });
                
        myDataTable.subscribe("cellMouseoverEvent", function (oArgs) {
            var column, firstChar, graphUrl, imgTag, record, symbol, target; 
            
            target = oArgs.target;
            column = this.getColumn(target);
            
            if (column.key === "name") {
                record = this.getRecord(target);            
                symbol = record.getData("symbol").toLowerCase();
                graphUrl = "http://chart.finance.yahoo.com/c/bb/";
                firstChar = symbol.substr(0, 1);
                if (firstChar === "^") {
                    firstChar = "_";
                }
                firstChar.toLowerCase();
                imgTag = "<img src=\"" + graphUrl + firstChar + 
                    "/" + symbol + "\" alt=\"" + symbol + "\">";
                
                if (graphPanel !== null) {
                    graphPanel.destroy();
                }
                
                graphPanel = new YAHOO.widget.Panel("graphPanel", {
                    context: [this.getTdEl(target), "tl", "br"],
                    fixedcenter: false,
                    close: false,
                    draggable: false,
                    modal: false,
                    visible: false                              
                });            
                graphPanel.setBody(imgTag);
                graphPanel.render("tab_Advisory");
                graphPanel.show();
            }
        });
    
        myDataTable.subscribe("cellClickEvent", function (ev) {
            var target, column, 
                formKeyStats, symbol; 
                
            target = ev.target;
            column = this.getColumn(target);
            
            if (column.key === "remove") {
                if (this.getRecordSet().getLength() > 0) {
                                                             
                    this.deleteRow(this.getRecord(target));                
                    resetOptimalWeigths(this);                
    
                    oReferenceDateButton.set("label", 
                        labelReferenceDateButton(now));
                    oReferenceDateButton.date = now;
                }
            }        
            
            function exitGetKeyStatistics() {
                waitPanel.hide();
                                                                
                formKeyStats = new inputEx.Group({
                    parentEl: 'formKeyStatistics',
                    fields: keyStats[symbol]
                });
                assetStatsPanel.bringToTop();
                assetStatsPanel.show();
            }
                
            if (column.key === "symbol") {
                symbol = this.getRecord(target).getData("symbol");
                    
                if (assetStatsPanel !== null) {
                    assetStatsPanel.destroy();   
                }
                
                assetStatsPanel = new YAHOO.widget.Panel('assetStatsPanel', {
                    width: "290px",                     
                    x: 400,
                    y: 290,
                    constraintoviewport: true,
                    fixedcenter: false,
                    modal: false,
                    visible: false
                });
                assetStatsPanel.setHeader("Key Statistics for " + symbol); 
                assetStatsPanel.setBody("<div id='formKeyStatistics'></div>");  
                assetStatsPanel.render("tab_Advisory");                
                
                waitPanel.setHeader("Retrieving Key Statistics, please wait...");
                waitPanel.show();
                
                Jaxer.Callback.onfailureAsync = function (error, extra, xhr) {
                    waitPanel.hide();
                    YAHOO.proplus.conpa.alert(extra.functionName + ": failed");
                };
                Jaxer.Callback.ontimeoutAsync = function (error, extra, xhr) {
                    waitPanel.hide();
                    YAHOO.proplus.conpa.alert(extra.functionName + ": timed out");
                };
                
                if (keyStats[symbol] === undefined) {
                    getKeyStatistics.async(function (res) {
                        keyStats[symbol] = res;
                        if (keyStats[symbol].length === 0) {
                            delete keyStats[symbol];
                            YAHOO.proplus.conpa.alert("Key Statistics not available for " + symbol);
                        }
                        exitGetKeyStatistics();
                    }, symbol);
                } else {                
                    exitGetKeyStatistics();
                }
            }        
            this.onEventShowCellEditor(ev);
        });
    
        myDataTable.subscribe("editorSaveEvent", function (oArgs) { 
            resetOptimalWeigths(this);    
            this.saveCellEditor(); 
        }); 
    }
    
    function initGetOptimalPortfolio()  {
        var referenceDate; 

        oGetOptimalPortfolioButton = new YAHOO.widget.Button("getOptimalPortfolio");        
    
        function onGetOptimalPortfolioClick() {
            var i, products, nProducts, record, recordData,
                res, prods = [], lows = [], highs = [],                
                targetReturn, perf, perfData = [], pieData = [];
                        
            products = myDataTable.getRecordSet();
            nProducts = products.getLength();
            if (nProducts < 3) {
                YAHOO.proplus.conpa.alert('You need at least 3 assets.');            
                return;
            }
            if (nProducts > 10) {
                YAHOO.proplus.conpa.alert('You can insert maximum 10 assets.');
                return;
            }
    
            for (i = 0; i < nProducts; i = i + 1) {
                prods[i] = products.getRecord(i).getData("symbol");
                lows[i] = products.getRecord(i).getData("min") / 100;
                highs[i] = -products.getRecord(i).getData("max") / 100;
            }

            if (nTargetReturn !== 0) { // from annual to weekly
                targetReturn = Math.pow((nTargetReturn + 1), (1 / 52)) - 1;
            } 
    
            referenceDate = oReferenceDateButton.date;
                
            waitPanel.setHeader("Optimizing, please wait...");
            waitPanel.show();
            oGetOptimalPortfolioButton.set("disabled", true);

            function exitGetOptimalPortfolio() {
                oGetOptimalPortfolioButton.set("disabled", false);
                waitPanel.hide();                                                
            }
            
            Jaxer.Callback.onfailureAsync = function (error, extra, xhr) {
                exitGetOptimalPortfolio();
                YAHOO.proplus.conpa.alert(extra.functionName + ": failed");
            };
            Jaxer.Callback.ontimeoutAsync = function (error, extra, xhr) {
                exitGetOptimalPortfolio();
                YAHOO.proplus.conpa.alert(extra.functionName + ": timed out");
            };

            getOptimalPortfolio.async(function (res) {
                try {
                    if (res.message !== "") {
                        throw res.message;
                    }
                    
                    for (i = 0; i < nProducts; i = i + 1) {
                        record = products.getRecord(i);
                        recordData = record.getData();
                        recordData.optimalWeight = res.optim.solution[i];
                        myDataTable.updateRow(record, recordData);
                        
                        pieData[i] = {
                            asset: prods[i],
                            weigth: res.optim.solution[i]
                        };
                        
                        YAHOO.util.Cookie.setSubs(YAHOO.proplus.conpa.COOKIE + "." +
                            recordData.symbol, recordData, {
                                expires: YAHOO.widget.DateMath.add(new Date(), 
                                    YAHOO.widget.DateMath.DAY, 30)
                            });
                    }
                    
                    YAHOO.util.Cookie.set(YAHOO.proplus.conpa.COOKIE +
                        ".targetReturn", nTargetReturn, {
                            expires: YAHOO.widget.DateMath.add(new Date(), 
                                YAHOO.widget.DateMath.DAY, 30)
                        });
                    YAHOO.util.Cookie.set(YAHOO.proplus.conpa.COOKIE +
                        ".referenceDate", referenceDate, {
                            expires: YAHOO.widget.DateMath.add(new Date(), 
                                YAHOO.widget.DateMath.DAY, 30)
                        });
                    YAHOO.util.Cookie.set(YAHOO.proplus.conpa.COOKIE, prods, {
                        expires: YAHOO.widget.DateMath.add(new Date(), 
                            YAHOO.widget.DateMath.DAY, 30)
                    });
                                
                    createPieChart();                                        
                    pieDS.liveData = pieData;
                    pieChart.set('dataSource', pieDS);
                    pieChartPanel.show();
                    
                    if (res.perf.length > 0) {
                        perfData[0] = {
                            performance: 0,
                            week: referenceDate
                        };
                        for (i = 0; i < res.perf.length; i = i + 1) {
                            perfData[i + 1] = {
                                performance: res.perf[i] * 100,
                                week: YAHOO.widget.DateMath.add(referenceDate, 
                                        YAHOO.widget.DateMath.WEEK, i + 1)
                            };                        
                        }        
                        createPerformanceChart();
                        perfDS.liveData = perfData;
                        perfChart.set('dataSource', perfDS);                                        
                        performanceChartPanel.show();                    
                    }
                    
                } catch (e) {
                    YAHOO.proplus.conpa.alert(e);                
                }
                                
                exitGetOptimalPortfolio();
            }, prods, referenceDate.toString(), targetReturn, lows, highs);                    
        }
        
        oGetOptimalPortfolioButton.on("click", onGetOptimalPortfolioClick);              
    }
    
initAssetSearch(); 
    

};

YAHOO.util.Event.onDOMReady(YAHOO.proplus.conpa.init);
 
