﻿function Question(xmlNode) {

    this.Xml;
    this.Answer;

    this.Id = function() {
        return (this.Xml.getAttribute('id'));
    }

    this.AnswerRequired = function() {
        return (this.Xml.getAttribute('AnswerRequired') != 'false');
    }

    this.SelectedAnswerHasComment = function() {
        return (this.Answer.getAttribute('comment') != null);
    }

    this.QuestionNode = function() {
        return this.Xml.getElementsByTagName('questionText')[0];
    }

    this.QuestionText = function() {
        var value = this.QuestionNode();
        if (value != null && value.childNodes[0] != null) return value.childNodes[0].nodeValue;
    }


    this.SplashImage = function() {
        return this.Xml.getAttribute('splashImage');
    }

    this.SupplementImage = function() {
        return this.Xml.getAttribute('supplementImage');
    }

    this.AnswerNodes = function() {
        return this.Xml.getElementsByTagName('answer');
    }

    this.ValidateAnswer = function() {
        if (this.AnswerRequired() && this.Answer == null) {
            return "No Answer has been selected";
        }
    }

    this.GetMediaFromAttribute = function(attribute, node) {
        var supplementAnswerImageSrc = node.getAttribute(attribute);
        if (supplementAnswerImageSrc != null) {
            switch (this.GetExtention(supplementAnswerImageSrc).toUpperCase()) {
                case "JPG":
                case "JPEG":
                case "GIF":
                    return '<img src="' + supplementAnswerImageSrc + '" alt="supplement image" />';
                default:
                    break;

            }
        }
        return null;
    }

    this.GetExtention = function(file) {
        var split = file.split('.');
        if (split.length > 0)
            return split[split.length - 1];
        return null;
    }

    this.RenderAnswerArea = function() {
        return "RenderAnswerArea not implemented yet, this shoudl be overridden by the question type!!!";
    }


    this.RenderQuestionArea = function() {
        var questionStringBuilder = this.QuestionText();
        if (this.GetMediaFromAttribute('supplementimagesrc', this.QuestionNode()) != null) {
            questionStringBuilder += '<br/>' + this.GetMediaFromAttribute('supplementimagesrc', this.QuestionNode());
        }
        return questionStringBuilder;
    }
    
    this.RenderButton = function(buttonType){
        switch (buttonType){
           case "continue":
               return "<a href='#' onclick='_core.GradeQuestion.call(_core)'><img src='/_layouts/images/rwcnavy/quiz/ContinueButton.gif' alt='continue' /></a>";
                break;
            case "complete":
                return "<button onclick='_core.GradeQuestion.call(_core)'>Complete</button>";
                break;
           case "ShowComment":
               return "<a href='#' onclick='_core.GradQuestionWithComments.call(_core)'><img src='/_layouts/images/rwcnavy/quiz/ContinueButton.gif' alt='continue' /></a>";
                break;
        }
    }


    this.Xml = xmlNode;

}

function QuestionFactory(questionXmlNode) {
    switch (questionXmlNode.getAttribute('type')) {
        case "radio":
            return new RadioQuestion(questionXmlNode);
            break;
        /*case "button":
            return new ButtonQuestion(questionXmlNode);
            break; */

        /*case "textbox":
        return new TextQuestion(questionXmlNode);
        break; */ 
    }
}

