/*
Copyright © Interactive Services 2013 - 2015 All Rights Reserved.  
No part of this code may be used, with or without modification, without prior consent from Interactive Services. 
Version 2.1, 01 March 2015
*/

var totalPagesViewed = 0;
var totalcoursePages = 0;
var manual_complete = false;


// update the progress for the current page. called by each individual page;
function updateCurrentPageProgress(intProg){
	//console.log(currentPage.src +" "+ currentPage.parent.id +" "+intProg)
	if (intProg != undefined && parseInt(intProg) > currentPage.progress){
		 currentPage.progress = parseInt(intProg);
	}
	generateTrackingData(currentPage.parent);
}

// generate tracking data for an object, that can be stored between sessions
function generateTrackingData(obj){
	//islDebug("[[generateTrackingData]] "+obj)
	if (obj.pageNodes != undefined && obj.pageNodes.length > 0 && obj.type.indexOf("_exam")==-1){
		var node_position = getArrayPosition(obj.id)
		
		if(node_position == -1){
			courseTrackingStringsArray.push("_" + obj.id)
			courseTrackingProgressArray.push("temp")
			node_position = courseTrackingProgressArray.length-1;
		}
		var numbers_string = ""; 
		for (var j=0; j < obj.pageNodes.length; j++){
			numbers_string += obj.pageNodes[j].progress +","
		}
		numbers_string = numbers_string.slice(0, numbers_string.length-1)
		courseTrackingProgressArray[node_position] = numbers_string
	}else{
		//islDebug("THIS IS AN EXAM NODE");
		var node_position = getArrayPosition(obj.id)
		islDebug("node_position: "+node_position, "green");
		if(node_position == -1){
			courseTrackingStringsArray.push("_" + obj.id)
			courseTrackingProgressArray.push(getAssScore(course, obj.type))
			//islDebug("1) getAssScore(course, obj.type): "+getAssScore(course, obj.type), "green");
		}else{
			courseTrackingProgressArray[node_position] = getAssScore(course, obj.type);
			//islDebug("2) getAssScore(course, obj.type): "+getAssScore(course, obj.type), "green");
		}
	} 
	
	var islTrackingStringArray = courseTrackingStringsArray.toString();	
	var islProgressString = "";//courseTrackingProgressArray.toString();	
	
	for(var i = 0; i<courseTrackingProgressArray.length; i++){
		islProgressString+=courseTrackingProgressArray[i]+"@";
	}
	
	islProgressString = islProgressString.slice(0, islProgressString.length-1)
	islSuspendData = islProgressString + "***" + islTrackingStringArray;
	
	//+++++++++++++++++++++++++++++++ lmsVariables +++++++++++++++++++++++++++++++++++++++++++++++++++++
	// Code to add extra data to the tracking string - variables are defined in the settings.xml file.
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	var lmsVarsArray = objCount(lmsVariables)
	if(lmsVarsArray.length>0){
		var vars_string=""
		for(var i=0; i<lmsVarsArray.length; i++){
			vars_string+= lmsVariables[lmsVarsArray[i]]+"**"
		}
		//Remove the trailing delimiters
		vars_string = vars_string.slice(0, vars_string.length-2)
		islSuspendData += "***"+vars_string;
	}
	
	checkcourseProgress();
}


function getArrayPosition(nodeId){
	var position = -1;
	for(var i=0; i<courseTrackingStringsArray.length; i++){
		//islDebug(courseTrackingStringsArray[i] +" == "+ "_"+nodeId)
		if(courseTrackingStringsArray[i]== "_"+nodeId){
			position = i;
			break;
		}
	}
	return position;

}
//++++++++++++++++++++++++++++ generateProgressFromData +++++++++++++++++++++++++++++
// Take the tracking data returned from the LMS and assign it to the course, marking
// the progress of each page to the value stored in the tracking string.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function generateProgressFromData(){
	suspend_data = unescape(jProgress)
	if (suspend_data != undefined && suspend_data.length > 1 && suspend_data.indexOf("***") > -1 ){
		islSuspendData = suspend_data;
		var tempArray = suspend_data.split("***")
		
		courseTrackingProgressArray = tempArray[0].split("@");
		courseTrackingStringsArray = tempArray[1].split(",");
		
	
		for (var i=0; i < courseTrackingStringsArray.length; i++){
			if (courseTrackingStringsArray[i].indexOf("_") == 0) {
				id = courseTrackingStringsArray[i].substr(1);
				var obj = findObjectById(course , id);
				var nodeData = courseTrackingProgressArray[i].split(",")
				
				
				if((obj.type == "pre_exam")||(obj.type == "post_exam")){
					obj.examscore = parseInt(nodeData);
				}else if (obj.pageNodes!= undefined && obj.pageNodes.length > 0){
					for (var p=0; p < obj.pageNodes.length; p++){
						obj.pageNodes[p].progress = nodeData[p];
					}
				}
			}
		}
		//+++++++++++++++++++++++++++++++ lmsVariables +++++++++++++++++++++++++++++++++++++++++++++++++++++
		// This code is to take the lms variables out of the tracking string rturned by the LMS and assign
		// the data to the relevant data objects in the lmsVariables Object.
		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		var lmsVarsNamesArray = objCount(lmsVariables)
		if(lmsVarsNamesArray.length>0){
			lmsVariablesArray = tempArray[2].split("**");
			for(var i=0; i<lmsVarsNamesArray.length; i++){
				lmsVariables[lmsVarsNamesArray[i]] = lmsVariablesArray[i]
			}
		}
	}
}



