﻿/// <reference path="jquery-1.3.2-vsdoc2.js" />

var gadget = null;
$(function() {
    gadget = new Gadget();
    gadget.init();
});

function Gadget() {
    this.userStocks = ["PETR4.SA", "VALE5.SA", "BVMF3.SA"];
    this.userIndexes = ["^BVSP", "^DJI", "^IXIC"];

    this.init = function() {

        // event binding
        $("#txtQuoteCode").bind("focus", this.checkStockCodeWaterMark);
        $("#txtQuoteCode").bind("blur", this.checkStockCodeWaterMark);
        $("#btnAdd").bind("click", this.addQuoteEventHandler);
        $("#btnUpdate").bind("click", this.updateQuotes);
        $("#txtQuoteCode").bind("keydown",
            function(event) {
                if (event.keyCode == 13) {
                    gadget.addQuoteEventHandler(null);
                    event.stopPropagation();
                    event.preventDefault();
                }
            }
        );
        $("#resetGadget").bind("click",
            function() {
                $("#dialog_bottom").showDialog(
                    {
                        cancelFunction: function() { $("#dialog_bottom").closeDialog(); },
                        okFunction: function() { gadget.resetQuotesInUserStore(); $("#dialog_bottom").closeDialog() }
                    }
                )
            }
        );
        $("#lastUpdateTime").ajaxComplete(
            function(event, request, settings) {
                var date = new Date();
                var hour = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
                var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
                $(this).text(hour + ":" + minutes);
                $(this).attr("title", "Atualizado pela última vez às " + (hour + ":" + minutes));
                $(this).show();
            }
        );
        $("#loading").ajaxComplete(function(event, request, settings) { $(this).hide(); });
        $("div.icon-button, div.close-icon-button, button.dialog-button").hover(
		    function() { $(this).addClass('ui-state-hover'); },
			function() { $(this).removeClass('ui-state-hover'); }
		);

        this.fillDefaultQuotes();
        this.logVisit();
        setInterval(this.updateQuotes, 300000);
    }

    this.updateDOM = function() {
        $("#stocksList > li.quote:gt(0)").click(this.toggleQuoteDetails);
        $("#indexesList > li.quote:gt(0)").click(this.toggleQuoteDetails);
        $("#quoteType > li.quotes").click(this.toggleQuoteType);

        $("ol.quote_list > li.quote:gt(0) > div.quote_title").hover(
            function(event) {
                $(this).children("div.close-quote-button").addClass("active");
                $(this).parent().css("background-color", "#EFEFEF");
            }
            ,
            function(event) {
                $(this).children("div.close-quote-button").removeClass("active");
                $(this).parent().css("background-color", "");
            }
        );
        $("div.close-quote-button").hover(
		    function() { $(this).addClass('ui-state-hover'); },
			function() { $(this).removeClass('ui-state-hover'); }
		);
        $("div.close-quote-button").bind("click", this.closeQuote);

        $("ol.quote_list > li.quote:gt(0) div.details_content div.tab").tabs().bind("tabsselect", this.loadTabChart).bind("tabsshow", this.callAdjustHeight);
        $("ol.quote_list > li.quote:gt(0) div.details_content").click(function(event) { event.stopPropagation(); });
        $("ol.quote_list").click(function(event) { event.stopPropagation(); });
        this.zebraQuoteLists();
    }

    this.zebraQuoteLists = function() {
        $("ol.quote_list > li").removeClass("zebra");
        $("ol.quote_list > li:nth-child(even)").addClass("zebra");
    }

    this.toggleQuoteDetails = function(event) {
        $(this).find("div.details_content").slideToggle("slow", gadget.callAdjustHeight);
        $(this).toggleClass("collapsed").toggleClass("expanded");
        event.stopPropagation();
    }

    this.toggleQuoteType = function(event) {
        $(this).children("ol.quote_list").slideToggle("slow", gadget.callAdjustHeight);
        $(this).toggleClass("collapsed").toggleClass("expanded");
    }

    this.checkStockCodeWaterMark = function(event) {
        if (event.type == "blur") {
            if (!$(this).val())
                $(this).css("text-transform", null).val("Código");
        }
        else if (event.type == "focus") 
            $(this).val("").css("text-transform", "uppercase");
    }

    this.fillDefaultQuotes = function() {
        if (typeof _IG_Prefs == "function") {
            var prefs = new _IG_Prefs();
            this.userStocks = prefs.getArray("stocks");
            this.userIndexes = prefs.getArray("indexes");
        }

        for (var i = 0; i < this.userStocks.length; i++) this.addQuote(this.userStocks[i], true);
        for (var i = 0; i < this.userIndexes.length; i++) this.addQuote(this.userIndexes[i], true);

        this.updateDOM();
        this.updateQuotes();
        this.callAdjustHeight();
    }

    this.addQuoteEventHandler = function(event) {

        var quoteCode = jQuery.trim($("#txtQuoteCode").val().toUpperCase());

        if (quoteCode == "CÓDIGO" || !quoteCode) {
            $("#dialog_top").showNotification({ message: "Você precisa entrar com um código para adicionar uma cotação.", showCloseButton: true });
            return;
        }
        if (quoteCode.match(/[^\^:\.A-Z0-9]/)) {
            $("#dialog_top").showNotification({ message: "O código não pode conter caracteres especiais (exceto '^', '.' e ':') e nem espaços em branco.", showCloseButton: true });
            return;
        }

        if (quoteCode.indexOf("^") < 0 && quoteCode.indexOf(".") < 0) {    // the quote code wasn't especified using the expected format used in Yahoo! Finance
            if (quoteCode.indexOf(":") >= 0) {
                var groups = new RegExp("(.*):(.*)").exec(quoteCode);
                var stockExchange = groups[1];
                var stockCode = groups[2];
                var suffix = "";
                switch (stockExchange) {
                    case "NASDAQ":
                    case "NYSE": { suffix = ""; break; }
                    case "BVSP":
                    case "BOV":
                    case "BOVESPA": { suffix = ".SA"; break; }
                    default: { suffix = stockExchange; }
                }
                quoteCode = stockCode + suffix;
            }
            else {
                quoteCode = quoteCode + ".SA"; // bovespa (.SA) is the default stock exchange
            }
        }
        if ($("li#" + quoteCode.replace(/\^/g, "").replace(/\./g, "_")).length > 0) {
            $("#dialog_top").showNotification({ message: "A cotação para esse código já foi inserida.", showCloseButton: true });
            return;
        }

        if (!event)  // user pressed the <ENTER> key within the textbox to trigger the add quote method
            $("#txtQuoteCode").val("");
        else
            $("#txtQuoteCode").css("text-transform", null).val("Código");

        gadget.addQuote(quoteCode, false);
    }

    this.addQuote = function(quoteCode, isQuoteInBatchInserting) {
        if (quoteCode.indexOf("^") < 0) { // stock
            var HTMLQuoteCode = quoteCode.replace(/\./g, "_");  // html's ids mustn't contain especial characters such as '.'
            var displayQuoteCode = quoteCode.replace(/\..*/g, "");
            var stockHTMLTemplate = $("#stockHTMLTemplate").html();
            stockHTMLTemplate = "<li id='" + HTMLQuoteCode + "' class='stock quote collapsed'>" + stockHTMLTemplate + "</li>";
            stockHTMLTemplate = stockHTMLTemplate.replace(/#HTML_STOCK_CODE/g, HTMLQuoteCode);
            stockHTMLTemplate = stockHTMLTemplate.replace(/#DISPLAY_STOCK_CODE/g, displayQuoteCode);

            $("#stocksSection").show();
            $("#stocksList").append(stockHTMLTemplate).show();

            if (!isQuoteInBatchInserting) {
                gadget.addQuoteToUserStore(quoteCode);

                if (!$.browser.msie) {
                    if ($("#stocksList").children().length < 3)
                        $("#stocksSection").effect("pulsate", { times: 1 }, 500, this.callAdjustHeight).removeClass("collapsed").addClass("expanded");
                    else
                        $("#stocksList li#" + HTMLQuoteCode).effect("pulsate", { times: 1 }, 500, this.callAdjustHeight);
                }
            }
        }
        else {  // index

            var HTMLQuoteCode = quoteCode.replace(/\^/g, "");

            var indexHTMLTemplate = $("#indexHTMLTemplate").html();
            indexHTMLTemplate = "<li id='" + HTMLQuoteCode + "' class='index quote collapsed'>" + indexHTMLTemplate + "</li>";
            indexHTMLTemplate = indexHTMLTemplate.replace(/#INDEX_CODE/g, quoteCode);
            indexHTMLTemplate = indexHTMLTemplate.replace(/#HTML_INDEX_CODE/g, HTMLQuoteCode);

            var aka = "";
            switch (quoteCode) {
                case "^BVSP": { aka = "IBOVESPA"; break; }
                case "^DJI": { aka = "DOW JONES"; break; }
                case "^IXIC": { aka = "NASDAQ"; break; }
                default: { aka = HTMLQuoteCode; }
            }
            indexHTMLTemplate = indexHTMLTemplate.replace(/#INDEX_AKAN/g, aka);

            $("#indexesSection").show();
            $("#indexesList").append(indexHTMLTemplate).show();

            if (!isQuoteInBatchInserting) {
                gadget.addQuoteToUserStore(quoteCode);

                if (!$.browser.msie) {
                    if ($("#indexesList").children().length < 3)
                        $("#indexesSection").effect("pulsate", { times: 1 }, 500, this.callAdjustHeight).removeClass("collapsed").addClass("expanded");
                    else
                        $("#indexesList li#" + HTMLQuoteCode).effect("pulsate", { times: 1 }, 500, this.callAdjustHeight);
                }
            }
        }

        if (!isQuoteInBatchInserting) {
            gadget.updateDOM();
            gadget.updateQuotes();
            $("#dialog_top").showNotification({ showCloseButton: false, message: "<div class='loading-dialog'>&nbsp;<strong>Aguarde...</strong></div>" });
        }
    }

    this.closeQuote = function(event) {
        gadget.removeQuoteFromUserStore($(this).parents("li.quote").attr("id").replace(/_/g, "."));
        if ($(this).parents("ol.quote_list").children().length < 3) {
            var waitingToVanishLI = $(this).parents("li.quote");
            if (!$.browser.msie) {
                $(this).parents("li.quotes").effect("pulsate", { times: 1 }, 500, function() {
                    waitingToVanishLI.remove();
                    $(this).hide();
                    gadget.callAdjustHeight();
                });
            }
            else {
                waitingToVanishLI.remove();
                $(this).parents("li.quotes").hide();
                gadget.callAdjustHeight();
            }
        }
        else {
            if (!$.browser.msie) {
                $(this).parents("li.quote").effect("pulsate", { times: 1 }, 500, function() {
                    $(this).remove();
                    gadget.zebraQuoteLists();
                    gadget.callAdjustHeight();
                });
            }
            else {
                $(this).parents("li.quote").remove();
                gadget.zebraQuoteLists();
                gadget.callAdjustHeight();
            }
        }

        event.stopPropagation();
    }

    this.updateQuotes = function() {
        $("#lastUpdateTime").hide();
        $("#loading").show();

        var URL = "http://www.tidybits.com/iGQuotesBR/GetYahooQuote.ashx?s=" + gadget.userStocks.join() + "&i=" + gadget.userIndexes.join() + "&callback=?";
        $.getJSON(URL,
            function(quotes) {
                var badCode = "";
                var errorMessage = "";
                for (var i = 0; i < quotes.stocks.length; i++) {
                    var stock = quotes.stocks[i];
                    if (!stock.valid) {
                        badCode = stock.code;
                        errorMessage = "<b>" + stock.code + "</b> não é um símbolo de ação correto.";
                        errorMessage += "<p>Procure símbolos para cotações em <a href='http://br.finance.yahoo.com/lookup' target='_blank'>Yahoo! Finanças</a>.</p>";
                        gadget.removeQuoteFromUserStore(badCode);
                    }
                    else
                        gadget.fillStockIndexItem(stock.code.replace(/\./g, "_"), stock);
                }
                for (var i = 0; i < quotes.indexes.length; i++) {
                    var index = quotes.indexes[i];
                    if (!index.valid) {
                        badCode = index.code;
                        errorMessage = "<b>" + index.code + "</b> não é um símbolo de índice correto.";
                        errorMessage += "<p>Procure símbolos para cotações em <a href='http://br.finance.yahoo.com/lookup' target='_blank'>Yahoo! Finanças</a>.</p>";
                        gadget.removeQuoteFromUserStore(badCode);
                    }
                    else
                        gadget.fillStockIndexItem(index.code.replace(/\^/g, ""), index);
                }
                for (var i = 0; i < quotes.forexes.length; i++) {
                    var forex = quotes.forexes[i];
                    var forexID = "li#" + forex.code;
                    $(forexID + " span.oscillation").text("R$ " + forex.ltp);
                }
                $("#dialog_top").closeNotification(false);
                if (errorMessage) {
                    $("li#" + badCode.replace(/\^/g, "").replace(/\./g, "_") + " div.close-quote-button").click();
                    $("#dialog_top").showNotification({ message: errorMessage, showCloseButton: true });
                }
                gadget.updateOpenedChartTabs();
            }
        );
    }

    this.fillStockIndexItem = function(HTMLQuoteCode, quote) {
        var ID = "li#" + HTMLQuoteCode;
        $(ID + " span.description").text(quote.desc);
        $(ID + " span.last_trade_price").text(quote.ltp);
        $(ID + " span.price_oscillation").text(quote.ltp + " (" + quote.ppo + ")");
        if (quote.po.indexOf("-") != -1) $(ID + " span.price_oscillation").removeClass("positive").addClass("negative");
        else $(ID + " span.price_oscillation").removeClass("negative").addClass("positive");
        $(ID + " span.oscillation").text(quote.po + " (" + quote.ppo + ")");
        if (quote.po.indexOf("-") != -1) $(ID + " span.oscillation").removeClass("positive").addClass("negative");
        else $(ID + " span.oscillation").removeClass("negative").addClass("positive");
        $(ID + " span.volume").text(quote.vol);
        $(ID + " span.last_day_price").text(quote.ldp);
        $(ID + " span.oppening_price").text(quote.op);
        $(ID + " span.daily_price_oscillation").text(quote.minp + " - " + quote.maxp);
    }

    this.loadTabChart = function(event, ui) {
        if (ui.index == 0) return;   // skip details tab
        gadget.getChartImage(ui.tab, ui.panel)
    }

    this.updateOpenedChartTabs = function() {
        $("ul > li.ui-tabs-selected > a:not(:contains('Detalhes'))").each(
            function() { gadget.getChartImage(this, $(this).parents("div").find("div.ui-tabs-panel:not([class*='ui-tabs-hide'])")[0]) }
        );
    }

    this.getChartImage = function(tab, panel) {
        var quoteCode = "";
        var stockTry = $(tab).parents("li.stock").attr("id");
        var indexTry = $(tab).parents("li.index").attr("id");
        if (stockTry)
            quoteCode = stockTry.replace(/_/g, ".");
        else if (indexTry)
            quoteCode = "^" + indexTry;

        var range = ""
        if (tab.hash.indexOf("intraday_chart") >= 0)
            range = "1d";
        else if (tab.hash.indexOf("weekly_chart") >= 0)
            range = "5d";
        else if (tab.hash.indexOf("quarterly_chart") >= 0)
            range = "3m";
        else if (tab.hash.indexOf("yearly_chart") >= 0)
            range = "1y";

        var imageURL = "http://ichart.finance.yahoo.com/instrument/1.0/" + quoteCode + "/chart;range=" + range + "/image;size=239x110/xyz;r=" + Math.random();

        var contentHolderWidth = $(panel).parent().width();
        var imgWidth = 239;
        var imgHeight = 110;
        var panel = $(panel);

        if (contentHolderWidth < 239) {
            panel.find("div.chart_container").css("width", contentHolderWidth);
            panel.find("div.loading_chart").css("left", (contentHolderWidth / 2) - 10);
            imgWidth = contentHolderWidth;
            imgHeight = 110 * imgWidth / 239;
        }

        panel.find("div.loading_chart").show();
        panel.find("div.img_container").hide();

        var img = new Image();
        $(img).load(
            function() {
                panel.find("div.loading_chart").hide();
                panel.find("div.img_container").html(this).fadeIn("slow");
                panel.find("div.chart_container").css("height", panel.find("div.img_container").height());
            }
        )
        .attr("width", imgWidth).css("width", imgWidth)
        .attr("height", imgHeight).css("height", imgHeight)
        .attr("src", imageURL);
    }

    this.callAdjustHeight = function() {
        var minHeight = 180;
        if ($("div#limit").height() < minHeight)
            $("div#limit").css("height", minHeight);
        else
            $("div#limit").css("height", null);

        if (typeof _IG_AdjustIFrameHeight == "function") _IG_AdjustIFrameHeight();
    }

    this.addQuoteToUserStore = function(quoteCode) {
        if (quoteCode.indexOf("^") > -1) {
            if (jQuery.inArray(quoteCode, gadget.userIndexes) == -1)
                gadget.userIndexes.push(quoteCode);
        }
        else {
            if (jQuery.inArray(quoteCode, gadget.userStocks) == -1)
                gadget.userStocks.push(quoteCode);
        }
        gadget.saveUserStoreState();
    }

    this.removeQuoteFromUserStore = function(quoteCode) {
        var userIndexesPos = jQuery.inArray(quoteCode, gadget.userIndexes);
        var userStocksPos = jQuery.inArray(quoteCode, gadget.userStocks);

        if (userIndexesPos != -1) gadget.userIndexes.splice(userIndexesPos, 1);
        if (userStocksPos != -1) gadget.userStocks.splice(userStocksPos, 1);

        gadget.saveUserStoreState();
    }

    this.resetQuotesInUserStore = function() {
        gadget.userStocks = ["PETR4.SA", "VALE5.SA", "BVMF3.SA"];
        gadget.userIndexes = ["^BVSP", "^DJI", "^IXIC"];
        gadget.saveUserStoreState();

        $("#stocksList > li:gt(0)").remove();
        $("#indexesList > li:gt(0)").remove();

        $("#stocksSection, #indexesSection, #forexSection").removeClass("collapsed").addClass("expanded");
        $("#stocksList, #indexesList, #forexList").show();

        gadget.fillDefaultQuotes();
    }

    this.saveUserStoreState = function() {
        if (typeof _IG_Prefs == "function") {
            var prefs = new _IG_Prefs();
            prefs.setArray("stocks", gadget.userStocks);
            prefs.setArray("indexes", gadget.userIndexes);
        }
    }

    this.logVisit = function() {
        if (typeof _IG_Analytics == "function") {
            _IG_Analytics("UA-6250681-1", "/igquotesbr");
        }
    }
}

(function($) {
    /*
    * jNotification 1.0.0
    *
    * Copyright (c) 2009 Gustavo Baggio (tidybits@gmail.com)
    * Licensed under the MIT (MIT-LICENSE.txt)
    * http://www.opensource.org/licenses/mit-license.php
    *
    * Date: Jun 20 2009
    */
    $.fn.showNotification = function(opts) {
        if (typeof opts == "undefined") var opts = {};
        
        var closeButton = $(this).find(".close-icon-button");
        closeButton.hide();
        $(this).hide();

        $("#overlay").css("height", $(document).height()).show();
        if (opts.message) $(this).find(".message p").html(opts.message);
        
        if (opts.showCloseButton) {
            $(this).find(".message p").css("margin-right", 30);
        }

        $(this).css("top", 0).slideDown("medium",
            function() {
                if (opts.showCloseButton) {
                    var container = $(this).find(".message-container");

                    closeButton
                    .css({
                        top: (container.innerHeight() / 2 - closeButton.outerHeight() / 2),
                        left: (container.innerWidth() - closeButton.outerWidth() - 2)
                    })
                    .click(function() { $(this).parents("div.dialog").closeNotification(); })
                    .fadeIn();
                }
            }
        );
    }
    $.fn.closeNotification = function(animate) {
        if (typeof animate == "undefined" || animate)
            $(this).slideUp("medium", function() { $("#overlay").hide(); });
        else {
            $(this).hide();
            $("#overlay").hide();
        }
    }
    $.fn.showDialog = function(opts) {
        if (typeof opts == "undefined") var opts = {};

        $("#overlay").css("height", $(document).height()).show();

        if (opts.message) $(this).find(".message p").html(opts.message);
        if (opts.cancelFunction) $(this).find("button.cancel-button").click(opts.cancelFunction);
        if (opts.okFunction) $(this).find("button.ok-button").click(opts.okFunction);

        $(this).css("top", $("#limit").height() - $(this).outerHeight()).fadeIn("slow");
    }
    $.fn.closeDialog = function() {
        if (typeof animate == "undefined" || !animate)
            $(this).fadeOut("medium", function() { $("#overlay").hide(); });
        else {
            $(this).hide();
            $("#overlay").hide();
        }
    }
})(jQuery);