//RadioQuestion inherits from Question using Parasitic Inheritance pattern
function RadioQuestion(xmlNode) {

    var _question = new Question(xmlNode);

    _question.SetSelectedAnswer = function(answer) {
        for (var i = 0; i < this.AnswerNodes().length; i++) {
            var id = this.AnswerNodes()[i].getAttribute('id');
            if (id == answer) {
                this.Answer = this.AnswerNodes()[i];
                $("#Answer-" + id).addClass("Selected")
            }
            else {
                $("#Answer-" + id).removeClass("Selected")
            }

        }
        return this.Answer;
    }


    _question.RenderAnswerArea = function() {
        var answerStringBuilder = "";
        for (var i = 0; i < this.AnswerNodes().length; i++) {
            var answerNode = this.AnswerNodes()[i];
            var id = answerNode.getAttribute('id');

            answerStringBuilder += '<div class="Answer" id="Answer-' + id + '" onclick="_core.SelectAnswer.call(_core, \'' + id + '\')">';
            answerStringBuilder += '<a href="#" ID="ie6Enabler"><div class="AnswerContent">';

            answerStringBuilder += answerNode.childNodes[0].nodeValue;

            //display supplement image for answers
            if (this.GetMediaFromAttribute('supplementimagesrc', answerNode) != null) {
                answerStringBuilder += '<br/>' + this.GetMediaFromAttribute('supplementimagesrc', answerNode);
            }
            answerStringBuilder += '</div></a>'
            answerStringBuilder += '</div>'
        }
        return answerStringBuilder;
    }

    _question.RenderComment = function() {
        if (this.Answer != null && this.Answer.getAttribute("comment") != null) {
            return this.Answer.getAttribute("comment");
        }

    }


    return _question;
}




