
[inclScorm1.2]
//JQUIZ-SPECIFIC SCORM-RELATED JAVASCRIPT CODE

function SetScormScore(){
//Reports the current score and any other information back to the LMS
	if (API != null){
		API.LMSSetValue('cmi.core.score.raw', Score);
//Now send detailed reports about each item
		for (var i=0; i<State.length; i++){
			if (State[i] != null){
				var ItemLabel = 'Item_' + (i+1).toString();
				var ThisItemScore = '';
				var ThisItemStatus = '';
				API.LMSSetValue('cmi.objectives.' + i + '.id', 'obj'+ItemLabel);
				API.LMSSetValue('cmi.interactions.' + i + '.id', 'int'+ItemLabel);
				API.LMSSetValue('cmi.objectives.' + i + '.score.min', '0');
				API.LMSSetValue('cmi.objectives.' + i + '.score.max', '100');
				if (State[i][2] > 0){
					ThisItemScore = Math.floor(State[i][0] * 100) + '';
					ThisItemStatus = 'completed';
				}
				else{
					ThisItemScore = '0';
					ThisItemStatus = 'incomplete';
				}
				API.LMSSetValue('cmi.objectives.' + i + '.score.raw', ThisItemScore);
				API.LMSSetValue('cmi.objectives.' + i + '.status', ThisItemStatus);
				API.LMSSetValue('cmi.interactions.' + i + '.weighting', I[i][0]);
//We can only use the performance type, because we're storing multiple responses of various types.
				API.LMSSetValue('cmi.interactions.' + i + '.type', 'performance');
				API.LMSSetValue('cmi.interactions.' + i + '.student_response', State[i][5]);
			}
		}

		API.LMSCommit('');
	}
}
[/inclScorm1.2]

//JQUIZ CORE JAVASCRIPT CODE

var CurrQNum = 0;
var CorrectIndicator = '[strCorrectIndicator]';
var IncorrectIndicator = '[strIncorrectIndicator]';
var YourScoreIs = '[strYourScoreIs]';
var ContinuousScoring = [boolContinuousScoring];
var CorrectFirstTime = '[strCorrectFirstTime]';
var ShowCorrectFirstTime = [boolShowCorrectFirstTime];
var ShuffleQs = [boolShuffleQs];
var ShuffleAs = [boolShuffleAs];
var DefaultRight = '[strDefaultRight]';
var DefaultWrong = '[strDefaultWrong]';
var QsToShow = [QsToShow];
var Score = 0;
var Finished = false;
var Qs = null;
var QArray = new Array();
var ShowingAllQuestions = false;
var ShowAllQuestionsCaption = '[strShowAllQuestionsCaptionJS]';
var ShowOneByOneCaption = '[strShowOneByOneCaptionJS]';
var State = new Array();
var Feedback = '';
var TimeOver = false;
var strInstructions = '';
var Locked = false;

//The following variable can be used to add a message explaining that
//the question is finished, so no further marking will take place.
var strQuestionFinished = '';

function CompleteEmptyFeedback(){
	var QNum, ANum;
	for (QNum=0; QNum<I.length; QNum++){
//Only do this if not multi-select
		if (I[QNum][2] != '3'){
  		for (ANum = 0; ANum<I[QNum][3].length; ANum++){
  			if (I[QNum][3][ANum][1].length < 1){
  				if (I[QNum][3][ANum][2] > 0){
  					I[QNum][3][ANum][1] = DefaultRight;
  				}
  				else{
  					I[QNum][3][ANum][1] = DefaultWrong;
  				}
  			}
  		}
		}
	}
}

