// quizzerjs javascript functions

// session variable

var customVars;

// session vars
var qzid;
var curq;
var questionSequenceStr;
var questionSequence;

var attempts;
var choiceDisplaySequence;
var choiceDisplaySequenceStr

var score = 0;
var newScore = 0;
var correctAnswerStr;

var screenreader = false;

// question vars
var questionType;
var vars;
var attemptPoints;
var randomizeChoices;
var question;
var standard;

// mchoice and mcorrect
var choices;
var cc;
var ccs;

// fill
var ca;
var prefix;
var suffix;

// functions

function getQueryParams() {

	var queryString = window.location.search.substring(1); 

	if (queryString == '') {
		return null;
	}
	
	// Array to store parameters
	var queryParams = new Array();
 
 	// save full query string as parameter
 	queryParams['QUERY_STRING'] = queryString;
 	
	// multi-value separator
	multivalueSeparator = ', ';
	
	if (queryString.length < 1) { return queryParams; }

	var params = queryString.split('&');
	
	for (p in params) {
		var curParam = params[p];

		var paramParts = curParam.split('=');

		// if param missing 
		if (paramParts.length == 1) {
			paramParts[1] = '';
		}
		
		// unencode value
		paramParts[1] = paramParts[1].replace('+', ' ');
		paramParts[1] = unescape(paramParts[1]);
		
		if (queryParams[paramParts[0]]) {
			// parameter already exits, append additional value
			queryParams[paramParts[0]] += multivalueSeparator + paramParts[1];
		} else {
			// create new parameter in array
			queryParams[paramParts[0]] = paramParts[1];
		}
	}
	
	return queryParams;

} // getQueryParams


function genRandomSequence(lowerBound, upperBound, sequenceCount) {

	var numRemainingValues = upperBound - lowerBound + 1;
	if (numRemainingValues < sequenceCount) {
		sequenceCount = numRemainingValues;
	}
	
	// create an array of the possible sequence index values
	var curSourceSequenceIndex = 0;
	var possibleValues = new Array;
	for (var s=0; s<numRemainingValues; s++) {
		possibleValues[s] = curSourceSequenceIndex;
		curSourceSequenceIndex++;
	}
	
	// create an array of random sequence index values	
	var randomList = new Array;
	var curDestSequenceIndex = 0;
	while (curDestSequenceIndex < sequenceCount) {
		// to not include upper bound, remove the plus one from the following
		selectedPosition = Math.floor((numRemainingValues)*Math.random());
		var selectedValue = possibleValues.splice(selectedPosition, 1);
		randomList[curDestSequenceIndex] = selectedValue;
		numRemainingValues--;
		curDestSequenceIndex++;
	}

	return randomList;

} // genRandomSequence


function genQuestionSequence(quizInfo) {

	var questionSequence = new Array;

	// if number to ask is wildcarded, set value to number of questions
	if (quizInfo["numToAsk"] == "*") {
		quizInfo["numToAsk"] = quizInfo["numQuestions"];
	} else if (quizInfo["numToAsk"] > quizInfo["numQuestions"]) {
		quizInfo["numToAsk"] = quizInfo["numQuestions"];
	}

	if (proofreading) {
		// if proofreading, ask all question in order
		quizInfo["numToAsk"] = quizInfo["numQuestions"];
		quizInfo["randomQ"] = false;
	} else if (numToAsk != null) {
		if (quizInfo["numQuestions"] >= numToAsk) {
			quizInfo["numToAsk"] = numToAsk;
		}
	}
	
	// create a random or straight number sequence
	if (quizInfo["randomQ"] == true) {
		questionSequence = genRandomSequence(0, quizInfo["numQuestions"]-1, quizInfo["numToAsk"]);
	} else {
		for (var q=0; q<quizInfo["numToAsk"]; q++) {
			questionSequence[q] = q;
		}
	}

	return questionSequence;
	
} // genQuestionSequence


function genChoiceSequence(numChoices, randomizeChoices) {

	var choiceSequence = new Array;

	if (randomizeChoices) {
		choiceSequence = genRandomSequence(0, numChoices-1, numChoices);
	} else {
		for (var c=0; c<numChoices; c++) {
			choiceSequence[c] = c;
		}
	}
	
	return choiceSequence;
	
} // genChoiceSequence


