﻿/*
Quiz files are named chap_XX_quiz.html
Answers files: chap_XX_quiz_answers.html

Data for each quiz resides in an XML file - quizX.xml (X is quiz number).

Each quiz page contains:
    1.  <a href="scripts/quizX.xml" id="quiz-location" style="display: none"></a> 
        Points to the related quiz data file. The script then loads the quiz data from this URL.
    2.  <div id="quiz"></div>
        The script generates the answers into this div.
    3.  <a href="chap_XX_quiz_answers.html" id="quiz-answers-location" ...>...</a>
        User answers are posted to this answers page.

Each answers page contains:
    1.  Same quiz URL as in quiz page (<a href="scripts/quizX.xml"...).
    2.  <div id="quiz-answers">
            <p id="quiz-status"></p><br />
        </div>
        "quiz-answers" is a placeholder for generated data about user answers.
        "quiz-status" is a placeholder for correct answers number indecator.

Quiz script is loaded via <body onload="quiz.init()">
Quiz answers script is loaded via <body onload="quiz.initAnswers()">

Answers are passed to answers page via hash "query string".

*/
var quiz={
    init:function(){
        quiz.answersLocationEl=document.getElementById("quiz-answers-location");
        quiz.answersUrl;
        if(typeof(quiz.answersLocationEl)!=undefined && typeof(quiz.answersLocationEl)!=null){
            quiz.type="questions";
            quiz.answersUrl=quiz.answersLocationEl.href;
            quiz.answersLocationEl.href=location.href;
            quiz.answersLocationEl.onclick=function(){quiz.send(); return false;};
            quiz.quizContanier=document.getElementById("quiz");
            if(typeof(quiz.quizContanier)!="object") return; 
        }
        quiz.ajaxRequest(document.getElementById('quiz-location').href); // calls the ajax function to retrieve quiz data
    },
    initAnswers:function(file){
        quiz.answersStatusEl=document.getElementById("quiz-status");
        quiz.quizContanier=document.getElementById("quiz-answers");
        if(typeof(quiz.quizContanier)!="object") return; 
        quiz.ajaxRequest(document.getElementById('quiz-location').href); // calls the ajax function to retrieve quiz data
    },
    questions:[],
    answers:[],
    quizContanier:null,
    answersStatusEl:null,
    entryQuestionTemplate: "<p class='question'>{QUESTION}</p>",
    entryAnswerTemplate: "<input type='radio' name='q{NUMBER}' value='{VALUE}' /><p class='answer'><strong>{OPTION}.</strong> {ANSWER} </p>",    
    
    answerPageTemplateOK: "<div class='mark'><img src='images/AnswerV.jpg' width='20' height='20' /> <strong>{QUESTION_NUMBER}</strong>.</div><div class='text'> <p>{QUESTION}</p> <p>Correct answer is <strong>{ANSWER_NUMBER}. {ANSWER}</strong></p></div>",
    answerPageTemplateWrong: "<div class='mark'><img src='images/AnswerX.jpg' width='20' height='20' /> <strong>{QUESTION_NUMBER}</strong>.</div><div class='text'> <p>{QUESTION}</p> <p>You answered <strong>{USER_ANSWER}.</strong> {USER_ANSWER_TEXT} <br />Correct answer is <strong>{ANSWER_NUMBER}. {ANSWER}<br /></strong></p></div>",
    answerPageStatusTemplate: "You answered {CORRECT}/{TOTAL} questions correctly."
    
}
quiz.ajaxRequest=function(quizFile){
    var http_request = false;       
    if (window.XMLHttpRequest) { // Mozilla, Safari, ...
        http_request = new XMLHttpRequest();
        if (http_request.overrideMimeType) {
            http_request.overrideMimeType('text/xml');
        }
    } else if (window.ActiveXObject) { // IE
        try {
            http_request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                http_request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {}
        }
    }
    if (!http_request) {
        return false;
    }
    http_request.onreadystatechange = function() { 
        if (http_request.readyState == 4) {
            if (http_request.status == 200) {
                if(quiz.type=="questions"){
                    quiz.parse(http_request.responseXML);
				    quiz.create(); // creates the quiz
				}else{
				    quiz.parseAnswers(http_request.responseXML); // creates answers result page
				}
            } else {
                alert('There was a problem with the request.');
            }
        }
    };
    http_request.open('GET', quizFile, true );
    http_request.send(null);
}
quiz.parse=function(xml){
    var xmlDoc=xml.getElementsByTagName("quiz"); 
    if(xmlDoc.length==0) return; //quiz not found;
    var questions=xmlDoc[0].getElementsByTagName("question"); // select all questions
    for(var i=0; i<questions.length; i++){
        newQuestion={};
        newQuestion.number=i;
        // retrieve all information about the question:
        newQuestion.answer=quiz.getNodeVal(questions[i], "answer", true); // correct answer number
        newQuestion.q=quiz.getNodeVal(questions[i], "q", false); // question text
        newQuestion.a=quiz.getNodeVal(questions[i], "a", false); // answer a text
        newQuestion.b=quiz.getNodeVal(questions[i], "b", false); // ...
        newQuestion.c=quiz.getNodeVal(questions[i], "c", false);
        newQuestion.d=quiz.getNodeVal(questions[i], "d", false);
        newQuestion.e=quiz.getNodeVal(questions[i], "e", false);
        newQuestion.f=quiz.getNodeVal(questions[i], "f", false);
        newQuestion.g=quiz.getNodeVal(questions[i], "g", false); // up to 7 answers are allowed
        quiz.questions.push(newQuestion); // put each question into array of all questions
    }
}
quiz.create=function(){
    var nums=["a","b","c","d","e","f","g"];
    var newContainer=document.createElement("ol"); // questions container
    for(var i=0; i<quiz.questions.length; i++){
        var newEntry=document.createElement("li"); // element for a single question
        newContainer.appendChild(newEntry);
        
        // generate HTML strings for question and answers based on pre-defined templates
        var q=quiz.entryQuestionTemplate.replace("{QUESTION}",quiz.questions[i].q);
        var aa=quiz.questions[i].a!=null?quiz.entryAnswerTemplate.replace("{NUMBER}",i).replace("{VALUE}","a").replace("{OPTION}","a").replace("{ANSWER}",quiz.questions[i].a):"";
        var ab=quiz.questions[i].b!=null?quiz.entryAnswerTemplate.replace("{NUMBER}",i).replace("{VALUE}","b").replace("{OPTION}","b").replace("{ANSWER}",quiz.questions[i].b):"";
        var ac=quiz.questions[i].c!=null?quiz.entryAnswerTemplate.replace("{NUMBER}",i).replace("{VALUE}","c").replace("{OPTION}","c").replace("{ANSWER}",quiz.questions[i].c):"";
        var ad=quiz.questions[i].d!=null?quiz.entryAnswerTemplate.replace("{NUMBER}",i).replace("{VALUE}","d").replace("{OPTION}","d").replace("{ANSWER}",quiz.questions[i].d):"";
        var ae=quiz.questions[i].e!=null?quiz.entryAnswerTemplate.replace("{NUMBER}",i).replace("{VALUE}","e").replace("{OPTION}","e").replace("{ANSWER}",quiz.questions[i].e):"";
        var af=quiz.questions[i].f!=null?quiz.entryAnswerTemplate.replace("{NUMBER}",i).replace("{VALUE}","f").replace("{OPTION}","f").replace("{ANSWER}",quiz.questions[i].f):"";
        var ag=quiz.questions[i].g!=null?quiz.entryAnswerTemplate.replace("{NUMBER}",i).replace("{VALUE}","g").replace("{OPTION}","g").replace("{ANSWER}",quiz.questions[i].g):"";
        newEntry.innerHTML=(q+aa+ab+ac+ad+ae+af+ag);
        
        quiz.answers.push(document.getElementsByName("q"+i));
        
    }
    quiz.quizContanier.appendChild(newContainer);
    setPageHeight(); // adjusts page height (located in funcs.js)
    
    setTimeout(function(){ // this trys to fix some wierd CSS behaviour in firefox
        var menu=document.getElementById("menu");
        var content=document.getElementById("content");
        content.style.height=quiz.quizContanier.clientHeight+100+"px";
        if(menu.scrollHeight>content.scrollHeight) {
            content.style.height=menu.scrollHeight+"px";
        }
    },200);
}
quiz.send=function(){ // sends user answers
    var unanswered=[]; // questions that the user didn't answer on
    var answered=[]; // questions answered
    var nums=["a","b","c","d","e","f","g"];
    for(var i=0; i<quiz.questions.length; i++){
        var ok=false;
        for(var j=0; j<quiz.answers[i].length; j++){
            if(quiz.answers[i][j]!=null){ 
                if(quiz.answers[i][j].checked) {
                    ok=true;
                    answered.push(nums[j]);
                }
            }
        }
        
        if(!ok) unanswered.push(quiz.questions[i]); 
    }
    if(unanswered.length>0){ // when there are unanswered questions, displays a message with question numbers
        var msg="You didn't answer the following questions: ";
        for(var k=0; k<unanswered.length; k++){
            msg+=parseInt(unanswered[k].number)+1 + ", ";
        }
        msg=msg.substring(0,msg.length-2);
        alert(msg);
        return;
    }
    location.href=quiz.answersUrl+"#"+answered.toString();
}