function SetUpQuestions(){
	var AList = new Array();
	var QList = new Array();
	var i, j;
	Qs = document.getElementById('Questions');
	while (Qs.getElementsByTagName('li').length > 0){
		QList.push(Qs.removeChild(Qs.getElementsByTagName('li')[0]));
	}
	var DumpItem = 0;
	if (QsToShow > QList.length){
		QsToShow = QList.length;
	}
	while (QsToShow < QList.length){
		DumpItem = Math.floor(QList.length*Math.random());
		for (j=DumpItem; j<(QList.length-1); j++){
			QList[j] = QList[j+1];
		}
		QList.length = QList.length-1;
	}
	if (ShuffleQs == true){
		QList = Shuffle(QList);
	}
	if (ShuffleAs == true){
		var As;
		for (var i=0; i<QList.length; i++){
			As = QList[i].getElementsByTagName('ol')[0];
			if (As != null){
  			AList.length = 0;
				while (As.getElementsByTagName('li').length > 0){
					AList.push(As.removeChild(As.getElementsByTagName('li')[0]));
				}
				AList = Shuffle(AList);
				for (j=0; j<AList.length; j++){
					As.appendChild(AList[j]);
				}
			}
		}
	}

	for (i=0; i<QList.length; i++){
		Qs.appendChild(QList[i]);
		QArray[QArray.length] = QList[i];
	}

//Show the first item
	QArray[0].style.display = '';

//Now hide all except the first item
	for (i=1; i<QArray.length; i++){
		QArray[i].style.display = 'none';
	}
	SetQNumReadout();

	SetFocusToTextbox();
}

function SetFocusToTextbox(){
//if there's a textbox, set the focus in it
	if (QArray[CurrQNum].getElementsByTagName('input')[0] != null){
		QArray[CurrQNum].getElementsByTagName('input')[0].focus();
//and show a keypad if there is one
		if (document.getElementById('CharacterKeypad') != null){
			document.getElementById('CharacterKeypad').style.display = 'block';
		}
	}
	else{
  	if (QArray[CurrQNum].getElementsByTagName('textarea')[0] != null){
  		QArray[CurrQNum].getElementsByTagName('textarea')[0].focus();
//and show a keypad if there is one
			if (document.getElementById('CharacterKeypad') != null){
				document.getElementById('CharacterKeypad').style.display = 'block';
			}
		}
//This added for 6.0.4.11: hide accented character buttons if no textbox
		else{
			if (document.getElementById('CharacterKeypad') != null){
				document.getElementById('CharacterKeypad').style.display = 'none';
			}
		}
	}
}

function ChangeQ(ChangeBy){
//The following line prevents moving to another question until the current
//question is answered correctly. Uncomment it to enable this behaviour.
//	if (State[CurrQNum][0] == -1){return;}
	if (((CurrQNum + ChangeBy) < 0)||((CurrQNum + ChangeBy) >= QArray.length)){return;}
	QArray[CurrQNum].style.display = 'none';
	CurrQNum += ChangeBy;
	QArray[CurrQNum].style.display = '';
//Undocumented function added 10/12/2004
	ShowSpecialReadingForQuestion();
	SetQNumReadout();
	SetFocusToTextbox();
}

var HiddenReadingShown = false;
function ShowSpecialReadingForQuestion(){
//Undocumented function for showing specific reading text elements which change with each question
//Added on 10/12/2004
	if (document.getElementById('ReadingDiv') != null){
		if (HiddenReadingShown == true){
			document.getElementById('ReadingDiv').innerHTML = '';
		}
		if (QArray[CurrQNum] != null){
//Fix for 6.0.4.25
			var Children = QArray[CurrQNum].getElementsByTagName('div');
			for (var i=0; i<Children.length; i++){
			if (Children[i].className=="HiddenReading"){
					document.getElementById('ReadingDiv').innerHTML = Children[i].innerHTML;
					HiddenReadingShown = true;
//Hide the ShowAllQuestions button to avoid confusion
					if (document.getElementById('ShowMethodButton') != null){
						document.getElementById('ShowMethodButton').style.display = 'none';
					}
				}
			}
		}
	}
}

function SetQNumReadout(){
	document.getElementById('QNumReadout').innerHTML = (CurrQNum+1) + ' / ' + QArray.length;
	if ((CurrQNum+1) >= QArray.length){
		if (document.getElementById('NextQButton') != null){
			document.getElementById('NextQButton').style.visibility = 'hidden';
		}
	}
	else{
		if (document.getElementById('NextQButton') != null){
			document.getElementById('NextQButton').style.visibility = 'visible';
		}
	}
	if (CurrQNum <= 0){
		if (document.getElementById('PrevQButton') != null){
			document.getElementById('PrevQButton').style.visibility = 'hidden';
		}
	}
	else{
		if (document.getElementById('PrevQButton') != null){
			document.getElementById('PrevQButton').style.visibility = 'visible';
		}
	}
}

[strItemArray]

