
// ScoreModule._instance = null;
//document.cookie = "scoreMod=[[1234,0,1], [235,0,1], [4564,0,2]]"
//document.cookie = "";
/**********************************
Defines the scoreModule class
***********************************/
function ScoreModule(){
//	alert("current cookie:\n" + document.cookie);
	if(ScoreModule._instance){
		return ScoreModule._instance;
	}
//	alert("init");
	this._arrScoreBoards = new Array();
	this._arrTests = new Array();
	this._strServerFeedbackUrl = "";
	this._currentScore = 0;
	this._maxScore = 0;
	ScoreModule._instance = this;
}
ScoreModule.prototype._instance = null;

ScoreModule.prototype.init			= ScoreModule_init;
ScoreModule.prototype.registerScoreBoard 	= ScoreModule_registerScoreBoard;
ScoreModule.prototype.freeScoreBoard 		= ScoreModule_freeScoreBoard;
ScoreModule.prototype.reportTestResult 		= ScoreModule_reportTestResult;
ScoreModule.prototype.reportTestLoaded 		= ScoreModule_reportTestLoaded;
ScoreModule.prototype.saveTestResult 		= ScoreModule_saveTestResult;
ScoreModule.prototype.setSaveURL 		= ScoreModule_setSaveURL;
ScoreModule.prototype.save 			= ScoreModule_save;
ScoreModule.prototype.reset 			= ScoreModule_reset;
ScoreModule.prototype.loadTestsResults		= scoreModule_loadTestsResults;
ScoreModule.prototype.getTest			= ScoreModule_getTest;
ScoreModule.prototype.addTest			= ScoreModule_addTest;
ScoreModule.prototype.updateScoreBoards		= ScoreModule_updateScoreBoards;
ScoreModule.prototype.getMaxScore		= ScoreModule_getMaxScore;
ScoreModule.prototype.getCurrentScore		= ScoreModule_getCurrentScore;
ScoreModule.prototype.getNumberAnswered		= ScoreModule_getNumberAnswered;
ScoreModule.prototype.getNumberRightAnswers			= ScoreModule_getNumberRightAnswers;
ScoreModule.prototype.getTestNumber		= ScoreModule_getTestNumber;
ScoreModule.prototype.unregisterTest = ScoreModule_unregisterTest;

function ScoreModule_init(){
//	alert("ScoreModule_init");
	// load filed in tests results;
	this.loadTestsResults();
	this._maxScore = this.getMaxScore();
}

function ScoreModule_registerScoreBoard(objScoreBoard){
//	alert("ScoreModule_registerScoreBoard");
	for(var i=0; i< this._arrScoreBoards.length; i++){
		if(this._arrScoreBoards[i] == objScoreBoard){
			return;
		}
	}
	this._arrScoreBoards.push(objScoreBoard);
//	alert("scoreBoard registered");
	this.updateScoreBoards();
}

function ScoreModule_freeScoreBoard(objScoreBoard){
//	alert("ScoreModule_freeScoreBoard()\n nb of scoreBoard: " + this._arrScoreBoards.length);
	var blnFound = false;
	for(var i=0; i< this._arrScoreBoards.length; i++){
		this._arrScoreBoards[i] == objScoreBoard ? blnFound = true : null;
		if(blnFound && i>0){
			this._arrScoreBoards[i-1] = this._arrScoreBoards[i];
		}
	}
	if(blnFound){
		this._arrScoreBoards.pop();
//		alert("ScoreModule_freeScoreBoard()\n freed! \nnb of scoreBoard: " + this._arrScoreBoards.length);
	}
}

function ScoreModule_reportTestResult(id, score, attempt){
	var test = this.getTest(id);
//    alert(test +" && " + test.getAttempt() + " < " + test.getMaxAttempt());
	if(test && test.getAttempt() <= test.getMaxAttempt()){
//		alert("reportTestResult \nTest id: " + test.getId() + "\nTest score: " + test.getScore() + "\nTest attempt: " + test.getAttempt() + "\nTest maxAttempt: " + test.getMaxAttempt() + "\n Test has been answered? " + test.hasBeenAnswered());
		test.setScore(score);
		test.incAttempt();
        test.overrideRetriesCount();
//		alert("reportTestResult \nTest id: " + test.getId() + "\nTest score: " + test.getScore() + "\nTest attempt: " + test.getAttempt() + "\nTest maxAttempt: " + test.getMaxAttempt() + "\n Test has been answered? " + test.hasBeenAnswered());
//		test.setAttempt(attempt);
		this.save();
		this.updateScoreBoards();
	}
}