function dynamicInclude(script_filename) {
    var html_doc = document.getElementsByTagName('head').item(0);
    var js = document.createElement('script');
    js.setAttribute('language', 'javascript');
    js.setAttribute('type', 'text/javascript');
    js.setAttribute('src', script_filename);
    html_doc.appendChild(js);
    return false;
}

function getSessionData() {
	queryParams = getQueryParams();
	qzid = queryParams['qzid'];
	questionSequenceStr = queryParams['qseq'];
	questionSequence = questionSequenceStr.split(',');
	curq = parseInt(queryParams['curq']);
	attempts = parseInt(queryParams['at']);
	score = parseInt(queryParams['score']);
	if (queryParams['sr'] != null) {
		screenreader = true;
	} else {
		screenreader = false;
	}
} // getSessionData

function loadQuestion() {
	
	var curQuestionID = questionSequence[curq];
	questionType = QUIZ["questions"][curQuestionID]["questionType"];
	if ((questionType == 'mul2') || (questionType == 'mul3') || (questionType == 'mul4')){
		questionType = 'mchoice';
	}
	customVars = QUIZ["customVars"];
	attemptPoints = QUIZ["points"][questionType];
	randomizeChoices = QUIZ["randomC"];
	question = QUIZ["questions"][curQuestionID]["question"];
	choices = QUIZ["questions"][curQuestionID]["choices"]
	if (questionType == 'mchoice') {
		cc = QUIZ["questions"][curQuestionID]["correctChoice"];
	} else if (questionType == 'mcorrect') {
		ccs = QUIZ["questions"][curQuestionID]["correctChoices"];
	} else if (questionType == 'fill') {
		ca = QUIZ["questions"][curQuestionID]["correctAnswer"];
	}
	if (QUIZ["questions"][curQuestionID]["prefix"] != null) {
		prefix = QUIZ["questions"][curQuestionID]["prefix"];
	} else {
		prefix = '';
	}
	if (QUIZ["questions"][curQuestionID]["suffix"] != null) {
		suffix = QUIZ["questions"][curQuestionID]["suffix"];
	} else {
		suffix = '';
	}
	if (QUIZ["questions"][curQuestionID]["standard"] != null) {
		standard = QUIZ["questions"][curQuestionID]["standard"];
	} else {
		standard = '';
	}
}

function displayTitle() {
	document.write(QUIZ["title"]);
}

function displayFeedback() {
	var feedback;
	var correctAnswer;
	
	if ((queryParams != null) && (queryParams['fb'] != null) && (queryParams['fb'] != '')) {
		feedback = queryParams['fb'];
	}
	if ((queryParams != null) && (queryParams['ca'] != null) && (queryParams['ca'] != '')) {
		correctAnswer = decodeURIComponent(queryParams['ca']);
	}
	if (feedback == 'tr') {
		if (!proofreading) {
			// only display positive feedback if not proofreading
			document.write('<p><strong>That\'s right!</strong></p><p><strong>Your score is ' + score + '.</strong></p>');
		}
	} else if (feedback == 'ta') {
		document.write('<p><strong>Try again!</strong></p>');
	} else if (feedback == 'ca') {
		document.write('<p><strong>Sorry, that\'s not right. The correct answer is ' + correctAnswer + '.</strong></p><p><strong>Your score is ' + score + '.</strong></p>');
	}

} // displayFeedback


function displayFinalFeedback() {

	var feedback;
	var correctAnswer;
	
	if ((queryParams != null) && (queryParams['fb'] != null) && (queryParams['fb'] != '')) {
		feedback = queryParams['fb'];
	}
	if ((queryParams != null) && (queryParams['ca'] != null) && (queryParams['ca'] != '')) {
		correctAnswer = decodeURIComponent(queryParams['ca']);
	}
	if (!proofreading) {
		if (feedback == 'tr') {
			// that's right!
			document.write('<p><strong>That\'s right!</strong></p><p><strong>Your final score is ' + score + '.</strong></p>');
		} else if (feedback == 'ca') {
			// correct answer
			document.write('<p><strong>Sorry, that\'s not right. The correct answer is ' + correctAnswer + '.</strong></p><p><strong>Your final score is ' + score + '.</strong></p>');
		} else if (feedback == 'eq') {
			// end quiz
			document.write('<p><strong>Your final score is ' + score + '.</strong></p>');
		}
	} else {
		document.write('<p><strong>Quiz Over!</strong></p>');
		document.write('<p>');
		document.write('<button onclick="javascript:nextQuiz(); return false;">Next Quiz</button>\n');
		document.write('<button onclick="javascript:chooseQuiz(); return false;">Choose Quiz</button>\n');
		document.write('<button onclick="javascript:chooseGrade(); return false;">Choose Grade</button>\n');
		document.write('</p>');
	}

} // displayFinalFeedback


