﻿// SCOTT.CSC.Tools.Gas.Quiz.Application

/// <reference name="MicrosoftAjax.debug.js" />
/// <reference name="MicrosoftAjaxTimer.debug.js" />
/// <reference name="MicrosoftAjaxWebForms.debug.js" />

/// <reference path="../jquery-1.2.6-vsdoc.js"/>

// Testing: (get to the results quick and check each boundary value)
// ctl00_ContentPlaceHolder1_pnl1.QuickFinish();
// ctl00_ContentPlaceHolder1_pnl1.TotalScore = 10; ctl00_ContentPlaceHolder1_pnl1.DisplayResults();
// ctl00_ContentPlaceHolder1_pnl1.TotalScore = 26; ctl00_ContentPlaceHolder1_pnl1.DisplayResults();
// ctl00_ContentPlaceHolder1_pnl1.TotalScore = 31; ctl00_ContentPlaceHolder1_pnl1.DisplayResults();
// ctl00_ContentPlaceHolder1_pnl1.TotalScore = 39; ctl00_ContentPlaceHolder1_pnl1.DisplayResults();
// ctl00_ContentPlaceHolder1_pnl1.TotalScore = 46; ctl00_ContentPlaceHolder1_pnl1.DisplayResults();
// ctl00_ContentPlaceHolder1_pnl1.TotalScore = 72; ctl00_ContentPlaceHolder1_pnl1.DisplayResults();

Type.registerNamespace('SCOTT.CSC.Tools.Gas');
Type.registerNamespace('SCOTT.CSC.Tools.Gas.Quiz');

SCOTT.CSC.Tools.Gas.Quiz.Application = function(panelId) 
{   
    var __app = this;
    this.ClientID = panelId;
    this.Selector = '#' + panelId;
    
    this.CurrentQuestionGroup = 1;
    
    this.BackgroundColor = '#fff';
    this.HighlightColor = '#e9f6fb';
    this.ErrorColor = '#f55';
    
    // inheritance (of sorts)
    SCOTT.CSC.Extend(SCOTT.CSC.Tools.Gas.Quiz.Application, SCOTT.CSC.Core);
    
    this.GasToolService = SCOTT.CSC.Tools.GasToolService;
    this.GasToolService.set_defaultUserContext(this);
    this.GasToolService.set_defaultFailedCallback(this.HandleError);
    
    this.Initialize();
    this.Start();
};