function StartUp(){
	RemoveBottomNavBarForIE();

//If there's only one question, no need for question navigation controls
	if (QsToShow < 2){
		document.getElementById('QNav').style.display = 'none';
	}

//Stash the instructions so they can be redisplayed
	strInstructions = document.getElementById('InstructionsDiv').innerHTML;

[inclScorm1.2]
	ScormStartUp();
[/inclScorm1.2]

[inclSendResults]
	GetUserName();
[/inclSendResults]

[inclPreloadImages]
	PreloadImages([PreloadImageList]);
[/inclPreloadImages]

	CompleteEmptyFeedback();

	SetUpQuestions();
	ClearTextBoxes();
	CreateStatusArray();

[inclTimer]
	setTimeout('StartTimer()', 50);
[/inclTimer]

//Check search string for q parameter
	if (document.location.search.length > 0){
		if (ShuffleQs == false){
			var JumpTo = parseInt(document.location.search.substring(1,document.location.search.length))-1;
			if (JumpTo <= QsToShow){
				ChangeQ(JumpTo);
			}
		}
	}
//Undocumented function added 10/12/2004
	ShowSpecialReadingForQuestion();
}

function ShowHideQuestions(){
	FuncBtnOut(document.getElementById('ShowMethodButton'));
	document.getElementById('ShowMethodButton').style.display = 'none';
	if (ShowingAllQuestions == false){
		for (var i=0; i<QArray.length; i++){
				QArray[i].style.display = '';
			}
		document.getElementById('Questions').style.listStyleType = 'decimal';
		document.getElementById('OneByOneReadout').style.display = 'none';
		document.getElementById('ShowMethodButton').innerHTML = ShowOneByOneCaption;
		ShowingAllQuestions = true;
	}
	else{
		for (var i=0; i<QArray.length; i++){
				if (i != CurrQNum){
					QArray[i].style.display = 'none';
				}
			}
		document.getElementById('Questions').style.listStyleType = 'none';
		document.getElementById('OneByOneReadout').style.display = '';
		document.getElementById('ShowMethodButton').innerHTML = ShowAllQuestionsCaption;
		ShowingAllQuestions = false;
	}
	document.getElementById('ShowMethodButton').style.display = 'inline';
}

function CreateStatusArray(){
	var QNum, ANum;
//For each item in the item array
	for (QNum=0; QNum<I.length; QNum++){
//Check if the question still exists (hasn't been nuked by showing a random selection)
		if (document.getElementById('Q_' + QNum) != null){
			State[QNum] = new Array();
			State[QNum][0] = -1; //Score for this q; -1 shows question not done yet
			State[QNum][1] = new Array(); //answers
			for (ANum = 0; ANum<I[QNum][3].length; ANum++){
				State[QNum][1][ANum] = 0; //answer not chosen yet; when chosen, will store its position in the series of choices
			}
			State[QNum][2] = 0; //tries at this q so far
			State[QNum][3] = 0; //incrementing percent-correct values of selected answers
			State[QNum][4] = 0; //penalties incurred for hints
			State[QNum][5] = ''; //Sequence of answers chosen by number
		}
		else{
			State[QNum] = null;
		}
	}
}

[inclMultiChoice]

