

function MyMarketWatch2Namespace()
{


///////////////////////////////////////////////////////////////////////////////////////
// MyMarketWatch2 - Core stuff

function MyMarketWatch2()
{
};


MyMarketWatch2.onLoad = function(e, info)
{
    if (typeof(info.controlId) == "undefined")
    {
        MyMarketWatch2.showError("...onLoad...info.controlId is undefined...");
        return;
    }
    
    var controlElem = document.getElementById(info.controlId);
    
    if (controlElem == null)
    {
        MyMarketWatch2.showError("...onLoad...element " + info.controlid + " not found...");
        return;
    }
    
    controlElem.quoteUrl = info.quoteUrl;
    controlElem.portfolioUrl = info.portfolioUrl;
    controlElem.screenerUrl = info.screenerUrl;
    controlElem.bridgeUrl = info.bridgeUrl;
    controlElem.userId = info.userId;
    
    controlElem.tabElems = new Array();
    var i, tabId, tabElem, dataElem, kind;
    var firstTabId = null;
    for (i = 0; i < info.tabIds.length; i++)
    {
        tabId = info.tabIds[i];
        tabElem = document.getElementById(tabId)
        dataElem = document.getElementById(tabId + "Data")
        kind = tabId.replace(info.controlId, "").replace("Tab", "");
        
        tabElem.controlElem = controlElem;
        
        if ((tabElem != null) && (dataElem != null))
        {
            controlElem.tabElems[i] = tabElem;
            
            tabElem.controlElem = controlElem;
            tabElem.dataElem = dataElem;
            tabElem.kind = kind;

            dataElem.tabElem = tabElem;

            dataElem.tickerList = null;         // The list of tickers to load up
            dataElem.quoteList = null;          // The list of quote objects to display
            dataElem.rendered = false;          // Set to true when the body div has been fully populated
            dataElem.loadInProgress = false;    // Set to true when we're actually loading the data

            dataElem.loadQuotes = null;         // Callback function to load the quotes for the tab

            dataElem.loadingElem = document.getElementById(tabId + "Loading");
            dataElem.quotesElem = document.getElementById(tabId + "Quotes");
            dataElem.emptyElem = document.getElementById(tabId + "Empty");
            dataElem.subheadElem = document.getElementById(tabId + "SubHead");

            dataElem.tickerLimit = info.tickerLimit;
            dataElem.scrollTickerLimit = info.scrollTickerLimit;

            if (kind == info.firstTab)
            {
                firstTabId = tabId;
                YAHOO.util.Dom.addClass(dataElem, "cmselectedtabpage");
            }

            switch (kind)
            {
                case "Recent":
                    dataElem.tickerList = info.recentTickers;
                    dataElem.loadQuotes = MyMarketWatch2.loadRecentTickers;
                    break;

                case "Portfolio":
                    dataElem.loadQuotes = MyMarketWatch2.loadPortfolioTickers;
                    break;

                case "Gainers":
                    dataElem.loadQuotes = MyMarketWatch2.loadGainerTickers;
                    MyMarketWatch2.loadGainerTickers(dataElem); // preload the tab
                    break;

                case "Losers":
                    dataElem.loadQuotes = MyMarketWatch2.loadLoserTickers;
                    MyMarketWatch2.loadLoserTickers(dataElem);  // preload the tab
                    break;

                default:
                    MyMarketWatch2.showError("Unhandled tab type: " + kind + ".");
                    break;
            }
        }
    }

    if (firstTabId)
    {
        MyMarketWatch2.onTabClick(firstTabId);
    }
    
    var initElem = document.getElementById(info.controlId + "Init")
    
    if (initElem)
    {
        initElem.style.display = "none";
    }
};



///////////////////////////////////////////////////////////////////////////////////////
// MyMarketWatch2 - UI


MyMarketWatch2.selectTab = function(tabElem)
{
    var e, i;
    for (i = 0; i < tabElem.controlElem.tabElems.length; i++)
    {
        e = tabElem.controlElem.tabElems[i];
        if (e == tabElem)
        {
            YAHOO.util.Dom.addClass(e, "cmselectedtab");
        }
        else
        {
            YAHOO.util.Dom.removeClass(e, "cmselectedtab");
        }
    }
};


MyMarketWatch2.onTabClick = function(id)
{
    try
    {
        var tabElem = document.getElementById(id);

        if (tabElem == null)
        {
            MyMarketWatch2.showError("...onTabClick...tab element " + id + " not found...");
            return;
        }
        
        var dataElem = tabElem.dataElem;
        
        if (dataElem == null)
        {
            MyMarketWatch2.showError("...onTabClick...data element for tab " + id + " is null...");
            return;
        }
        
        // Deselect the "other" tab(s) and select our own...
        MyMarketWatch2.selectTab(tabElem);

        // If we haven't built the body yet, do so now.
        if (!dataElem.rendered && !dataElem.loadInProgress)
        {
            // Do we have all the data we need?
            if (dataElem.QuoteList != null)
            {
                MyMarketWatch2.renderData(dataElem);
            }
            else
            {
                if (dataElem.QuoteList == null)
                {
                    if (dataElem.loadQuotes != null)
                    {
                        dataElem.loadQuotes(dataElem);
                    }
                }
                else
                {
                    MyMarketWatch2.renderNoData(dataElem);
                }
            }
        }
    }
    catch (boomer)
    {
        MyMarketWatch2.showError("MyMarketWatch2.onTabClick: " + boomer);
    }
};


MyMarketWatch2.renderQuoteTableHeader = function(quoteTable)
{
    var quoteHeaderRow = document.createElement("div");
    quoteTable.appendChild(quoteHeaderRow);

    var tickerHeader = document.createElement("p");
    quoteHeaderRow.appendChild(tickerHeader);
    tickerHeader.className = "symbol";
    tickerHeader.innerHTML = "Symbol";

    var priceHeader = document.createElement("p");
    quoteHeaderRow.appendChild(priceHeader);
    priceHeader.className = "price";
    priceHeader.innerHTML = "Price";
    
    var datasourceHeader = document.createElement("p");
    quoteHeaderRow.appendChild(datasourceHeader);
    datasourceHeader.className = "datasource";
    datasourceHeader.innerHTML = "&nbsp;";

    var changeHeader = document.createElement("p");
    quoteHeaderRow.appendChild(changeHeader);
    changeHeader.className = "change";
    changeHeader.innerHTML = "Change";

    var percentChangeHeader = document.createElement("p");
    quoteHeaderRow.appendChild(percentChangeHeader);
    percentChangeHeader.className = "percentchange";
    percentChangeHeader.innerHTML = "% Change";
    
    var clearall = document.createElement("div");
    quoteHeaderRow.appendChild(clearall);
    clearall.className = "clearall";
};


MyMarketWatch2.renderQuoteTableRow = function(quoteTable, quote, index)
{
    var quoteRow = document.createElement("div");
    quoteTable.appendChild(quoteRow);    
    quoteRow.className = "quoterow";
    
    var tickerCell = document.createElement("p");
    quoteRow.appendChild(tickerCell);
    tickerCell.className = "symbol";
    var tickerAnchor = document.createElement("a");
    tickerCell.appendChild(tickerAnchor);

    var quoteValue;
    if(quote.countryCode != null && quote.countryCode.toUpperCase() !=  "US") 
    {
        quoteValue = quote.countryCode + ":" + quote.ticker;
    }
    else
    {
        quoteValue = quote.ticker;
    }
    
    var isIndu = false;
    if (quoteValue.toLowerCase() == 'indu' || quoteValue.toLowerCase() == 'djia')
        isIndu = true;
    
    var quoteHref = quote.url;

    tickerAnchor.innerHTML = quoteValue;
    tickerAnchor.href = quoteHref;

    var priceCell = document.createElement("p");
    quoteRow.appendChild(priceCell);
    priceCell.className = "price";
    var neutralPrice = document.createElement("span");
    priceCell.appendChild(neutralPrice);
    neutralPrice.className = "neutral";
    var formattedPrice = document.createElement("span");
    priceCell.appendChild(formattedPrice);
    if (!isIndu)
        formattedPrice.className = "mwlivequotes";
    formattedPrice.setAttribute("mwfield", "Price");
    formattedPrice.setAttribute("mwformat", ",2");
    formattedPrice.setAttribute("mwsymbol", quoteValue);
    formattedPrice.innerHTML = MyMarketWatch2.formatNumber(quote.price, 2);

    var dataSourceCell = document.createElement("p");
    quoteRow.appendChild(dataSourceCell);
    dataSourceCell.className = "datasource";
    var dataSource = document.createElement("span");
    if (!isIndu)
        dataSource.className = "mwlivequotes";
    dataSource.setAttribute("mwfield", "Flags");
    dataSource.setAttribute("mwformat", "none");
    dataSource.setAttribute("mwsymbol", quoteValue);
    dataSource.innerHTML = "&nbsp;";
    var initialIcon = document.createElement("span");
    if (quote.flag && quote.flag.length > 0)
        initialIcon.className = quote.flag;
    else
        initialIcon.className = "delayed";
    initialIcon.innerHTML = "&nbsp;";
    initialIcon.setAttribute("time", quote.time)
    dataSource.appendChild(initialIcon);
    
    dataSourceCell.appendChild(dataSource);
    //MyMarketWatch2.toolTipElements.push(dataSource);

    var changeCell = document.createElement("p");
    quoteRow.appendChild(changeCell);
    changeCell.className = "change";
    var formattedChange = document.createElement("span");
    changeCell.appendChild(formattedChange);
    if (!isIndu)
        formattedChange.className = "mwlivequotes";
    formattedChange.setAttribute("mwfield", "Change");
    formattedChange.setAttribute("mwformat", ",2");
    formattedChange.setAttribute("mwsymbol", quoteValue);
    var colorChange = document.createElement("span");
    if (quote.change > 0)
    {
        colorChange.className = "up";
    }
    else if (quote.change < 0)
    {
        colorChange.className = "down";
    }
    colorChange.innerHTML = MyMarketWatch2.formatNumber(quote.change, 2);
    formattedChange.appendChild(colorChange);

    var percentChangeCell = document.createElement("p");
    quoteRow.appendChild(percentChangeCell);
    percentChangeCell.className = "percentchange";
    var formattedPercentChange = document.createElement("span");
    percentChangeCell.appendChild(formattedPercentChange);
    if (!isIndu)
        formattedPercentChange.className = "mwlivequotes";
    formattedPercentChange.setAttribute("mwfield", "PercentChange");
    formattedPercentChange.setAttribute("mwformat", ",2");
    formattedPercentChange.setAttribute("mwsymbol", quoteValue);
    var colorPercentChange = document.createElement("span");
    if (quote.percentChange > 0)
    {
        colorPercentChange.className = "up";
    }
    else if (quote.percentChange < 0)
    {
        colorPercentChange.className = "down";
    }
    colorPercentChange.innerHTML = MyMarketWatch2.formatNumber(quote.percentChange, 2);
    formattedPercentChange.appendChild(colorPercentChange);
    
    var clearall = document.createElement("div");
    quoteRow.appendChild(clearall);
    clearall.className = "clearall";
};


MyMarketWatch2.renderQuoteData = function(dataElem)
{
    var quoteTable = document.createElement("div");

    if (dataElem.quoteList.length > 10)
    {
        dataElem.className += " tall";
    }
    dataElem.quotesElem.appendChild(quoteTable);

    var quoteHead = document.createElement("div");
    quoteHead.className = "quotehead";
    quoteTable.appendChild(quoteHead);

    var quoteBody = document.createElement("div");
    quoteBody.className = "quotebody";
    
    quoteTable.appendChild(quoteBody);

    MyMarketWatch2.renderQuoteTableHeader(quoteHead);

    var index = 0;
    for (var i = 0; i < dataElem.quoteList.length; i++)
    {
        if (dataElem.quoteList[i] != null)
        {
            this.renderQuoteTableRow(quoteBody, dataElem.quoteList[i], index);
            index++;
        }
    }
};


MyMarketWatch2.renderData = function(dataElem)
{
    // Build the quote content...
    MyMarketWatch2.renderQuoteData(dataElem);
    
    // Hide the loading div and show the quote divs
    dataElem.loadingElem.style.display = "none";
    dataElem.quotesElem.style.display = "block";
    
    if (dataElem.subheadElem)
    {
        dataElem.subheadElem.style.display = "block";
    }

    // Remember that we've rendered everything, so we don't do it again...
    dataElem.rendered = true;
    dataElem.loadInProgress = false;
    
    // Since we may have new tickers...re-initialize LiveQuotes...
    if (typeof(LiveQuotesGateway) != 'undefined' && LiveQuotesGateway != null)
    {
        if (window.LiveQuotesExchanges != null)
            LiveQuotesGateway.setup(window.LiveQuotesExchanges);
        else
            LiveQuotesGateway.setup();
    }
    else if (window.MWLiveQuotes != null)
    {
        MWLiveQuotes.setup();
    }
};


MyMarketWatch2.renderNoData = function(dataElem)
{
    if (dataElem.emptyElem)
    {
        dataElem.loadingElem.style.display = "none";
        dataElem.emptyElem.style.display = "block";
        dataElem.quotesElem.style.display = "none";
        
        if (dataElem.subheadElem)
        {
            dataElem.subheadElem.style.display = "none";
        }
    }
    
    dataElem.rendered = true;
    dataElem.loadInProgress = false;
}


///////////////////////////////////////////////////////////////////////////////////////
// MyMarketWatch2 - Data loading


MyMarketWatch2.loadTickers = function(dataElem, tickers, sortBy)
{
    if ((tickers == null) || (tickers.length == 0))
    {
        MyMarketWatch2.renderNoData(dataElem);
    }
    else
    {
        dataElem.loadInProgress = true;
        
        // TODO - we're making a copy of the array here...do we really want/need to do so?
        var quoteMessage = new Object();
        quoteMessage.tickers = [];
        quoteMessage.sortBy = sortBy;
        quoteMessage.dist = "hpmymw";
        
        var limit = Math.min(tickers.length, parseInt(dataElem.tickerLimit));
        for (var i = 0; i < limit; i++)
        {
            var ticker = tickers[i];
            
            quoteMessage.tickers.push(ticker);
        }
        
        var quoteRequest = MyMarketWatch2.getRequestObject();
        var quoteUrl = dataElem.tabElem.controlElem.quoteUrl + "?json=" + JSON.serialize(quoteMessage);
        quoteRequest.open("GET", quoteUrl, true);
        quoteRequest.onreadystatechange = function()
        {
            if(quoteRequest.readyState == 4)
            {
                MyMarketWatch2.onLoadTickersComplete(quoteRequest.responseText, dataElem);
                delete quoteRequest.onreadystatechange;
                quoteRequest = null;
            }
        };
        quoteRequest.send(null);
    }
};


MyMarketWatch2.loadRecentTickers = function(dataElem)
{
    MyMarketWatch2.loadTickers(dataElem, dataElem.tickerList, "countryCode,ticker");
};


MyMarketWatch2.onLoadTickersComplete = function(responseText, dataElem)
{
    var response = JSON.deserializeNoValidate(responseText);
    
    if (response.succeeded)
    {
        dataElem.quoteList = [];
        
        for (var i = 0; i < response.quotes.length; i++)
        {
            var currentQuote = response.quotes[i];
            if (currentQuote != null)
            {
                var myQuote = new Object();
                
                myQuote.ticker = currentQuote.liveData.ticker;
                myQuote.countryCode = currentQuote.liveData.countryCode;
                myQuote.price = currentQuote.liveData.price;
                myQuote.percentChange = currentQuote.liveData.percentChange;
                myQuote.change = currentQuote.liveData.change;
                myQuote.url = currentQuote.liveData.url;
                myQuote.time = currentQuote.liveData.time;
                if(currentQuote.extraData.halted)
                    myQuote.flag = "halt";
                else if (currentQuote.extraData.hasPremarket)
                    myQuote.flag = "pre";
                else if (currentQuote.extraData.hasAfterHours)
                    myQuote.flag = "after";
                else if (currentQuote.extraData.realTime)
                    myQuote.flag = "realtime";
                else
                    myQuote.flag = "delayed";
                
                dataElem.quoteList.push(myQuote);
            }
        }

        MyMarketWatch2.renderData(dataElem);
    }
    else
    {
        MyMarketWatch2.showError(response.errorMessage);
    }
};


MyMarketWatch2.loadPortfolioTickers = function(dataElem)
{
    if (dataElem.tabElem.controlElem.userId == null)
    {
        MyMarketWatch2.renderNoData(dataElem);
    }
    else
    {
        dataElem.loadInProgress = true;
        
        var quoteMessage = new Object();
        quoteMessage.userId = dataElem.tabElem.controlElem.userId;
        
        var quoteRequest = MyMarketWatch2.getRequestObject();
        var quoteUrl = dataElem.tabElem.controlElem.portfolioUrl + "?json=" + JSON.serialize(quoteMessage);
        quoteRequest.open("GET", quoteUrl, true);
        quoteRequest.onreadystatechange = function()
        {
            if(quoteRequest.readyState == 4)
            {
                MyMarketWatch2.onLoadPortfolioComplete(quoteRequest.responseText, dataElem);
                delete quoteRequest.onreadystatechange;
                quoteRequest = null;
            }
        };
        quoteRequest.send(null);
    }
};


MyMarketWatch2.onLoadPortfolioComplete = function(responseText, dataElem)
{
    var response = JSON.deserializeNoValidate(responseText);
    
    if (response.succeeded)
    {
        if (response.tickers == null)
        {
            MyMarketWatch2.renderNoData(dataElem);
        }
        else
        {
            MyMarketWatch2.loadTickers(dataElem, response.tickers, "countryCode,ticker");
        }
    }
    else
    {
        MyMarketWatch2.renderNoData(dataElem);
        MyMarketWatch2.showError(response.errorMessage);
    }
};


MyMarketWatch2.loadScreenerTickers = function(dataElem, descending)
{
    dataElem.loadInProgress = true;
    
    var screenerMessage = new Object();
    screenerMessage.field = "PercentChange";
    screenerMessage.sortDescending = descending;
    screenerMessage.exchange = "All";
    screenerMessage.count = 30;
    
    var screenerRequest = MyMarketWatch2.getRequestObject();
    var screenerUrl = dataElem.tabElem.controlElem.screenerUrl + "?json=" + JSON.serialize(screenerMessage);
    screenerRequest.open("GET", screenerUrl, true);
    screenerRequest.onreadystatechange = function()
    {
        if(screenerRequest.readyState == 4)
        {
            MyMarketWatch2.onLoadScreenerComplete(screenerRequest.responseText, dataElem);
            delete screenerRequest.onreadystatechange;
            screenerRequest = null;
        }
    };
    screenerRequest.send(null);
};


MyMarketWatch2.loadGainerTickers = function(dataElem)
{
    MyMarketWatch2.loadScreenerTickers(dataElem, false);
};


MyMarketWatch2.onLoadScreenerComplete = function(responseText, dataElem)
{
    var response = JSON.deserializeNoValidate(responseText);
    
    if (response.succeeded)
    {
        MyMarketWatch2.loadTickers(dataElem, response.tickers, "none");
    }
    else
    {
        MyMarketWatch2.renderNoData(dataElem);
        MyMarketWatch2.showError(response.errorMessage);
    }
};


MyMarketWatch2.loadLoserTickers = function(dataElem)
{
    MyMarketWatch2.loadScreenerTickers(dataElem, true);
};


///////////////////////////////////////////////////////////////////////////////////////
// MyMarketWatch2 - Utility



MyMarketWatch2.clearRecentList = function(id)
{
    var dataElem = document.getElementById(id);
    
    if (dataElem)
    {
        // Clear the cookie...
        var mymwCookie = new Cookie("");
        
        mymwCookie.clearAllViewedQuotes();
        
        // Clear the UI...
        MyMarketWatch2.renderNoData(dataElem);
        
        // If they're logged in, clear the DB as well...
        var controlElem = dataElem.tabElem.controlElem;
        
        if (controlElem.userId)
        {
            var message = {"UserId": controlElem.userId};

            var request = MyMarketWatch2.getRequestObject();
            try
            {
                request.open("GET", controlElem.bridgeUrl + "?task=MyMarketWatch&target=MyMarketWatch2&userid=" + controlElem.userId, true);
                request.send(null);
            }
            catch(sendException)
            {
                MyMarketWatch2.showError("MyMarketWatch2.clearRecentList: " + sendException);
            }
        }
    }
};


MyMarketWatch2.expandTickerList = function(id)
{
    var elem = document.getElementById(id);
    if (typeof(elem) == 'undefined')
        return;
    elem.className = elem.className.replace(/\stall/, ' untall');
}

MyMarketWatch2.collapseTickerList = function(id)
{
    var elem = document.getElementById(id);
    if (typeof(elem) == 'undefined')
        return;
    elem.className = elem.className.replace(/\suntall/, ' tall');
}


MyMarketWatch2.formatNumber = function(value, places)
{
    var valueFormat = new NumberFormat(value);
    valueFormat.setPlaces(places);
    return valueFormat.toFormatted();
};


MyMarketWatch2.getRequestObject = function()
{
    var xmlHttp = false;

    try 
    {
        xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    } 
    catch (msxml2Exception) 
    {
        try 
        {
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        } 
        catch (microsoftException) 
        {
            xmlHttp = false;
        }
    }

    if (!xmlHttp && typeof XMLHttpRequest != 'undefined')
    {
        xmlHttp = new XMLHttpRequest();
    }

    return xmlHttp; 
};

MyMarketWatch2.showError = function(msg)
{
    // TODO - comment this out before we go to production!
    //alert(msg);
}


///////////////////////////
// InstallLibrary

function InstallLibrary(target)
{
    var t = target || window;
    t.MyMarketWatch2 = MyMarketWatch2;
};

InstallLibrary();

}


MyMarketWatch2Namespace();