function displayQuestion() {
	document.write(question);
}

function displayStandard() {
	document.write(standard);
}

function displayChoices() {

	if ((queryParams == null) || (queryParams['cseq'] == null) || (queryParams['cseq'] == '')) {
		choiceDisplaySequence = genChoiceSequence(choices.length, randomizeChoices);
		choiceDisplaySequenceStr = choiceDisplaySequence.join(',');
	} else {
		choiceDisplaySequenceStr = queryParams['cseq'];
		choiceDisplaySequence = choiceDisplaySequenceStr.split(',');
	}
	
	if (screenreader) {
		displayScreenReaderChoices();
	} else {
		// display visible and proofreading choices
		displayVisibleChoices();
	}
	
} // displayChoices

function displayVisibleChoices() {
		
	if (questionType == 'mchoice') {
		document.write('<table class="answers" summary="two column layout">\n');
		for (var curDisplayChoice=0; curDisplayChoice<choiceDisplaySequence.length; curDisplayChoice++) {
			var curChoice = choiceDisplaySequence[curDisplayChoice];

			var checked = "";
			if (proofreading && curChoice == cc) {
				// check correct answer if proofreading
				checked = " checked";
			}
			document.write('<tr scope="row"><td><input type="radio" name="choices" class="button" id="choice' + curChoice + '" value="' + curChoice + '"' + checked + '/></td><td>' + choices[curChoice] + '</td></tr>\n');
		}
		document.write('</table>\n');
	} else if (questionType == 'mcorrect') {
		document.write('<table class="answers" summary="two column layout">\n');
		for (var curDisplayChoice=0; curDisplayChoice<choiceDisplaySequence.length; curDisplayChoice++) {
			var curChoice = choiceDisplaySequence[curDisplayChoice];
			var checked = "";
			if (proofreading) {
				// check correct answers if proofreading
				for (i=0; i<=ccs.length; i++) {
					if (ccs[i] == curChoice) {
						checked = " checked";
					}
				}
			}
			document.write('<tr scope="row"><td><input type="checkbox" name="choices" class="button" id="choice' + curChoice + '" value="' + curChoice + '"' + checked + '/></td><td>' + choices[curChoice] + '</td></tr>\n');
		}
		document.write('</table>\n');
	} else if (questionType == 'fill') {
		document.write('<p class="answers">\n');
		if (prefix != '') {
			document.write(prefix + ' ');
		}
		var correctAnswer = "";
		if (proofreading) {
			// display correct answer if proofreading
			var correctAnswers = ca.split(';');
			correctAnswer = correctAnswers[0];
		}
		document.write('<input type="TEXT" id="fillanswer" name="fillanswer" value="' + correctAnswer + '" />\n');
		if (suffix != '') {
			document.write(suffix + ' ');
		}
		document.write('</p>\n');
	}
	
} // displayVisibleChoices


function displayScreenReaderChoices() {
	
	if (questionType == 'mchoice') {
		document.write('<p class="answers">\n');
		for (var curDisplayChoice=0; curDisplayChoice<choiceDisplaySequence.length; curDisplayChoice++) {
			var curChoice = choiceDisplaySequence[curDisplayChoice];
			document.write('<input type="radio" name="choices" class="button" id="choice' + curChoice + '" value="' + curChoice + '"/>' + choices[curChoice] + '<br/>\n');
		}
		document.write('</p>\n');
	} else if (questionType == 'mcorrect') {
		document.write('<p class="answers">\n');
		for (var curDisplayChoice=0; curDisplayChoice<choiceDisplaySequence.length; curDisplayChoice++) {
			var curChoice = choiceDisplaySequence[curDisplayChoice];
			document.write('<input type="checkbox" name="choices" id="choice' + curChoice + '" value="' + curChoice + '"/>' + choices[curChoice] + '<br/>\n');
		}
		document.write('</p>\n');
	} else if (questionType == 'fill') {
		document.write('<p class="answers">\n');
		if (prefix != '') {
			document.write(prefix + ' ');
		}
		document.write('<input type="TEXT" id="fillanswer" name="fillanswer" value="" />\n');
		if (suffix != '') {
			document.write(suffix + ' ');
		}
		document.write('</p>\n');
	}
	
} // displayScreenReaderChoices