function CheckMCAnswer(QNum, ANum, Btn){
//if question doesn't exist, bail
	if (State[QNum].length < 1){return;}

//Get the feedback
	Feedback = I[QNum][3][ANum][1];

//Now show feedback and bail if question already complete
	if (State[QNum][0] > -1){
//Add an extra message explaining that the question
// is finished if defined by the user
		if (strQuestionFinished.length > 0){Feedback += '<br />' + strQuestionFinished;}
//Show the feedback
		ShowMessage(Feedback);
		return;
	}

//Hide the button while processing
	Btn.style.display = 'none';

//Increment the number of tries
	State[QNum][2]++;

//Add the percent-correct value of this answer
	State[QNum][3] += I[QNum][3][ANum][3];

//Store the try number in the answer part of the State array, for tracking purposes
	State[QNum][1][ANum] = State[QNum][2];
	if (State[QNum][5].length > 0){State[QNum][5] += ' | ';}
	State[QNum][5] += String.fromCharCode(65+ANum);

//Should this answer be accepted as correct?
	if (I[QNum][3][ANum][2] < 1){
//It's wrong

//Mark the answer
		Btn.innerHTML = IncorrectIndicator;

//Remove any previous score unless exercise is finished (6.0.3.8+)
		if (Finished == false){
			WriteToInstructions(strInstructions);
		}

//Check whether this leaves just one MC answer unselected, in which case the Q is terminated
		var RemainingAnswer = FinalAnswer(QNum);
		if (RemainingAnswer > -1){
//Behave as if the last answer had been selected, but give no credit for it
//Increment the number of tries
			State[QNum][2]++;

//Calculate the score for this question
			CalculateMCQuestionScore(QNum);

//Get the overall score and add it to the feedback
			CalculateOverallScore();
			if ((ContinuousScoring == true)||(Finished == true)){
				Feedback += '<br />' + YourScoreIs + ' ' + Score + '%.';
				WriteToInstructions(YourScoreIs + ' ' + Score + '%.');
			}
		}
	}
	else{
//It's right
//Mark the answer
		Btn.innerHTML = CorrectIndicator;

//Calculate the score for this question
		CalculateMCQuestionScore(QNum);

//Get the overall score and add it to the feedback
		if (ContinuousScoring == true){
			CalculateOverallScore();
			if ((ContinuousScoring == true)||(Finished == true)){
				Feedback += '<br />' + YourScoreIs + ' ' + Score + '%.';
				WriteToInstructions(YourScoreIs + ' ' + Score + '%.');
			}
		}
	}

//Show the button again
	Btn.style.display = 'inline';

//Finally, show the feedback
	ShowMessage(Feedback);

//Check whether all questions are now done
	CheckFinished();
}

function CalculateMCQuestionScore(QNum){
	var Tries = State[QNum][2] + State[QNum][4]; //include tries and hint penalties
	var PercentCorrect = State[QNum][3];
	var TotAns = GetTotalMCAnswers(QNum);
	var HintPenalties = State[QNum][4];

//Make sure it's not already complete

	if (State[QNum][0] < 0){
//Allow for Hybrids
		if (HintPenalties >= 1){
			State[QNum][0] = 0;
		}
		else{
//This line calculates the score for this question
			if (TotAns == 1){
				State[QNum][0] = 1;
			}
			else{
				State[QNum][0] = ((TotAns-((Tries*100)/State[QNum][3]))/(TotAns-1));
			}
		}
//Fix for Safari bug added for version 6.0.3.42 (negative infinity problem)
		if ((State[QNum][0] < 0)||(State[QNum][0] == Number.NEGATIVE_INFINITY)){
			State[QNum][0] = 0;
		}
	}
}

function GetTotalMCAnswers(QNum){
	var Result = 0;
	for (var ANum=0; ANum<I[QNum][3].length; ANum++){
		if (I[QNum][3][ANum][4] == 1){ //This is an MC answer
			Result++;
		}
	}
	return Result;
}

function FinalAnswer(QNum){
	var UnchosenAnswers = 0;
	var FinalAnswer = -1;
	for (var ANum=0; ANum<I[QNum][3].length; ANum++){
		if (I[QNum][3][ANum][4] == 1){ //This is an MC answer
			if (State[QNum][1][ANum] < 1){ //This answer hasn't been chosen yet
				UnchosenAnswers++;
				FinalAnswer = ANum;
			}
		}
	}
	if (UnchosenAnswers == 1){
		return FinalAnswer;
	}
	else{
		return -1;
	}
}

[/inclMultiChoice]

[inclMultiSelect]

function CheckMultiSelAnswer(QNum){
//bail if question doesn't exist or exercise finished
	if ((State[QNum].length < 1)||(Finished == true)){return;}

//Increment the tries for this question
	State[QNum][2]++;

	var ShouldBeChecked;
	var Matches = 0;
	if (State[QNum][5].length > 0){State[QNum][5] += ' | ';}

//Check if there are any mismatches
	Feedback = '';
	var CheckBox = null;
	for (var ANum=0; ANum<I[QNum][3].length; ANum++){
		CheckBox = document.getElementById('Q_' + QNum + '_' + ANum + '_Chk');
		if (CheckBox.checked == true){
			State[QNum][5] += 'Y';
		}
		else{
			State[QNum][5] += 'N';
		}
		ShouldBeChecked = (I[QNum][3][ANum][2] == 1);
		if (ShouldBeChecked == CheckBox.checked){
			Matches++;
		}
		else{
			Feedback = I[QNum][3][ANum][1];
		}
	}
//Add the hit readout
	Feedback = Matches + ' / ' + I[QNum][3].length + '<br />' + Feedback;
	if (Matches == I[QNum][3].length){
//It's right
		CalculateMultiSelQuestionScore(QNum);
		if (ContinuousScoring == true){
			CalculateOverallScore();
			if ((ContinuousScoring == true)||(Finished == true)){
				Feedback += '<br />' + YourScoreIs + ' ' + Score + '%.';
				WriteToInstructions(YourScoreIs + ' ' + Score + '%.');
			}
		}
	}
	else{
//It's wrong -- Remove any previous score unless exercise is finished (6.0.3.8+)
		if (Finished == false){
			WriteToInstructions(strInstructions);
		}
	}

//Show the feedback
	ShowMessage(Feedback);

//Check whether all questions are now done
	CheckFinished();
}