function ScoreModule_reportTestLoaded(objQtiWin){
		//' check if there are scoreboards, if there are none, then do nothing
		if (this._arrScoreBoards.length==0) return false;
	
		var testId = objQtiWin.frameElement.getAttribute("name").replace(/\D/g, '');
		var test = this.getTest(testId);
        test.setWindowObject(objQtiWin);
        // if all attempts have been used, then the test can not answered anymore,
        // block the inputs
        if( test.getAttempt() >= test.getMaxAttempt()){
            objQtiWin.assessmentItem.blockInput();
		}else if(test.getAttempt() > 0){
            // try to set the retries value
            var objAssItem = objQtiWin.assessmentItem;
            var tmpInt = test.getMaxAttempt() - test.getAttempt();
            objAssItem.variables.getOutcomeVar('retries').setValue(new objQtiWin.classExpression('single','integer', String(tmpInt)));
            objAssItem.printedVariables();
        }
        var divs = objQtiWin.document.body.getElementsByTagName("div");
        for(var j=0; j < divs.length; j++){
            if(divs[j].getAttribute("identifier") == "retries"){
                divs[j].innerHTML = test.getMaxAttempt() - test.getAttempt(); 
                return;
            }
        }
}

function ScoreModule_saveTestResult(){}
function ScoreModule_setSaveURL(){}


function ScoreModule_save(){
//	alert("ScoreModule_save");
	var expDate = new Date((new Date()).getTime() + 30*86400*1000); // 86400s = 1 day
//	var expDate=new Date();
//	expDate.setDate(30);
	var blnIsFirst = true;
	var c_str = "scoreMod=[";
	for(var i=0; i<this._arrTests.length; i++){
	var test = this._arrTests[i];
		if(test.hasBeenAnswered()){
//			alert("saving test " + test.getId());
			c_str += (blnIsFirst ? "" : ",");
			blnIsFirst = false;
			c_str += "[" + test.getId() + ","  + test.getScore() + ", " + test.getAttempt() + "]";
		}
	}
	c_str += "]; expires=" + expDate.toGMTString(); // + "; domain=" + document.location.href + "; secure";
//	alert("replace " + _getCookieString("scoreMod") + "\nby " + c_str + "\nin cookie string");
	var curCookieString = _getCookieString("scoreMod");
//	alert("ScoreModule_save(): \n" + curCookieString);
	if(curCookieString){
//		alert("ScoreModule_save\ncookie exists, replace it.");
		document.cookie = String(document.cookie).replace(curCookieString, c_str);
	}
	else if(!document.cookie || document.cookie == ""){
//		alert("ScoreModule_save\nno cookie defined, create it.");
		document.cookie = c_str;
	}
	else{
//		alert("ScoreModule_save\nappend to current cookie string.\n;" + c_str);
		document.cookie = c_str + ";" + String(document.cookie);
	}
	//	alert("str: " + c_str + "\ncookie:" + document.cookie);
}

function ScoreModule_reset(){
	for(var i=0; i< this._arrTests.length; i++){
		this._arrTests[i].reset();
	}
	this.save();
	this.updateScoreBoards();
}

function ScoreModule_updateScoreBoards(){
	var curr_score = this.getCurrentScore();
	var nbAnswered = this.getNumberAnswered();
	var rightAnswered = this.getNumberRightAnswers();
	var nbTests = this.getTestNumber();

	for(var i=0; i< this._arrScoreBoards.length; i++){
//		alert("updating scoreBoard " + i);
		this._arrScoreBoards[i].update(curr_score, this._maxScore, nbAnswered, rightAnswered, nbTests);
	}
}
function ScoreModule_getMaxScore(){
	var retVal = 0;
	for(var i=0; i< this._arrTests.length; i++){
		retVal += Number(this._arrTests[i].getMaxScore());
	}
	return retVal;
}
function ScoreModule_getCurrentScore(){
	var retVal = 0;
	for(var i=0; i< this._arrTests.length; i++){
//		alert("score for test " + i + ": " + this._arrTests[i].getScore());
		retVal += Number(this._arrTests[i].getScore());
	}
	return retVal;
}
function ScoreModule_getTestNumber(){
	return this._arrTests.length;
}
function ScoreModule_getNumberAnswered(){
	var retVal = 0;
	for(var i=0; i< this._arrTests.length; i++){
		if(this._arrTests[i].hasBeenAnswered()) retVal++;
	}
	return retVal;
}

function ScoreModule_getNumberRightAnswers(){
	var retVal = 0;
	for(var i=0; i< this._arrTests.length; i++){
		if(this._arrTests[i].hasBeenAnswered() && this._arrTests[i].getScore() > 0) retVal++;
	}
	return retVal;
}

function ScoreModule_addTest(id, maxScore, maxAttempt){
	if(!this.getTest(id)){
		this._arrTests.push(new Test(id, maxScore, maxAttempt));
		this._maxScore = Number(this._maxScore + maxScore);
	}
}