quiz.parseAnswers=function(xml){ // generates data about answers
    var answersQS=location.hash.replace("#",""); // gets answers from url's hash value
    var answers=answersQS.split(",");
    var correctAnswers=0;

    var questions=xml.getElementsByTagName("question"); // gets all questions from XML to compare answers
    
    for(var i=0; i<questions.length; i++){
        answer={};
        answer.number=i+1;
        answer.answerNumber=quiz.getNodeVal(questions[i], "answer", true);
        answer.question=quiz.getNodeVal(questions[i],"q",false);
        answer.answerText=quiz.getNodeVal(questions[i],answer.answerNumber,false);
        answer.userAnswerText=quiz.getNodeVal(questions[i],answers[i],false);
        answer.userAnswered=answers[i]; // the answer user sumbitted
        answer.userCorrect=(answer.userAnswered==answer.answerNumber); // did the user answer correctly?
        quiz.answers.push(answer);
        
        var newEntry=document.createElement("div");
        newEntry.className="answer";
        if(answer.userCorrect) correctAnswers++; // counts all the correct answers
        var html=(answer.userCorrect)? // generates HTML string based on template
            quiz.answerPageTemplateOK.replace("{QUESTION_NUMBER}",answer.number).replace("{QUESTION}",answer.question).replace("{ANSWER_NUMBER}",answer.answerNumber).replace("{ANSWER}",answer.answerText)
            :
            quiz.answerPageTemplateWrong.replace("{QUESTION_NUMBER}",answer.number).replace("{QUESTION}",answer.question).replace("{ANSWER_NUMBER}",answer.answerNumber).replace("{ANSWER}",answer.answerText).replace("{USER_ANSWER}",answer.userAnswered).replace("{USER_ANSWER_TEXT}",answer.userAnswerText);
        newEntry.innerHTML=html;
        quiz.quizContanier.appendChild(newEntry); // append answer node to container
        
    }
    
    // write how many questions the user answered
    quiz.answersStatusEl.innerHTML=quiz.answerPageStatusTemplate.replace("{TOTAL}",questions.length).replace("{CORRECT}",correctAnswers);

}

quiz.getNodeVal=function(node,tag,attr){ // this function extracts tag or attribute value from XML node
    if(typeof(attr)!="undefined" && attr==true){
        return node.getAttribute(tag);
    }
    var o=node.getElementsByTagName(tag);
    if(o==null || o.length==0 ||o[0].childNodes.length==0) return null;
    return o[0].firstChild.nodeValue;
}