function CalculateMultiSelQuestionScore(QNum){
	var Tries = State[QNum][2];
	var TotAns = State[QNum][1].length;

//Make sure it's not already complete
	if (State[QNum][0] < 0){
		State[QNum][0] = (TotAns - (Tries-1)) / TotAns;
		if (State[QNum][0] < 0){
			State[QNum][0] = 0;
		}
	}
}

[/inclMultiSelect]

function CalculateOverallScore(){
	var TotalWeighting = 0;
	var TotalScore = 0;

	for (var QNum=0; QNum<State.length; QNum++){
		if (State[QNum] != null){
			if (State[QNum][0] > -1){
				TotalWeighting += I[QNum][0];
				TotalScore += (I[QNum][0] * State[QNum][0]);
			}
		}
	}
	if (TotalWeighting > 0){
		Score = Math.floor((TotalScore/TotalWeighting)*100);
	}
	else{
//if TotalWeighting is 0, no questions so far have any value, so
//no penalty should be shown.
		Score = 100;
	}
}

function CheckFinished(){
	var FB = '';
	var AllDone = true;
	for (var QNum=0; QNum<State.length; QNum++){
		if (State[QNum] != null){
			if (State[QNum][0] < 0){
				AllDone = false;
			}
		}
	}
	if (AllDone == true){

//Report final score and submit if necessary
		CalculateOverallScore();
		FB = YourScoreIs + ' ' + Score + '%.';
		if (ShowCorrectFirstTime == true){
			var CFT = 0;
			for (QNum=0; QNum<State.length; QNum++){
				if (State[QNum] != null){
					if (State[QNum][0] >= 1){
						CFT++;
					}
				}
			}
			FB += '<br />' + CorrectFirstTime + ' ' + CFT + '/' + QsToShow;
		}
		WriteToInstructions(FB);

		Finished == true;
[inclTimer]
		window.clearInterval(Interval);
[/inclTimer]

[inclScorm1.2]
		if (TimeOver == true){
			SetScormTimedOut();
		}
		else{
			SetScormComplete();
		}
[/inclScorm1.2]

		TimeOver = true;
		Locked = true;

[inclSendResults]
		setTimeout('SendResults(' + Score + ')', 50);
[/inclSendResults]

		Finished = true;
		Detail = '<?xml version="1.0"?><hpnetresult><fields>';
		for (QNum=0; QNum<State.length; QNum++){
			if (State[QNum] != null){
				if (State[QNum][5].length > 0){
					Detail += '<field><fieldname>Question #' + (QNum+1) + '</fieldname><fieldtype>question-tracking</fieldtype><fieldlabel>Q ' + (QNum+1) + '</fieldlabel><fieldlabelid>QuestionTrackingField</fieldlabelid><fielddata>' + State[QNum][5] + '</fielddata></field>';
				}
			}
		}
		Detail += '</fields></hpnetresult>';
		setTimeout('Finish()', SubmissionTimeout);
	}
[inclScorm1.2]
	else{
		SetScormIncomplete();
	}
[/inclScorm1.2]
}

[inclTimer]
function TimesUp(){
	document.getElementById('Timer').innerHTML = '[strTimesUp]';
[inclPreloadImages]
	RefreshImages();
[/inclPreloadImages]
	TimeOver = true;
	Finished = true;
	ShowMessage('[strTimesUp]');

//Set all remaining scores to 0
	for (var QNum=0; QNum<State.length; QNum++){
		if (State[QNum] != null){
			if (State[QNum][0] < 0){
				State[QNum][0] = 0;
			}
		}
	}
	CheckFinished();
}
[/inclTimer]