function QuizCore(quizXmlpath, selectorprefix) {

    //private vars
    var _questionXmlDoc;
    var _questionIdx;
    var _selectorprefix = selectorprefix;

    //events for hoocking into
    var OnEnd;

    //public properties
    this.Questions;
    this.CurrentQuestion;


    this.SelectAnswer = function(answer) {
        this.ClearError();
        this.CurrentQuestion.SetSelectedAnswer(answer);
        if (this.CurrentQuestion.SelectedAnswerHasComment())
            $(_selectorprefix + " div.ButtonBar").empty().append(this.CurrentQuestion.RenderButton("ShowComment"));
        else if (_questionIdx < this.TotalQuestionsCount())
            $(_selectorprefix + " div.ButtonBar").empty().append(this.CurrentQuestion.RenderButton("continue"));
        else
            $(_selectorprefix + " div.ButtonBar").empty().append(this.CurrentQuestion.RenderButton("complete"));
    }


    this.GradQuestionWithComments = function() {

        var errors = this.CurrentQuestion.ValidateAnswer();
        if (errors != null) {
            this.HandleError(errors);
        }
        else {
            this.UpdateProgress();
            $(_selectorprefix + " .AnswerArea").empty();
            $(_selectorprefix + " .AnswerCommentArea").append(this.CurrentQuestion.RenderComment());
            $(_selectorprefix + " .AnswerCommentContainer").show(200);

            if (_questionIdx < this.TotalQuestionsCount())
                $(_selectorprefix + " div.ButtonBar").empty().append(this.CurrentQuestion.RenderButton("continue"));
            else
                $(_selectorprefix + " div.ButtonBar").empty().append(this.CurrentQuestion.RenderButton("complete"));
        }

    }

    //functions
    this.GradeQuestion = function() {
        this.ClearError();

        //cp5: validate answer
        var errors = this.CurrentQuestion.ValidateAnswer();
        if (errors != null) {
            this.HandleError(errors);
        }
        else {
            var selectedAnswer = this.CurrentQuestion.Answer;
            this.NextQuestion();
        }
    }

    this.UpdatePlaceholders = function() {
        if (_questionXmlDoc != null) {
            var placeholderNodes = _questionXmlDoc.getElementsByTagName('placeholder');
            for (var i = 0; i < placeholderNodes.length; i++) {
                var placeholderNode = placeholderNodes[i];
                $(_selectorprefix + " ." + placeholderNode.getAttribute('name')).html(placeholderNode.childNodes[0].nodeValue);
            }
        }
    }

    this.LoadQuestions = function(path) {
        this.Debug("LoadQuestions: " + path);
        var context = this;

        _questionIdx = -1;
        this.Questions = new Array();
        this.Answers = new Array();

        jQuery.ajax({ type: 'GET', url: path, dataType: 'xml',
            success: function(xml) {
                _questionXmlDoc = xml;
                context.Debug("LoadQuestions: Got xml");
                $(_selectorprefix + " .Loading").hide();
                $(_selectorprefix + " .Start").show();
                context.UpdateProgress();
                context.UpdatePlaceholders();
            },
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                context.HandleError("Unable to load questions: " + textStatus);
            }
        });
    }

    this.TotalQuestionsCount = function() {
        if (_questionXmlDoc != null) {
            return _questionXmlDoc.getElementsByTagName('question').length;
        }
        return 0;
    }

    // CP6: Progress bar
    this.UpdateProgress = function() {
        this.Debug("UpdateProgress(): ");
        var progressBarStringBuilder = "";
        for (var i = 0; i < this.TotalQuestionsCount(); i++) {
            var question = this.Questions[i];
            if (question != null && question.Answer != null && question.Answer.getAttribute("customProgressIcon") != null)
                progressBarStringBuilder += "<img src='" +  question.Answer.getAttribute("customProgressIcon") + "' alt='(*)' />";
            else if (i<= _questionIdx)
                progressBarStringBuilder += "<img src='/_layouts/images/rwcnavy/quiz/Progress_on.gif' alt='(*)' />";
            else
                progressBarStringBuilder += "<img src='/_layouts/images/rwcnavy/quiz/Progress_off.gif' alt='( )' />";
        }
        $(_selectorprefix + " .ProgressBar").html(progressBarStringBuilder);
    }

    this.HandleError = function(errorMessage) {
        this.Debug(errorMessage);
        $(_selectorprefix + " .AnswerCommentContainer ").hide();
        this.ClearError();
        $(_selectorprefix + " .ErrorMessage").text(errorMessage);
    }

    this.ClearError = function() {
        $(_selectorprefix + " .ErrorMessage").html('&nbsp;');
    }

    this.Debug = function(message) {
        $("#DebugMessage").append(message + "<br/>");
    }

    this.DisplayEnd = function() {
        if (this.OnEnd != null) {
            this.OnEnd();
        }
        this.Debug("End");
        $(_selectorprefix + " .ProgressBar").hide();
        $(_selectorprefix + " .Start").hide();
        $(_selectorprefix + " .Questions").hide();
        $(_selectorprefix + " .End").show(400);

    }

    this.DisplayQuestion = function() {
        this.Debug("displaying question: " + _questionIdx);
        this.Debug("displaying question: " + this.CurrentQuestion.QuestionText());

        this.UpdateProgress();
        $(_selectorprefix + " .QuestionArea").empty();
        $(_selectorprefix + " .AnswerCommentArea").empty();
        $(_selectorprefix + " .AnswerCommentContainer ").hide();
        $(_selectorprefix + " .ButtonBar").empty();
        $(_selectorprefix + " .AnswerArea").empty();

        //render questions
        $(_selectorprefix + " .QuestionArea").append(this.CurrentQuestion.RenderQuestionArea());

        //render display answers
        $(_selectorprefix + " .AnswerArea").append(this.CurrentQuestion.RenderAnswerArea());

        //render button bar if question requires
        $(_selectorprefix + " .ButtonBar").append(this.CurrentQuestion.RenderButton("continue"));

        $(_selectorprefix + " .QuizContent").show();
    }


    this.StartTest = function() {
        _questionIdx = -1;
        this.Questions = new Array();
        this.NextQuestion();
    }

    this.NextQuestion = function() {

        $(_selectorprefix + " .Start").hide();
        $(_selectorprefix + " .Questions").show(400);
        $(_selectorprefix + " .ProgressBar").show();
        $(_selectorprefix + " .End").hide();

        _questionIdx++;

        var questionXml = _questionXmlDoc.getElementsByTagName('question')[_questionIdx];

        if (this.TotalQuestionsCount() > _questionIdx) {
            //creates a instance to represent the question (ie: radio, button etc)
            this.CurrentQuestion = QuestionFactory(questionXml);
            this.Questions[_questionIdx] = this.CurrentQuestion;
            this.DisplayQuestion();
        }
        else {
            this.DisplayEnd();
        }
    }
    $(_selectorprefix + " .Loading").show();
    $(_selectorprefix + " .End").hide();
    $(_selectorprefix + " .Start").hide();
    $(_selectorprefix + " .Questions").hide();
    $(_selectorprefix + " .ProgressBar").hide();
    $(_selectorprefix + " .End").hide();
    $(_selectorprefix + " .AnswerCommentContainer ").hide();

    this.LoadQuestions(quizXmlpath);

};