function checkAnswer() {

	if (questionType == 'mchoice') {
		checkMChoiceAnswer();
	} else if (questionType == 'mcorrect') {
		checkMCorrectAnswer();
	} else if (questionType == 'fill') {
		checkFillAnswer();
	} else {
		alert("ERROR: Unrecognized question type:" + questionType);
	}
	
} // checkAnswer


function checkMChoiceAnswer() {
	var choiceSelected = false;
	var correctAnswer = false;
	
	// retrieve first choice
	var curChoiceNum = 0;
	var curChoice = document.getElementById("choice" + curChoiceNum);
	while (curChoice != null) {
		if (curChoice.checked) {
			if (curChoice.value == cc.toString()) {
				correctAnswer = true;
				choiceSelected = true;
				break;
			} else {
				choiceSelected = true;
			}
		}
		
		// get next choice
		curChoiceNum++;
		curChoice = document.getElementById("choice" + curChoiceNum);
	}
	if (!choiceSelected) {
		alert('You must choose an answer.');
	} else if (correctAnswer) {
		updateScore();
		choiceDisplaySequenceStr = '';
		attempts = 0;
		displayPage('tr'); // that's right!
	} else {
		attempts++;
		if (attempts < attemptPoints.length) {
			displayPage('ta'); // try again!
		} else {
			correctAnswerStr = choices[cc];
			choiceDisplaySequenceStr = '';
			attempts = 0;
			displayPage('ca'); // correct answer is...
		}
	}

} // checkMChoiceAnswer


function checkMCorrectAnswer() {
	var choiceSelected = false;
	var incorrectAnswer = false;
	
	// create correct choices array
	var correctChoices = new Array;
	for (i=0; i<=choices.length; i++) {
		correctChoices[i] = false;
	}
	for (i=0; i<=ccs.length; i++) {
		correctChoices[ccs[i]] = true;
	}
	
	// retrieve first choice
	var curChoiceNum = 0;
	var curChoice = document.getElementById("choice" + curChoiceNum);
	while (curChoice != null) {
		if (curChoice.checked) {
			// selected a choice
			if (correctChoices[curChoice.value] == true) {
				// choice is correct and was selected by user
				choiceSelected = true;
			} else {
				// choice is incorrect, shouldn't have been selected by user
				incorrectAnswer = true;
				choiceSelected = true;
			}
		} else {
			// didn't select a choice
			if (correctChoices[curChoice.value] == false) {
				// choice is incorrect and wasn't selected by user
			} else {
				// choice is correct, should have been selected by user
				incorrectAnswer = true;
			}
		}
		
		// get next choice
		curChoiceNum++;
		curChoice = document.getElementById("choice" + curChoiceNum);
	}
	if (!choiceSelected) {
		alert('You must choose an answer.');
	} else if (incorrectAnswer == false) {
		updateScore();
		choiceDisplaySequenceStr = '';
		attempts = 0;
		displayPage('tr'); // that's right
	} else {
		attempts++;
		if (attempts < attemptPoints.length) {
			displayPage('ta'); // try again
		} else {
			choiceDisplaySequenceStr = '';
			attempts = 0;
			correctAnswerStr = choices[ccs[0]];
			if (ccs.length == 1) {
				// single choice answer
			} else if (ccs.length == 2) {
				// 2 choice answer
				correctAnswerStr += ' and ' + choices[ccs[1]];
			} else {
				// 3 or more choice answer
				for (i=1; i<ccs.length-1; i++) {
					correctAnswerStr += ', ' + choices[ccs[i]];
				}
				correctAnswerStr += ' and ' + choices[ccs[ccs.length-1]];
			}
			displayPage('ca');
		}
	}

} // checkMCorrectAnswer

