﻿/// <reference path="/Scripts/jquery-1.3.2.min.js"/>
PredictionManager =
{
    /// <summary>
    /// Manages ajaxed predictions on the dashboard.
    /// This class consists entirely of static methods because as of yet we do not have a way to get an Anthem callback to a method
    /// of an instanced class.  Where we would normally save data as private properties, here we use the TimeFramePredict object
    /// to do that.
    /// </summary>

    //Public methods
    //------------------------------------------------------
    makePrediction: function PredictionManager$makePrediction(direction, clientId, timeFrame, symbol, associatedPollResultsClientId, associatedPollResultsVerticalClientId) {
        /// <summary>
        /// Performs an 'ajaxed' prediction.
        /// </summary>
        /// <param name="direction">The prediction direction (as TimeFramePredict.TimeFrames)</param>
        /// <param name="clientId">The ClientID of the TimeFramePrediction User Control that is calling this function</param>
        /// <param name="timeFrame">The timeframe of the prediction as int (1,7,30 or 90)</param>
        /// <param name="direction">The symbol to which the prediction applies</param>


        //Save prediction               
        Anthem_InvokeControlMethod(
                            clientId,
                            "SavePrediction",
                            [direction, timeFrame, symbol],
                            PredictionManager.makePredictionCallback
                            );


        TimeFramePredict.CurrentTimeFrame = timeFrame;
        TimeFramePredict.CurrentPredictionDirection = direction;


        //retrieve timeframe string
        var timeFrameString
        switch (timeFrame) {
            case TimeFramePredict.TimeFrames.OneDay:
                {
                    timeFrameString = TimeFramePredict.TimeFrames.OneDayString;
                    break;
                }
            case TimeFramePredict.TimeFrames.OneWeek:
                {
                    timeFrameString = TimeFramePredict.TimeFrames.OneWeekString;
                    break;
                }
            case TimeFramePredict.TimeFrames.OneMonth:
                {
                    timeFrameString = TimeFramePredict.TimeFrames.OneMonthString;
                    break;
                }
            case TimeFramePredict.TimeFrames.ThreeMonth:
                {
                    timeFrameString = TimeFramePredict.TimeFrames.ThreeMonthString;
                    break;
                }
        }

        //Remember clientId, selected timeframe ans associated Poll Results control for later callback
        TimeFramePredict.ClientId = clientId;
        TimeFramePredict.CurrentlySelectedTimeframe = timeFrame;
        TimeFramePredict.AssociatedPollResultsClientId = associatedPollResultsClientId;
        TimeFramePredict.AssociatedPollResultsVerticalClientId = associatedPollResultsVerticalClientId;
        TimeFramePredict.Symbol = symbol;

        //Set visibility on the appropriate pre-predict or post-predict panel for this timeframe
        $("#" + clientId + "_divArrows" + timeFrame).css("display", "none");
        $("#" + clientId + "_divPredicted" + timeFrame).css("display", "block");

        //clear out the 'from' section so it does not show stale data
        $("#" + clientId + "_spnFrom" + timeFrame).html("from ...");

        //set post-prediction panel to down or up
        var spnYouPredicted = $elt(clientId + "_spnYouPredicted" + timeFrame);
        if (direction == PWSConstants.PredictionDirection.Down) {
            spnYouPredicted.className = "pred-down";
            $("#" + clientId + "_spnYouPredicted" + timeFrame).html('down');
            //$("#" + clientId + "_spnUp" + timeFrame).css("display", "none");
            //$("#" + clientId + "_spnDown" + timeFrame).css("display", "block");
        }
        else {
            spnYouPredicted.className = "pred-up";
            $("#" + clientId + "_spnYouPredicted" + timeFrame).html('up');
            //$("#" + clientId + "_spnUp" + timeFrame).css("display", "block");
            //$("#" + clientId + "_spnDown" + timeFrame).css("display", "none");
        }

        //set post-prediction area to show if it is not already since at least one prediction has been made        
        //(TODO - Get page clientId from parent page)
        var clientIdArray = clientId.split("_");
        var pageId = "";
        if (clientIdArray.length > 1) {
            pageId = clientIdArray[0] + "_" + clientIdArray[1];
        }
        $("#" + pageId + "_divPostPredictionResultsArea").css("display", "block");
        $("#" + pageId + "_divPredictionBoardMidSection").css("display", "block");
        $("#" + pageId + "_divPrePredictionResultsArea").css("display", "none");

        $("#" + pageId + "_divPrePredictionTabbedElements").css("display", "none");
        $("#" + pageId + "_divPostPredictionTabbedElements").css("display", "block");

        //Set selected state of panel we just predicted to on, and the others to off.
        PredictionManager._selectPanel(timeFrame);

        //Bind the select click event to the panel for this timeframe
        //(ie only now that the arrow are gone can we bind the click event for 'selection' of the timeframe)
        $("#" + clientId + "_divPredictionPanel" + timeFrame).bind("click", { "TimeFrame": timeFrame, "ClientId": clientId, "Symbol": symbol, "AssociatedPollResultsClientId": associatedPollResultsClientId, "AssociatedPollResultsVerticalClientId": associatedPollResultsVerticalClientId }, PredictionManager.selectTimeframeEvent);

        //If there is an associated Share a Thought control, then set its height to post-prediction height
        if (TimeFramePredict.AssociatedShareAThoughtControl) {
            //TimeFramePredict.AssociatedShareAThoughtControl.setHeight(TimeFramePredict.ShareAThoughtPostPredictionHeight);
            TimeFramePredict.AssociatedShareAThoughtControl.enable();
        }

        //If there is an associated Sentiment Trend control, then show its sentiment line.
        if (TimeFramePredict.AssociatedSentimentTrendClientId != "") {
            Anthem_InvokeControlMethod(
                TimeFramePredict.AssociatedSentimentTrendClientId,
                'ShowSentiment',
                [],
                function(result) { TimeFramePredict.AssociatedSentimentTrendClientId = ""; }); // make sure this only gets run once.
        }
    },

    makePredictionCallback: function PredictionManager$makePredictionCallback(result) {
        /// <summary>
        /// The callback function for the ajax SavePrediction call.  When TimeframePredict.ascx.cs.SavePrediction is complete,
        /// this callback handler will be invoked.
        /// Sets the returned baseline price for the symbol for which the prediction was made, and makes a
        /// call to the server-side GetPollResults method to retrieve the poll results.
        /// </summary>
        /// <param name="result">The JSON result from the TimeframePredict.SavePrediction call.</param>

        //Get object from JSON return param
        if (result.value == null) {
            return;
        }
        var data = eval(result.value);
        data = data[0];

        //set baseline price in UI
        //document.getElementById(TimeFramePredict.ClientId + "_lblPrice").innerHTML = "from " + data.BaselinePrice;
        $("#" + TimeFramePredict.ClientId + "_spnFrom" + data.TimeFrame).html("from " + data.BaselinePrice)

        //Get Poll results
        if (TimeFramePredict.AssociatedPollResultsClientId != "") {
            Anthem_InvokeControlMethod(
                                    TimeFramePredict.ClientId,
                                   "GetPollResults",
                                    [data.TimeFrame, data.Symbol],
                                    PredictionManager.getPollResultsCallback
                                    );
        }
    },

    getPollResultsCallback: function PredictionManager$getPollResultsCallback(result) {
        /// <summary>
        /// Retrieves the callback from GetPollResults, receiving poll results for the operative symbol/timeframe
        /// and updates the UI accordingly.
        /// </summary>
        /// <param name="result">The result from the TimeframePredict.GetPollResults call. </param>




        //if the callback param is null, abort this routine
        if (result.value == null) {
            return;
        }
        var predictionResult = eval(result.value);
        predictionResult = predictionResult[0];

        //If a new prediction has been made before this callback was triggered, ignore 
        //this callback
        if (TimeFramePredict.CurrentlySelectedTimeframe != predictionResult.TimeFrame) {
            return
        }

        var percentUp = 0;
        var percentDown = 0;
        var pixelWidthUp = 0;
        var pixelWidthDown = 0;

        if (predictionResult.TotalPredictions != 0) {
            percentUp = (predictionResult.TotalUp / predictionResult.TotalPredictions);
            percentDown = (predictionResult.TotalDown / predictionResult.TotalPredictions);
            //determine pixel width of bar chart for up and down
            pixelWidthUp = percentUp * TimeFramePredict.PollPixelWidthFull;
            pixelWidthDown = percentDown * TimeFramePredict.PollPixelWidthFull;
        }

        percentUp *= 100;
        percentDown *= 100;

        //Day close
        var closeDay = $("#close-day");
        closeDay.html(predictionResult.CloseDay);

        //set bookcaps off if results are 0%
        $(".BarImageCap").css("width", "7px");
        if (percentUp == 0) {
            $("#" + TimeFramePredict.AssociatedPollResultsClientId + "_imgBarChartPercentUpLeft").css("width", "0px");
            $("#" + TimeFramePredict.AssociatedPollResultsClientId + "_imgBarChartPercentUpRight").css("width", "0px");
        }
        if (percentDown == 0) {
            $("#" + TimeFramePredict.AssociatedPollResultsClientId + "_imgBarChartPercentDownLeft").css("width", "0px");
            $("#" + TimeFramePredict.AssociatedPollResultsClientId + "_imgBarChartPercentDownRight").css("width", "0px");
        }

        //set poll results bar width
        $("#" + TimeFramePredict.AssociatedPollResultsClientId + "_imgBarChartPercentUp").css("width", pixelWidthUp + "px");
        $("#" + TimeFramePredict.AssociatedPollResultsClientId + "_imgBarChartPercentDown").css("width", pixelWidthDown + "px");
        $("#" + TimeFramePredict.AssociatedPollResultsClientId + "_lblPercentUp").html(Math.round(percentUp));
        $("#" + TimeFramePredict.AssociatedPollResultsClientId + "_lblPercentDown").html(Math.round(percentDown));
        $("#" + TimeFramePredict.AssociatedPollResultsClientId + "_lblDetailHeader").html(predictionResult.HeaderText);

        //show time frame in Poll Results header
        var longTimeFrameDescription = PredictionManager._getTimeFrameDescription(predictionResult.TimeFrame, TimeFramePredict.TimeFrameDescriptionType.Long);
        $("#" + TimeFramePredict.AssociatedPollResultsClientId + "_lblControlTitle").html("Community Poll Results: " + longTimeFrameDescription);

        var shortTimeFrameDescription = PredictionManager._getTimeFrameDescription(predictionResult.TimeFrame, TimeFramePredict.TimeFrameDescriptionType.Short);
        $("#scoreboard-header").html(shortTimeFrameDescription + " Predictions for Close " + predictionResult.CloseDay);

        // Update vertical poll results, if they are on the page.

        if (TimeFramePredict.AssociatedPollResultsVerticalClientId != "") {

            $("#" + TimeFramePredict.AssociatedPollResultsVerticalClientId + "_lblControlTitle").html("Poll Results: " + longTimeFrameDescription);

            if (percentUp > 0) {

                pixelHeightUp = percentUp * TimeFramePredict.PollPixelVerticalHeightFull;

                $("#" + TimeFramePredict.AssociatedPollResultsVerticalClientId + "_divPollResultsVerticalUp").css("height", pixelHeightUp + "px");

                if (percentUp < 100) {
                    $("#" + TimeFramePredict.AssociatedPollResultsVerticalClientId + "_divPollResultsVerticalDivider").css("height", pixelHeightUp + "px");
                }
                else {
                    $("#" + TimeFramePredict.AssociatedPollResultsVerticalClientId + "_divPollResultsVerticalDivider").css("height", "0px");
                }
            }
            else {
                $("#" + TimeFramePredict.AssociatedPollResultsVerticalClientId + "_divPollResultsVerticalUp").css("height", "0px");
                $("#" + TimeFramePredict.AssociatedPollResultsVerticalClientId + "_divPollResultsVerticalDivider").css("height", "0px");
            }

            $("#" + TimeFramePredict.AssociatedPollResultsVerticalClientId + "_lblPercentUp").html(Math.round(percentUp) + "%");
            $("#" + TimeFramePredict.AssociatedPollResultsVerticalClientId + "_lblPercentDown").html(Math.round(percentDown) + "%");
            $("#" + TimeFramePredict.AssociatedPollResultsVerticalClientId + "_lblDetailHeader").html('<b>' + predictionResult.HeaderText.replace(' at ', '</b><br />at ').replace(' ET', ' ET <br /><br />'));
        }




        //Update Community Scoreboard
        //Prediction Images (up or down arrows)
        TimeFramePredict.CurrentPredictionDirection = predictionResult.PredictionDirectionYou;
        var youImage = $elt(TimeFramePredict.PredictionPageClientId + "_imgYouPredictionImage");
        if (predictionResult.PredictionDirectionYou != TimeFramePredict.PredictionDirection.NotProvided) {
            youImage.src = "/images/" + PredictionManager.getDirectionalImage(predictionResult.PredictionDirectionYou);
            youImage.style.display = "block";
        }
        else {
            youImage.style.display = "none";
        }
        var communityImage = $elt(TimeFramePredict.PredictionPageClientId + "_imgCommunityPredictionImage");
        if (predictionResult.PredictionDirectionCommunity != TimeFramePredict.PredictionDirection.NotProvided) {
            communityImage.src = "/images/" + PredictionManager.getDirectionalImage(predictionResult.PredictionDirectionCommunity);
            communityImage.style.display = "block";
        }
        else {
            communityImage.style.display = "none";
        }
        if (predictionResult.FriendPredictions) {
            var friendPredictionLength = predictionResult.FriendPredictions.length
            for (var i = 0; i < friendPredictionLength; i++) {
                var friendPrediction = predictionResult.FriendPredictions[i];
                PredictionManager.updateFriendPredictionDirectionImage(friendPrediction);
            }
        }
        var superstarImage = $elt(TimeFramePredict.PredictionPageClientId + "_imgSuperstarPredictionImage");
        if (predictionResult.PredictionDirectionSuperstar != TimeFramePredict.PredictionDirection.NotProvided) {
            superstarImage.src = "/images/" + PredictionManager.getDirectionalImage(predictionResult.PredictionDirectionSuperstar);
            superstarImage.style.display = "block";
        }
        else {
            superstarImage.style.display = "none";
        }

    },

    updateFriendPredictionDirectionImage: function updateFriendPredictionDirectionImage(friendPrediction) {
        /// <summary>
        /// Updates the appropriate image, up or down, for the given PredictorId and prediction direction
        /// in the friends/I follow section of the community scoreboard
        /// </summary>
        /// <param name="friendPrediction">A friend prediction object, containing PredictorId and Direction properties for each friend</param>   
        var images = document.images;
        var imagesCount = images.length;
        for (var i = 0; i < imagesCount - 1; i++) {
            var image = images[i];

            //we hold the prediction id of the friend in the longdesc attribute of the image
            var longDesc = image.longDesc;

            //firefox reports this longDesc value prefixed with the current url, ie 'http://pws/12343' for some reason, so deal with that here
            if (longDesc.indexOf("/") > -1) {
                var longDescArray = longDesc.split("/");
                longDesc = longDescArray[longDescArray.length - 1];
            }

            if ((longDesc * 1) == friendPrediction.PredictorId) {
                image.style.display = "block";
                if (friendPrediction.Direction == PWSConstants.PredictionDirection.Up) {
                    image.src = "/images/" + TimeFramePredict.UpArrowSmall;
                }
                if (friendPrediction.Direction == PWSConstants.PredictionDirection.Down) {
                    image.src = "/images/" + TimeFramePredict.DownArrowSmall;
                }
                if (friendPrediction.Direction == PWSConstants.PredictionDirection.NotProvided) {
                    image.style.display = "none";
                }
            }
        }
    },

    getDirectionalImage: function getDirectionalImage(direction) {
        /// <summary>
        /// Given a prediction direction, returns the appropriate up or down arrow
        /// </summary>
        /// <param name="direction">The predcition direction</param>   
        if (direction == PWSConstants.PredictionDirection.Up) {
            return TimeFramePredict.UpArrow;
        }
        if (direction == PWSConstants.PredictionDirection.Down) {
            return TimeFramePredict.DownArrow;
        }
    },

    selectTimeframeEvent: function selectTimeframeEvent(e) {
        /// <summary>
        /// Used for when the event is bound client-side.  When server-side certain prediction panels are already detected
        /// to be in a post-prediction state, markup is emitteed that hooks up the onclick event of the panel to the function
        /// below: selectTimeFrame. 
        /// </summary>    
        PredictionManager.selectTimeframe(e.data.TimeFrame, e.data.ClientId, e.data.Symbol, e.data.AssociatedPollResultsClientId, e.data.AssociatedPollResultsVerticalClientId);
    },

    selectTimeframe: function PredictionManager$selectTimeframe(timeFrame, clientId, symbol, associatedPollResultsClientId, associatedPollResultsVerticalClientId) {
        /// <summary>
        /// Selects a new timeframe and updates poll results accordingly.
        /// </summary>
        /// <param name="timeFrame">The timeframe relating to the panel to set</param>
        /// <param name="clientId">the ClientId of the TimeFramePredict user control as it is appearing in the page from which this call was made</param>
        /// <param name="symbol">The operative stock symbol</param>
        /// <param name="clientId">The ClientId of the Poll Results User Control that was associatied in server-side code with the Eight Button Timerframe User Control from which this selection was made</param>

        //Set values to be picked up by callback routine
        //TODO: Figure out how to Anthem to callback to a method within an existing instance of an object
        //and then these values would be held as private properties of that object
        TimeFramePredict.CurrentlySelectedTimeframe = timeFrame;
        TimeFramePredict.AssociatedPollResultsClientId = associatedPollResultsClientId;
        TimeFramePredict.AssociatedPollResultsVerticalClientId = associatedPollResultsVerticalClientId;
        TimeFramePredict.ClientId = clientId;
        TimeFramePredict.CurrentTimeFrame = timeFrame;

        //Set selected state of panel
        PredictionManager._selectPanel(timeFrame);

        //Get Poll results
        Anthem_InvokeControlMethod(
                        clientId,
                        "GetPollResults",
                        [timeFrame, symbol],
                        PredictionManager.getPollResultsCallback
                        );
    },


    //Private methods
    //---------------------------------------------    
    _getTimeFrameDescription: function PredictionManager$_getTimeFrameDescription(timeFrame, descriptionType) {
        /// <summary>
        /// Returns the long description for a timeframe to appear after Poll Results header
        /// ie, Poll Results: In a Month
        /// </summary>

        //'convert' to 'int'
        timeFrame = timeFrame * 1;
        var isShort = (descriptionType == TimeFramePredict.TimeFrameDescriptionType.Short)

        switch (timeFrame) {
            case TimeFramePredict.TimeFrames.OneDay:
                {
                    return isShort ? "1-Day" : "In a Day";
                    break;
                }
            case TimeFramePredict.TimeFrames.OneWeek:
                {
                    return isShort ? "1-Week" : "In a Week";
                    break;
                }
            case TimeFramePredict.TimeFrames.OneMonth:
                {
                    return isShort ? "1-Month" : "In a Month";
                    break;
                }
            case TimeFramePredict.TimeFrames.ThreeMonth:
                {
                    return isShort ? "3-Month" : "In Three Months";
                    break;
                }
        }
    },

    _selectPanel: function PredictionManager$_selectPanel(timeFrame) {
        /// <summary>
        /// Selects a timeframe panel in the UI.
        /// </summary>    
        /// <param name="timeFrame">The timeframe relating to the panel to set</param
        PredictionManager._setAllPanelsOff();
        PredictionManager._setPanelSelected(timeFrame, true);
    },

    _setPanelSelected: function PredictionManager$_setPanelSelected(timeFrame, isSelected) {
        /// <summary>
        /// Sets the selection state of a single prediction panel
        /// </summary>    
        /// <param name="timeFrame">The timeframe relating to the panel to set</param>
        /// <param name="isSelected">True if the panel should be selected, false otherwise</param>

        var divPredictionPanel = $elt(TimeFramePredict.ClientId + "_divPredictionPanel" + timeFrame);
        if (divPredictionPanel) {
            if (isSelected) {
                divPredictionPanel.className = "dow-time-selected";
            }
            else {
                divPredictionPanel.className = "dow-time";
            }
        }
    },

    _setAllPanelsOff: function PredictionManager$_setAllPanelsOff() {
        /// <summary>
        /// Deselects all the prediction panels
        /// </summary>
        PredictionManager._setPanelSelected(TimeFramePredict.TimeFrames.OneDay, false);
        PredictionManager._setPanelSelected(TimeFramePredict.TimeFrames.OneWeek, false);
        PredictionManager._setPanelSelected(TimeFramePredict.TimeFrames.OneMonth, false);
        PredictionManager._setPanelSelected(TimeFramePredict.TimeFrames.ThreeMonth, false);
    }
}