// check the progress of the pages in an object
function checkNodeProgress(node){
	var myscore = 0;
	var mytotal = 0;
	
	if (node.subNodes != undefined && node.subNodes.length > 0){
		for (var i=0; i< node.subNodes.length; i++){
			var returned=checkNodeProgress(node.subNodes[i]);
			returned = (returned==undefined) ? 0 : returned;
			myscore += returned;
		}	
		mytotal = node.subNodes.length;
	} 
	if (node.pageNodes != undefined &&node.pageNodes.length > 0){
		var totalProgressAmount = 0;
		var optionalPage = new Array()
		for (var i=0; i< node.pageNodes.length; i++){
			//+++++++++++++++++++++++ JE 18/02/11 ++++++++++++++++++++++++++++++++++++++++++++++++++
			// If a page node(or  group node) is set to optional then the user does not need view 
			// the page for the page views to be incremented.
			//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			var isOptional = false
			if(node.pageNodes[i].optional != undefined && node.pageNodes[i].optional.toLowerCase() == "on") {
				isOptional = true
				optionalPage.push(i)
			}
			
			if(node.pageNodes[i].parent!=undefined&&node.pageNodes[i].parent.optional !=undefined && node.pageNodes[i].parent.optional.toLowerCase() == "on") isOptional = true
			if(node.pageNodes[i].parent.parent!=undefined&&node.pageNodes[i].parent.parent.optional !=undefined &&node.pageNodes[i].parent.parent.optional.toLowerCase() == "on") isOptional = true
			if(node.pageNodes[i].parent.parent.parent!=undefined&&node.pageNodes[i].parent.parent.parent.optional !=undefined && node.pageNodes[i].parent.parent.parent.optional.toLowerCase() == "on") isOptional = true
			
			//totalProgressAmount = ((node.pageNodes[i].progress==2)||(node.pageNodes[i].progress==1)) ? totalProgressAmount+2 : totalProgressAmount
			totalProgressAmount = totalProgressAmount + node.pageNodes[i].progress;
		}
		
		//+++++++++++++++++++++++ JE 18/02/11 +++++++++++++++++++++++++
		// If a page node is set to optional then the user does not need view the page but the
		// indicator for the page will be set so the menu indicators are accurate.
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
		if(totalProgressAmount != 0 && optionalPage.length>0){
			for(var i=0; i<optionalPage.length; i++){
				node.pageNodes[optionalPage[i]].progress = 2
				totalProgressAmount+=2;
			}
		}
		
		//trace("node.id: "+node.id+" progress "+totalProgressAmount)
		//trace("node progress=" + Math.ceil( totalProgressAmount / node.pageNodes.length))
		//trace(node.id + ": totalProgressAmount=" + totalProgressAmount + ", node.pageNodes.length=" + node.pageNodes.length);
		var temp = (totalProgressAmount/node.pageNodes.length);
		
		if (node.type != undefined && node.type == "pre_exam"){
			var the_score = getAssScore(course, node.type)
			if(the_score >= parseInt(islCompletion.pre_exam_passmark)) myscore += 2;
			else if ((the_score !=null && the_score < parseInt(islCompletion.pre_exam_passmark) && the_score>0)||(temp > 0))myscore += 1;
			else myscore = 0;
		} else if (node.type != undefined && node.type == "post_exam"){
			var the_score = getAssScore(course, node.type)
			islDebug("PROGRESS - the_score: "+the_score)
			if(the_score >= parseInt(islCompletion.post_exam_passmark)) myscore += 2;
			else if ((the_score !=null && the_score < parseInt(islCompletion.post_exam_passmark) && the_score>0)||(temp > 0))myscore += 1;
			else myscore = 0;
		} else {
			if (temp >= 2) myscore += 2;
			else if (temp > 0) myscore += 1;
			else myscore = 0;
		}
		mytotal += 1;
	}
	
	if ( myscore > 0){
		//trace(node.id + ": myscore="+myscore+":mytotal=" + mytotal+" >>>>>>>>>>>>>>> return 1 or 2");
		if ( parseInt(myscore / mytotal)==2) return 2;
		else if (myscore > 0) return 1;
	} else {
		//trace(node.id + ": myscore="+myscore+":mytotal=" + mytotal+" <<<<<<<<<<<<<<< return 0");
		return 0;	
	}
}