SCOTT.CSC.Tools.Gas.Quiz.Application.prototype =
{
    __type : 'SCOTT.CSC.Tools.Gas.Quiz.Application',
    Start : function()
    {
        var __app = this;
        var context = $(this.Selector);
        
        // disable for unsupported browsers
        if ($.browser.safari && parseFloat($.browser.version) < 3.1)
        {
            alert('Sorry, this version of Safari is not supported. Please upgrade to version 3.1 or later.');
            return;
        }
        else if ($.browser.mozilla && parseFloat($.browser.version) < 1.8)
        {
            // Note: Firefox 2.0 is Mozilla 1.8 and Firefox is Mozilla 1.9.
            alert('Sorry, this version of Firefox is not supported. Please upgrade to version 2.0 or later.');
            return;
        }
        else if ($.browser.msie && parseFloat($.browser.version) < 6.0)
        {
            alert('Sorry, this version of Internet Explorer is not supported. Please upgrade to version 6.0 or later.');
            return;
        }
        
        $(context).before('<div id="LoadStatus" style="display: none;"><span>Loading...</span></div>');
        this.CenterElement($('#LoadStatus').get(0));
        $('#LoadStatus').show();
        
        var onQuestionLoaded = function()
        {
            $('#LoadStatus').fadeOut(250, function()
            {
                __app.DisplayQuestions();
                
                // workaround for IE
                if ($.browser.msie)
                {
                    $('#Application .Answer').css('background-color', __app.BackgroundColor);
                }
            
                $('#Application').show();
            });
        };
        
        this.LoadQuestions(onQuestionLoaded);
        
        // Fix PNG transparency
        if ($.browser.msie)
        {
            $('#Results .MyMarker').
                add('#Results .AverageMarker').
                add('#Results .Graph .Overlays > div').
                ifixpng();
        }
    },
    AttachEvents : function()
    {
        var __app = this;
        var context = $(this.Selector);
        var i, html, selector;
        
        i = 1;
        var attachHover = function()
        {
            var j = i;
            $(this).hover(function()
            {
                // over
                $('div.Graph div.Overlays div.Overlay' + j, context).show();
            },
            function()
            {
                // out
                $('div.Graph div.Overlays div.Overlay' + j, context).hide();
            });
            i++;
        };
        
        $('.Groups .Group', context).each(attachHover);
        
        // QA testing
        var onTesting = function()
        {
            var scores = [72, 46, 39, 31, 26, 10, 50, 42, 15];
            
            html = '<div id="Testing">' +
                '<a href="javascript:void(0);" class="QuickFinish">Quick Finish</a><br /> Set Score: ';
            for (i=0;i<scores.length;i++)
            {
                html += '<a href="javascript:void(0);" class="Score' + scores[i] + '">' + scores[i] + '</a> ';
            }
            html += '</div>';
            
            $('#Application').before(html);
            
            $('#Testing .QuickFinish').click(function()
            {
                __app.QuickFinish();
            });
            
            for (i=0;i<scores.length;i++)
            {
                selector = '#Testing .Score' + scores[i];
                var onScore = function()
                {
                    var score = scores[i];
                    return function()
                    {
                        __app.TotalScore = score;
                        __app.DisplayResults();
                    };
                }();
                $(selector).click(onScore);
            }
        };
        
        $.hotkeys.add('Ctrl+Shift+t', onTesting);
        $.hotkeys.add('Ctrl+Shift+b', function()
        {
            __app.QuickFinish();
            onTesting();
        });
    },
    LoadQuestions : function(callback)
    {
        var __app = this;
        
        var onLoad = function(questions)
        {
            __app.Questions = questions;
            if (__app.IsFunction(callback))
            {
                callback();
            }
        };
        
        this.GasToolService.GetQuestions(onLoad);
    },
    DisplayQuestions : function()
    {
        var __app = this;
        var context = $(this.Selector);
        var html = '';
        var i, j, questionId, question, radioButton, answerId, answer;
        
        //html = '<div id="Questions" style="display: none;">';
        
        for (i=0;i<this.Questions.length;i++)
        {
            question = this.Questions[i];
            questionId = 'Question-' + question.ID.Value;
            html += '<div id="' + questionId + '" class="Question">' + (i+1) + '. ' + question.Text + '<br />';
            for (j=0;j<question.Answers.length;j++)
            {
                answer = question.Answers[j];
                answerId = 'Answer-' + answer.ID.Value;
                radioButton = '<input id=' + answerId + '" type="radio" name="' + questionId + '" value="' + answer.ID.Value + '" /> ';
                html += '<label for="' + answerId + '" class="Answer">' + radioButton + '<span>' + answer.Text + '</span></label><br />';
            }
            html += '</div>';
        }
        
        //html += '</div>';
        
        html += '<div class="Controls"><a href="javascript:void(0);" id="NextButton" class="Button" title="Next"><span>Next</span></a></div>';
        
//        if ($.browser.msie)
//        {
//            $('#Questions').after('<textarea id="Html"></textarea>');
//            $('#Html').val(html);
//        }
        
        $('#Questions .Inner', context).html(html);
        
        var onRadioButtonClick = function()
        {
            var name = $(this).attr('name');
            var elementId = $(this).attr('id');
            var questionId = __app.GetIntegerFromElementID(name, 'Question-');
            var answerId = __app.GetIntegerFromElementID(elementId, 'Answer-');
            var matches, question;
            
            var isMatch = function(item)
            {
                return item.ID.Value === questionId;
            };
            matches = From(__app.Questions).Where(isMatch).Select("*").GetArray();
            if (matches.length > 0)
            {
                question = matches[0];
                question.SelectedAnswerID = answerId;
            }
        };
        
        $('.Answer input[type="radio"]', context).click(onRadioButtonClick);
        
        var onClickNext = function()
        {
            var count = $('#Application .Answer input[type="radio"]:checked').length;
            if (count < (__app.CurrentQuestionGroup * 3))
            {
                alert('Please answer each question.');
            }
            else if (__app.CurrentQuestionGroup < 3)
            {
                __app.CurrentQuestionGroup++;
                __app.DisplayCurrentQuestionGroup();
            }
            else if (__app.CurrentQuestionGroup === 3)
            {
                var onGetOverallResult = function(result)
                {
                    __app.OverallResult = result;
                    __app.TotalResultsAndDisplay();
                };
            
                __app.GasToolService.GetOverallResult(onGetOverallResult);
            }
            return false;
        };
        
        $('#NextButton', context).click(onClickNext);
        
        this.DisplayCurrentQuestionGroup();
    },
    DisplayCurrentQuestionGroup : function()
    {
        var __app = this;
        var context = $(this.Selector);
        
        var max = __app.CurrentQuestionGroup * 3;
        var min = max - 2;
            
        var onEach = function()
        {
            var elementId = $(this).attr('id');
            var id = __app.GetIntegerFromElementID(elementId, 'Question-');
            
            if (id >= min && id <= max)
            {
                $(this).show();
            }
            else
            {
                $(this).hide();
            }
        };
        
        $('#Questions', context).fadeOut(100, function()
        {
            $('#Questions .Question', context).each(onEach);
            $('#Questions', context).show();
        });
        
        this.ChangeStep(__app.CurrentQuestionGroup);
    },
    TotalResultsAndDisplay : function()
    {
        var __app = this;
        var context = $(this.Selector);
        var totalScore = 0;
        
        for (i=0;i<this.Questions.length;i++)
        {
            question = this.Questions[i];
            if (question.SelectedAnswerID)
            {
                var isMatch = function(item)
                {
                    return item.ID.Value === question.SelectedAnswerID;
                };
        
                matches = From(question.Answers).Where(isMatch).Select("*").GetArray();
                if (matches.length > 0)
                {
                    answer = matches[0];
                    totalScore += answer.Points;
                }
            }
        }
        
        this.GasToolService.SaveResult(totalScore);
        
        this.TotalScore = totalScore;
        this.DisplayResults();
    },
    DisplayResults : function()
    {
        var __app = this;
        var context = $(this.Selector);
        var i, question, matches, answer, html;
        var totalScore = this.TotalScore;
        
        this.ChangeStep(4);
        
        $('#Results .Group1 .Percentage', context).html(this.OverallResult.Group1Percentage + '%');
        $('#Results .Group2 .Percentage', context).html(this.OverallResult.Group2Percentage + '%');
        $('#Results .Group3 .Percentage', context).html(this.OverallResult.Group3Percentage + '%');
        $('#Results .Group4 .Percentage', context).html(this.OverallResult.Group4Percentage + '%');
        $('#Results .Group5 .Percentage', context).html(this.OverallResult.Group5Percentage + '%');
        $('#Results .AverageResult', context).html(this.OverallResult.AverageResult);
        $('#Results .MyResult', context).html('You scored ' + totalScore + '.');
        
        // show results description
        
        //-- 1	47	72	Gas Guzzler
        //-- 2	40	46	Road Warrior
        //-- 3	32	39	Median Driver
        //-- 4	27	31	Conscientious Commuter
        //-- 5	10	26	Hyper Miler
        
        $('#Results .Descriptions .Description', context).hide();
        
        var getLeftPosition = function(score, min, max, rightPosition)
        {
            // 81px is the width of each section in the spectrum
            // the numerical gap for each group is not equal, so this formula
            // accounts for the difference by using a percentage of the width
            // based on the size of the gap. The marker is also 77px wide.
            var percentage = (score - min) / (max - min);
            var leftDistance = 81 * percentage;
            var leftPosition = rightPosition - leftDistance - 10;
            return parseInt(leftPosition + '', 10);
        };
        
        var myPercentage = totalScore / 72;
        var myLeft = 10;
        
        // ensure the score is within bounds
        if (totalScore < 10)
        {
            totalScore = 10;
        }
        if (totalScore > 72)
        {
            totalScore = 72;
        }
        
        if (totalScore >= 47)
        {
            $('#Results .Descriptions .Group1', context).show();
            myLeft = getLeftPosition(totalScore, 47, 72, 91);
        }
        else if (totalScore >= 40 && totalScore <= 46)
        {
            $('#Results .Descriptions .Group2', context).show();
            myLeft = getLeftPosition(totalScore, 40, 46, 171);
        }
        else if (totalScore >= 32 && totalScore <= 39)
        {
            $('#Results .Descriptions .Group3', context).show();
            myLeft = getLeftPosition(totalScore, 32, 39, 252);
        }
        else if (totalScore >= 27 && totalScore <= 31)
        {
            $('#Results .Descriptions .Group4', context).show();
            myLeft = getLeftPosition(totalScore, 27, 31, 333);
        }
        else if (totalScore <= 26)
        {
            $('#Results .Descriptions .Group5', context).show();
            myLeft = getLeftPosition(totalScore, 10, 26, 414);
        }
        
        var averageResult = this.OverallResult.AverageResult;
        var averageLeft = 10;
        
        // ensure the score is within bounds
        if (averageResult < 10)
        {
            averageResult = 10;
        }
        if (averageResult > 72)
        {
            averageResult = 72;
        }
        
        if (averageResult >= 47)
        {
            averageLeft = getLeftPosition(averageResult, 47, 72, 91);
        }
        else if (averageResult >= 40 && averageResult <= 46)
        {
            averageLeft = getLeftPosition(averageResult, 40, 46, 171);
        }
        else if (averageResult >= 32 && averageResult <= 39)
        {
            averageLeft = getLeftPosition(averageResult, 32, 39, 252);
        }
        else if (averageResult >= 27 && averageResult <= 31)
        {
            averageLeft = getLeftPosition(averageResult, 27, 31, 333);
        }
        else if (averageResult <= 26)
        {
            averageLeft = getLeftPosition(averageResult, 10, 26, 414);
        }
        
        $('#Results .MyMarker', context).css('left', myLeft + 'px');
        $('#Results .AverageMarker', context).css('left', averageLeft + 'px');
        
        // 98 is the max
        // .Percentage { top-margin }
        // .Bar .Top { height }
        var totalHeight, percentageTopMargin, topHeight;
        totalHeight = 98;
        
        // Group1
        topHeight = parseInt(totalHeight * (this.OverallResult.Group1Percentage / 100), 10);
        percentageTopMargin = totalHeight - topHeight;
        $('#Results .Group1 .Percentage', context).css('margin-top', percentageTopMargin + 'px');
        $('#Results .Group1 .Bar .Top', context).css('height', topHeight  + 'px');
        
        // Group2
        topHeight = parseInt(totalHeight * (this.OverallResult.Group2Percentage / 100), 10);
        percentageTopMargin = totalHeight - topHeight;
        $('#Results .Group2 .Percentage', context).css('margin-top', percentageTopMargin + 'px');
        $('#Results .Group2 .Bar .Top', context).css('height', topHeight  + 'px');
        
        // Group3
        topHeight = parseInt(totalHeight * (this.OverallResult.Group3Percentage / 100), 10);
        percentageTopMargin = totalHeight - topHeight;
        $('#Results .Group3 .Percentage', context).css('margin-top', percentageTopMargin + 'px');
        $('#Results .Group3 .Bar .Top', context).css('height', topHeight  + 'px');
        
        // Group4
        topHeight = parseInt(totalHeight * (this.OverallResult.Group4Percentage / 100), 10);
        percentageTopMargin = totalHeight - topHeight;
        $('#Results .Group4 .Percentage', context).css('margin-top', percentageTopMargin + 'px');
        $('#Results .Group4 .Bar .Top', context).css('height', topHeight  + 'px');
        
        // Group5
        topHeight = parseInt(totalHeight * (this.OverallResult.Group5Percentage / 100), 10);
        percentageTopMargin = totalHeight - topHeight;
        $('#Results .Group5 .Percentage', context).css('margin-top', percentageTopMargin + 'px');
        $('#Results .Group5 .Bar .Top', context).css('height', topHeight  + 'px');
        
        var minMarginTop = 100;
        
        $('#Results .Percentage', context).each(function()
        {
            // find the minimum margin top
            var marginTop = parseInt($(this).css('margin-top'), 10);
            if (marginTop < minMarginTop)
            {
                minMarginTop = marginTop;
            }
        });
        
        // move the graph up by setting a negative top margin
        $('#Results .Graph', context).css('margin-top', (minMarginTop * -1) + 'px');
        
        $('#Questions', context).hide();
        $('#Results', context).show();
    },
    ChangeStep : function(step)
    {
        var __app = this;
        var context = $(this.Selector);
        
        $('div.GasQuizSteps > span', context).
            removeClass('ActiveStep').
            addClass('InactiveStep').
            filter('span.Step' + step).
            addClass('ActiveStep').
            removeClass('InactiveStep');
    },
    GetIntegerFromElementID : function(elementId, prefix)
    {      
        var id = parseInt(elementId.slice(prefix.length), 10);
        return id;
    },
    QuickFinish : function()
    {
        var __app = this;
        var context = $(this.Selector);
        var i, timeout;

        // get to the results by clicking each first answer for each question and clicking Next
        for (i=1;i<=3;i++)
        {
            timeout = 500 * i;
            setTimeout(function()
            {
                $('.Question:visible', context).each(function() {$(this).find('input:first').click();});
            }, timeout);
            setTimeout(function()
            {
                $('a#NextButton', context).click();
            }, timeout + 250);
        }
    }
};