function checkFillAnswer() {
	var correctAnswer = false;
	var answer;
	
	correctAnswerStr = '';
	
	// retrieve user's answer
	var answerElement = document.getElementById("fillanswer");
	var answer = answerElement.value;

	// clean up spaces
	answer = answer.replace(/\s+/g, ' ');
	answer = answer.replace(/^ /, '');
	answer = answer.replace(/ $/, '');
	answer = answer.replace(/\s*,\s*/g, ',');

	// make sure an answer was entered
	if (answer == '') {
		alert('You must enter an answer.');
	} else {
		// cycle through each answer and see if user's answer is an exact match
		var correctAnswers = ca.split(';');
		for (i=0; i<correctAnswers.length; i++) {
			var curCorrectAnswer = correctAnswers[i];
			if (correctAnswerStr == '') {
				correctAnswerStr = curCorrectAnswer;
			}
			curCorrectAnswer = curCorrectAnswer.replace(/\s*,\s*/g, ',');
			if (answer.toLowerCase() == curCorrectAnswer.toLowerCase()) {
				correctAnswer = true;
				correctAnswerStr = curCorrectAnswer;
				break;
			}
		}
		
		if (correctAnswer == true) {
			updateScore();
			choiceDisplaySequenceStr = '';
			attempts = 0;
			displayPage('tr');
		} else {
			attempts++;
			if (attempts < attemptPoints.length) {
				displayPage('ta');
			} else {
				choiceDisplaySequenceStr = '';
				attempts = 0;
				displayPage('ca');
			}
		}
	}
			
} // checkFillAnswer


function updateScore() {

	if (attempts < attemptPoints.length) {
		newScore = score + attemptPoints[attempts];
	} else {
		alert(attempts + ',' + attemptPoints.length);
	}
	
} // updateScore


function displayPage(feedback) {

	var quizFilename = 'quiz';
	var quizOverFilename = 'quiz_over';
	if (proofreading) {
		quizFilename = 'proofread';
		quizOverFilename = 'proofread_over';
	}
	
	var pageLocation;
	
	var nextq = curq;
	var nextScore = score;
	if (feedback == 'tr') {
		nextq++;
		nextScore = newScore;
	} else if (feedback == 'ca') {
		nextq++;
	}
	
	if (nextq < questionSequence.length) {
		var questionStr = questionSequence[nextq].toString();
		if (questionSequence[nextq] < 9) {
			questionStr = '0' + questionStr;
		}
		if (choiceDisplaySequenceStr != '') {
			pageLocation = quizFilename + '.html?qzid=' + qzid + '&qseq=' + questionSequenceStr + '&cseq=' + choiceDisplaySequenceStr + '&at=' + attempts.toString() + '&fb=' + feedback + '&score=' + nextScore.toString() + '&curq=' + nextq.toString();
		} else {
			pageLocation = quizFilename + '.html?qzid=' + qzid + '&qseq=' + questionSequenceStr + '&at=' + attempts.toString() + '&fb=' + feedback + '&score=' + nextScore.toString() + '&curq=' + nextq.toString();
		}
	} else {
		pageLocation = quizOverFilename + '.html?qzid=' + qzid + '&qseq=' + questionSequenceStr + '&fb=' + feedback + '&score=' + nextScore.toString() + '&GRADE=' + customVars["GRADE"];
	}

	if (feedback == 'ca') {
		pageLocation += '&ca=' + encodeURIComponent(correctAnswerStr);
	}
	
	// add relay parameters
	for (curParamNum=0; curParamNum<relayParams.length; curParamNum++) {
		var curParam = relayParams[curParamNum];
		if (queryParams[curParam] != null) {
			pageLocation += '&' + curParam + '=' + queryParams[curParam];
		}
	}
	
	// add screenreader parameter
	if (screenreader) {
		pageLocation += '&sr=1';
	}
	
	// redirect to 
	document.location = pageLocation;
	
} // displayPage


function endQuiz() {

	var quizOverFilename = 'quiz_over';
	if (proofreading) {
		quizOverFilename = 'proofread_over';
	}
	
	document.location = quizOverFilename + '.html?qzid=' + qzid + '&qseq=' + questionSequenceStr + '&fb=eq&score=' + score.toString() + '&GRADE=' + customVars["GRADE"] + '&CHAPTER=' + customVars["CHAPTER"];
	
} // endGame

function nextQuiz() {

	document.location = 'proofread_init.html?&next=1&qzid=' + queryParams["qzid"] + '&GRADE=' + queryParams["GRADE"];
	
} // nextQuiz

function chooseQuiz() {

	document.location = 'proofread_init.html?GRADE=' + queryParams["GRADE"];
	
} // chooseQuiz

function chooseGrade() {

	document.location = 'proofread_init.html';
	
} // chooseQuiz