function checkcourseProgress(){
	if(islCompletion.pre_assessment=="on"){var pre_assessment_score = getAssScore(course, "pre_exam");}
	if(islCompletion.post_assessment=="on"){var post_assessment_score = getAssScore(course, "post_exam");}
	if(islCompletion.manual_complete!="off"){var manually_passed = getManualCompletionStatus()}
	var pages_viewed = getPagesViewed();
	var num_required_conditions = getNumConditions();
	var num_passed_conditions = 0;
	
	var course_status = "incomplete"
	var course_score = " ";
	
	var pre_exam_condition = ((islCompletion.pre_assessment=="on")&&(pre_assessment_score!=null)&&(pre_assessment_score>=islCompletion.pre_exam_passmark)) ? true : false
	var post_exam_condition = ((islCompletion.post_assessment=="on")&&(post_assessment_score!=null)&&(post_assessment_score>=islCompletion.post_exam_passmark)) ? true : false
	var manual_complete_condition = (((islCompletion.manual_complete=="on")||(islCompletion.manual_complete.indexOf(".swf") !=-1))&&(manually_passed==true)) ? true : false
	var page_views_condition = (pages_viewed>=islCompletion.page_views) ? true : false
	
	islDebug("[PAGE VIEWS] "+pages_viewed+" >= "+islCompletion.page_views)
	
	if(pre_exam_condition == true) num_passed_conditions++;
	if(post_exam_condition == true) num_passed_conditions++;
	if(page_views_condition == true) num_passed_conditions++;
	if(manual_complete_condition == true) num_passed_conditions++;
	
	
	islDebug("[COMPLETION CONDITIONS] "+num_passed_conditions +" == "+ num_required_conditions)
	if( num_passed_conditions == num_required_conditions){
		overallcourseStatus = course_status ="completed";
	}
	
	if((islCompletion.pre_assessment=="on")&&(islCompletion.post_assessment=="off")){
		course_score = ((pre_assessment_score>=islCompletion.pre_exam_passmark)||((islCompletion.recordFailScores == "on")&&(calculatingQuiz==true))) ? pre_assessment_score : "";
	}else if((islCompletion.pre_assessment=="off")&&(islCompletion.post_assessment=="on")){
		course_score = ((post_assessment_score>=islCompletion.post_exam_passmark)||((islCompletion.recordFailScores == "on")&&(calculatingQuiz==true))) ? post_assessment_score : "";
	}else if((islCompletion.pre_assessment=="on")&&(islCompletion.post_assessment=="on")){
		course_score = ((post_assessment_score>=islCompletion.post_exam_passmark)||((islCompletion.recordFailScores == "on")&&(calculatingQuiz==true))) ? post_assessment_score : "";
	}
	
	//+++++++++++++++++++++++++ JE 25/04/08+++++++++++++++++++++++++++++++++++++
	// This is so that a score is not set before the user has completed the course.  Example: A user could take and 
	// pass the quiz first but not view all the required pages.
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	if((course_status !="completed")&&(islCompletion.recordFailScores == "off")){
		course_score = " ";
	}
	
	islDebug("["+islSuspendData+"] ["+islBookmarkTracker+"] ["+course_status+"] ["+course_score+"]")
	
	
	if (delivery == "scorm") {
		scorm_updateTracking(islSuspendData, islBookmarkTracker, course_status, course_score);
	}else if (delivery == "iln"){
		iln_updateTracking(islSuspendData, islBookmarkTracker, course_status, course_score);
	}else if (delivery == "aicc"){
		var aicc_time = getAICCTime();
		$.aicc({
        action:'set',
        score:course_score,
        time:aicc_time,
        credit:jCredit,
        location:islBookmarkTracker,
        status:course_status.slice(0,1),
        suspend_data:islSuspendData,
        response:function(r){}
    });
	}else if  (delivery == "custom") {
		//trace("++++++++++++++++++++++++++++++++ CUSTOM TRACKING SOLUTION ++++++++++++++++++++++++++++++")
	}
}