function scoreModule_loadTestsResults(){
	var answeredTests = eval(_getCookieString("scoreMod"));
	if(!answeredTests){return false};
	for(var i=0; i< answeredTests.length; i++){
		// a testresult  is made of an array like: [id, score, attempt]
		var objTest = this.getTest(answeredTests[i][0]);
		if(objTest){
//		alert("Test Loaded !! \nTest id: " + objTest.getId() + "\nTest score: " + objTest.getScore() + "\nTest attempt: " + objTest.getAttempt() + "\nTest maxAttempt: " + objTest.getMaxAttempt());

			objTest.setScore(answeredTests[i][1]);
			objTest.setAttempt(answeredTests[i][2]);
			objTest._blnAnswered = true;
			this._currentScore = Number(this._currentScore + answeredTests[i][1]);
		}
//		alert(answeredTests[i][0] + "\n" + answeredTests[i][1]);
	}

	return true;
}

function _getCookieString(strCookieName){
	var c_start = document.cookie.indexOf(strCookieName);
	if(c_start == -1){
//		alert("cookie does not exist");
		return null;
	}
	var c_end = document.cookie.indexOf(";",c_start)
	if (c_end==-1) c_end=document.cookie.length;
	return document.cookie.substring(c_start,c_end);
}

function ScoreModule_getTest(id){
	for(var i=0; i< this._arrTests.length; i++){
		if(this._arrTests[i].getId() == id){
			return this._arrTests[i];
		}
	}
	return null;
}

function ScoreModule_unregisterTest(objWin){
    for (var i=0; i < this._arrTests.length; i++){
        if(this._arrTests[i].getWindowObject() == objWin){
            this._arrTests[i].freeWindowObj();
            return;
        }
    }
}

/**********************************
Defines the test class
***********************************/

function Test(intId, intMaxScore, intMaxAttempt){
	this._id = intId;
	this._score = 0;
	this._maxScore = intMaxScore;
	this._maxAttempt = intMaxAttempt;
	this._blnAnswered = false;
	this._attempt = 0;
    this._objWin;
}

Test.prototype.getId 		= Test_getId;
Test.prototype.setScore 	= Test_setScore;
Test.prototype.getScore 	= Test_getScore;
Test.prototype.getMaxScore 	= Test_getMaxScore;
Test.prototype.incAttempt	= Test_incAttempt;
Test.prototype.setAttempt 	= Test_setAttempt;
Test.prototype.getAttempt 	= Test_getAttempt;
Test.prototype.getMaxAttempt 	= Test_getMaxAttempt;
Test.prototype.hasBeenAnswered 	= Test_hasBeenAnswered;
Test.prototype.reset			= Test_reset;
Test.prototype.setWindowObject = Test_setWindowObject;
Test.prototype.getWindowObject = Test_getWindowObject;
Test.prototype.overrideRetriesCount = Test_overrideRetriesCount;
Test.prototype.freeWindowObj = Test_freeWindowObj;

// this last function avoids the window object to stay in memory after a test window is closed
function Test_freeWindowObj(){
    this._objWin = null;
}

function Test_overrideRetriesCount(){
    if(this._objWin){
        var divs = this._objWin.document.body.getElementsByTagName("div");
        for(var j=0; j < divs.length; j++){
            if(divs[j].getAttribute("identifier") == "retries"){
                divs[j].innerHTML = this.getMaxAttempt() - this.getAttempt(); 
                return;
            }
        }
    }
}
function Test_setWindowObject(objWin){
    this._objWin = objWin;
}
function Test_getWindowObject(){
    return this._objWin;
}
function Test_getId(){
	return this._id;
}
function Test_getScore(){
	return this._score;
}
function Test_getMaxScore(){
	return this._maxScore;
}
function Test_setScore(val){
	this._blnAnswered = true;
	this._score = val;
}
function Test_setAttempt(val){
	this._blnAnswered = true;
	this._attempt = val;
}
function Test_getAttempt(){
	return this._attempt;
}
function Test_getMaxAttempt(){
	return this._maxAttempt;
}
function Test_hasBeenAnswered(){
	return this._blnAnswered;
}

function Test_incAttempt(){
	this._attempt = this._attempt + 1;
}

function Test_reset(){
	this._score = 0;
	this._attempt = 0;
	this._blnAnswered = false;
}

/*
top.myScoreMod = new ScoreModule();
top.myScoreMod.addTest(1234, 5, 1);
top.myScoreMod.addTest(235, 1, 2);
top.myScoreMod.addTest(4564, 2, 1);
top.myScoreMod.addTest(739783, 1, 3);
top.myScoreMod.init();*/
/*
top.myScoreMod.reportTestResult(1234, 4, 2);
top.myScoreMod.reportTestResult(4564, 0, 1);
top.myScoreMod.reportTestResult(45, 0, 1);*/