//Constants and Global variables
//---------------------------------------------
TimeFramePredict = {};
TimeFramePredict.TimeFrames = { OneDay: 1, OneWeek: 7, OneMonth: 30, ThreeMonth: 90 };
TimeFramePredict.TimeFrameStrings = { OneDay: "OneDay", OneWeek: "OneWeek", OneMonth: "OneMonth", ThreeMonth: "ThreeMonth" };
TimeFramePredict.PredictionDirection = { NotProvided: -1, Down: 0, Up: 1 };
TimeFramePredict.CurrentTimeframe = 0;
TimeFramePredict.CurrentPredictionDirection = 0;
TimeFramePredict.ClientId = "";
TimeFramePredict.TimeFrameOfLastPrediction = 0;
TimeFramePredict.AssociatedPollResultsClientId = "";
TimeFramePredict.AssociatedPollResultsVerticalClientId = "";
TimeFramePredict.AssociatedSentimentTrendClientId = "";
TimeFramePredict.PollPixelWidthFull = 180;
TimeFramePredict.PollPixelVerticalHeightFull = 241;
//TimeFramePredict.ShareAThoughtPostPredictionHeight = 495;
TimeFramePredict.AssociatedShareAThoughtControl = null; //populate this on load, so we can set width
TimeFramePredict.Symbol = "";
TimeFramePredict.UpArrow = "arrow-up.gif";
TimeFramePredict.DownArrow = "arrow-down.gif";
TimeFramePredict.UpArrowSmall = "arrow-up-sml.gif";
TimeFramePredict.DownArrowSmall = "arrow-down-sml.gif";
TimeFramePredict.TimeFrameDescriptionType = { Short: 1, Full: 2};



//hover effects
function img_mouseover(ele, timeFrame) {


    //if this timeframe is in pre-prediction state (arrows are visible)
    //or it is selected, then do nothing
    if (!performHoverAction(timeFrame,ele)) {
        return;
    }

    //set container class to hover, and set cursor style to pointer
    ele.style.cursor = 'pointer';
    ele.className = 'dow-time-hover';
}

function img_mouseout(ele,timeFrame, clientID) {

    //if this timeframe is in pre-prediction state (arrows are visible)
    //or it is selected, then do nothing
    if (!performHoverAction(timeFrame,ele)) {
        return;
    }

    //set container class to standard non-hover, and set cursor style to normal
    ele.style.cursor = 'auto';
    ele.className = 'dow-time';
}


function performHoverAction(timeFrame,ele) 
{
    //if this timeframe is in pre-prediction state (arrows are visible)
    //or it is selected, then do nothing
    var arrows = $elt(TimeFramePredict.ClientId + "_divArrows" + timeFrame);
    if (arrows.style.display == "") {
        return false;
    }
    if (ele.className == "dow-time-selected") {
        return false;
    }
    return true;
}