//++++++++++++++++++++++++++++ getAssScore ++++++++++++++++++++++++++++++++++++
// Recursive function to scan through the nodes to find the relevant exam node
// and find the score that was associated with it.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function getAssScore(obj, the_exam){
	if (obj.subNodes != undefined && obj.subNodes.length > 0){
		for (var k=0; k < obj.subNodes.length; k++){
			if(obj.subNodes[k].type.toLowerCase() == the_exam.toLowerCase()){
				return obj.subNodes[k].examscore
			}
			 if(obj.subNodes[k].subNodes != undefined && obj.subNodes[k].subNodes.length > 0){
			 		getAssScore(obj.subNodes[k], the_exam)
			}
		}
	}	 
}

//++++++++++++++++++++++++++++ getPagesViewedCount ++++++++++++++++++++++++++
// Recursive function to scan through the nodes to find how many of them have
// been visited and completed.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function getPagesViewedCount(obj){
	if (obj.pageNodes != undefined && obj.pageNodes.length > 0){
		for (var i=0; i < obj.pageNodes.length; i++){
			if (obj.type.indexOf("exam") == -1) {
				totalPagesViewed += (obj.pageNodes[i].progress ==2) ? 1 : 0
				totalcoursePages++;
			}
		}	
	} 
	if (obj.subNodes != undefined && obj.subNodes.length > 0){
		for (var k=0; k < obj.subNodes.length; k++){
			 getPagesViewedCount(obj.subNodes[k]); 
		}
	} 
}

//++++++++++++++++++++++++++++ getPagesViewed +++++++++++++++++++++++++++++++
// Return the percentage of pages that have been viewed in the course.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function getPagesViewed(){
	totalPagesViewed = 0;
	totalcoursePages = 0;
	
	getPagesViewedCount(course)
	//islDebug("Viewed "+totalPagesViewed+" of "+totalcoursePages)

	return_value = Math.round((totalPagesViewed/totalcoursePages)*100)
	
	return return_value
}

//++++++++++++++++++++++++++++ getNumConditions +++++++++++++++++++++++++++++
// Find the number of conditions required to pass the course
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function getNumConditions(){
	//Total starts at 1 because the number of page views is always a condition.
	var total = 1;
	if(islCompletion.pre_assessment=="on"){total++}
	if(islCompletion.post_assessment=="on"){total++}
	if((islCompletion.manual_complete=="on")||(islCompletion.manual_complete.indexOf(".swf") !=-1)){total++}
	return total;
}

function manual_finish(){
	manual_complete = true;
	checkcourseProgress();
}


//++++++++++++++++++++++++++++ getNumConditions +++++++++++++++++++++++++++++
// Find the number of conditions required to pass the course
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function getManualCompletionStatus(){
	var manul_complete_status = false
	var page;
	if(islCompletion.manual_complete.indexOf(".swf") !=-1){
		page = findPageBySrc(course, islCompletion.manual_complete);
		manul_complete_status = (page.progress == 2) ? true : false; 
	}else if(islCompletion.manual_complete=="on"){
		manul_complete_status = manual_complete;
	}	
	return manul_complete_status
}



//++++++++++++++++++++++++++++ calculateCurrentQuizScore ++++++++++++++++++++
// Calculate and return the score as a percentage for the current quiz
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function calculateCurrentQuizScore(obj){
	calculatingQuiz = true
	var totalscore = 0;
	var totalPages = 0;
	
	for (var i=0; i<obj.pageNodes.length; i++){
		if (obj.pageNodes[i].type == "question"){
			totalPages++;
			islDebug(obj.pageNodes[i].src+" has a score of "+obj.pageNodes[i].questionResult)
			totalscore += (obj.pageNodes[i].questionResult != undefined) ?  obj.pageNodes[i].questionResult : 0;
		}
	}	
	var percentage = (totalscore > 0) ? Math.ceil((totalscore/totalPages)*100) : 0
	obj.examscore = percentage;
	generateTrackingData(obj)
	return percentage;
	
}


function objCount(obj){
	tmpArray = new Array()
  for(var prop in obj){
    tmpArray.push(prop)
  }
  return tmpArray;
}


