/* LMS tracking functions */

/*
	Function: trackingObj
	Arguments: object of initial values for parameters for internal tracking object
	Description: creates parameters for internal tracking object
	Returns: nothing
*/
function trackingObj(obj){   
   this.int_initialize = obj.int_initialize;
   this.int_lesson_location = obj.int_lesson_location;
   this.int_lesson_status = obj.int_lesson_status;
   this.int_lesson_mode = obj.int_lesson_mode;
   this.int_score_raw = obj.int_score_raw;
   this.int_student_data_max_time_allowed = obj.int_student_data_max_time_allowed;
   this.int_launch_data = obj.int_launch_data;
   this.int_suspend_data = obj.int_suspend_data;
   this.int_mastery_score = obj.int_mastery_score;
   this.int_lesson_mode = obj.int_lesson_mode;
   this.int_session_time = obj.int_session_time;   
}

/* internal tracking object */
var int_tracking = new trackingObj({
	int_initialize:'',						//boolean
	int_lesson_location:'',					//string
	int_lesson_status:'',					//string
	int_lesson_mode:'',						//string
	int_score_raw:'',						//int
	int_student_data_max_time_allowed:'',	//time
	int_launch_data:'',						//string
	int_suspend_data:'',					//string
	int_mastery_score:'',					//int
	int_lesson_mode:'',						//string
	int_session_time:''						//time
})

/* indicates if LMS finishing code has been called */
document.courseFinished = false;
/* indicates if completed or passed lesson status was just set */
document.setCourseComplete = false;
/* indicates if passing and higher score than LMS was just set */
document.setPassingScore1 = false;
document.setPassingScore2 = false;

/* number of seconds between each session time being set to lms */
document.sessionInterval = 30000;
var sessionTimeout;

/* call the LMS finish actions if the course is closed with the browser X */
$(parent.window).bind('beforeunload', function() {
	/* 20221130 Update to language selection and bookmark functionality replaced LMSAPI with parent.document.scormAPI as API is now at sco.html */
	if(in_preview_mode == false && (typeof(parent.document.scormAPI)!="undefined")){
		actionsLMSFinish();
	}
});

/*
	Function: courseInit
	Arguments: none
	Description: initial LMS calls and other initial function calls for the course when it is launched
	Returns: nothing
*/
function courseInit()
{
	/* 20221130 Update to language selection and bookmark functionality replaced LMSAPI with parent.document.scormAPI as API is now at sco.html */
	if (!parent.document.scormAPI && (lms_type != "none")) {
		/* show API not found error message if course launched from sco.html, wbtframe.html or index_dynamic.html which uses en if no language is available to obtain */
		document.selectedLang = getQueryVariable("lang");
		if (typeof(document.selectedLang) == "undefined") { document.selectedLang = "en"; }			
		/* if the course is opened by sco.html */
		if (window != parent) {
			actionsLMSError("","","apiNotFound","");
		}
		/* if the course is opened by wbtframe.html or index_dynamic.html */
		else {				
			actionsLMSError("","","apiNotFound","");
		}
	}	
	/* 20221130 Update to language selection and bookmark functionality replaced LMSAPI with parent.document.scormAPI as API is now at sco.html */
	if (!parent.document.scormAPI && (lms_type == "none") && (window == parent)) {
		/* show API not found error message if course launched from wbtframe.html or index_dynamic.html which uses en if no language is available to obtain */
		document.selectedLang = getQueryVariable("lang");
		if (typeof(document.selectedLang) == "undefined") { document.selectedLang = "en"; }
		actionsLMSError("","","apiNotFound","");
	}
	else {
		/* run course normally if launched from sco.html when parent.document.scormAPI or lms_type is NONE */
		if(!parent.document.wrapperInit){
			document.lmsInitialized = actionsLMSInitialize();
			parent.document.wrapperInit = document.lmsInitialized
		}else{
			document.lmsInitialized = parent.document.wrapperInit;
		}
		if(document.lmsInitialized) /* 20221130 Update to language selection and bookmark functionality*/
		{				
			/* start timer for session time */
			courseStartTimer();
			var less_status = actionsLMSGetLessonStatus();			
			
			/* check if the student id is blank */
			var userId = actionsLMSGetStudentId();
			document.userId = userId;
			if(userId == '') {				
				actionsLMSError("LMSGetValue","studentId","startErrorGet","");
			}
			
			/* check if the student name is blank */
			var userName = actionsLMSGetStudentName();
			document.userName = userName;
			if(userName == ''){
				actionsLMSError("LMSGetValue","studentName","startErrorGet","");
			}		
			
			/* set lesson status to incomplete */
			if ((less_status!=lms_pass_status1) && (less_status!=lms_pass_status2)) {				
				actionsLMSSetLessonStatus("incomplete",true);
				actionsLMSCommit();
			}else{
				actionsLMSSetLessonStatus("completed",false);
				actionsLMSCommit();
			}				
			
			/* obtain suspend data */
			var suspend_data = actionsLMSGetSuspendData();		
			if(suspend_data != ""){				
				/* test out: if there is a pre-test in the course */
				if (document.pretestPresent == 1 || document.topicPreTest || document.trackSections)
				{
					/* test out: obtain if the pre-test has been attempted and the topics that have been tested out of from suspend_data */
					document.pretestAttempted = suspend_data.split('|')[0];
					document.topicsPretestedOut = suspend_data.split('|')[1]//.split('%')[0];
					document.topicTestAttempted = suspend_data.split('|')[2]//.split('%')[0];
					document.sectionCompleted = suspend_data.split('|')[3].split('%')[0];
				}	
				/*if(){
					//LJ
					document.pretestAttempted = suspend_data.split('|')[0];
					document.topicsPretestedOut = suspend_data.split('|')[1].split('%')[0];
				}*/
				suspend_data = suspend_data.split('_Data:')[1];
                /* 20190102 Updated to track post-test attempts */
                document.assessAttempts = Number(suspend_data.split('|')[1]); 
				document.userBranch = Number(suspend_data.split('|')[2]);

				/* 25/03/2024 testing out of sections of content */
				document.hiddenContentArr = suspend_data.split('|')[3];
				if (document.hiddenContentArr !== ""){
					if (document.hiddenContentArr.indexOf(",") != -1){
						document.hiddenContentArr = document.hiddenContentArr.split(",");
						for (i =0; i < document.hiddenContentArr.length; i++) {
							hidePage(document.hiddenContentArr[i]); 
						}
					}
					else {
						hidePage(document.hiddenContentArr);
					}
					// 0|0000|0000|2200%_Data:11111111111111111100000000000000000000000|0|0|8,9,10,11,16,17
				}
				else {
					document.hiddenContentArr = [];
				}
				/* 25/03/2024 testing out of sections of content END */

                suspend_data = suspend_data.split('|')[0]
				/* populate tracking array for unlock functionality */
				document.trackingArr = suspend_data.split('');
				launchHover();
			}else{
				/* initialize suspend data */
				recordPercentComplete(1, document.subsectionCount, false);
				launchHover(); // 20190208 Added to unlock burger menu 
			}
			/* obtain the bookmark */
			document.lesson_location = actionsLMSGetLessonLocation();
			document.lesson_location_retrieved = true;
		}
		//console.log(int_tracking.int_lesson_status);
	} 
}


function setSessionTime(){
	if(!document.courseFinished){
		
		clearTimeout(sessionTimeout);
		
		courseWriteTimer(true);
		actionsLMSCommit();	
		
		sessionTimeout = setTimeout(setSessionTime, document.sessionInterval);
	}
}

/*
	Function: courseStartTimer
	Arguments: none
	Description: records the the start time of a course to be later used 
				 to calculate the total time spent using the course
	Returns: nothing
*/
function courseStartTimer() {   
	/* get current time */
	startTime = new Date().getTime();	
	
	sessionTimeout = setTimeout(setSessionTime, document.sessionInterval);
}

/*
	Function: courseWriteTimer
	Arguments: boolean indicator if the timer should be restarted
	Description: writes the session time to the API adapter
				 resets the timer if indicated
	Returns: nothing
*/
function courseWriteTimer(restart_timer) {	
	if (startTime != 0  && startTime != "") {
		var currentTime = new Date().getTime();
		var elapsedSeconds = ((currentTime - startTime) / 1000);
		sessionTime += elapsedSeconds;
    }
		
	if(lms_type == "scorm_1_2"){
		var formattedTime = convertSecondsToCMITimeSpan(sessionTime);
	}else if(lms_type == "scorm_2004"){
		var formattedTime = ConvertMilliSecondsIntoSCORM2004Time(sessionTime*1000);
	}
	
	actionsLMSSetSessionTime(formattedTime);	
	/* if required then restart timer */
	if (restart_timer) {
		startTime = new Date().getTime();
	} else {
		startTime = 0;
	}
}

/*
	Function: checkViewedPages
	Arguments: none
	Description: checks if all pages required have been viewed in the course
	Returns: boolean indicating if all pages required have been viewed in the course
*/
function checkViewedPages(){
	var pagesViewed = true;
	/* test out: if there is a pre-test in the course */
	if (document.pretestPresent == 1)
	{
		/* test out: obtain the status of what topics have been tested out of */
		var tempTPretestOutArr = document.topicsPretestedOut.split('');
		/* test out: if there is a pre-test in the course do not count the tested out topics when determining pages viewed */
		for (var i = 0; i < (document.topicsCount - 1); i++)
		{
			if(document.preTestPassmark == 100){
				if (tempTPretestOutArr[i] == 0)
				{					
					if(document.trackingArr[($('div.breaker:eq('+(i+1)+')').index('.section')) - 1]==0){
						pagesViewed = false;
					}
				}
			}else{
				if (document.assessPercentageScore < document.preTestPassmark){
					pagesViewed = false;
				}
			}
		}
	}
	else {	
		var completeString = '';
		var trackingString = '';
		var currentsection = $('.section');
		for(var j = 0; j < document.trackingArr.length; j++){
			if(!currentsection.eq(j).is('.testQues, .testStart, .testResults')){
				completeString+='1';
				trackingString+=document.trackingArr[j].toString();
			}
		}
		if(completeString != trackingString){
			pagesViewed = false;
		}
	}
	return pagesViewed;
}

/*
	Function: checkCourseCompletion
	Arguments: none
	Description: checks if the assessment has been passed and all pages have been viewed in the course as required and then sets the course to completed in the LMS with the highest score obtained and also sets session time
	Returns: nothing
*/
function checkCourseCompletion() {
	var lesson_status = actionsLMSGetLessonStatus();
	var score = actionsLMSGetScore();
	score = score == "" ? 0 : Number(score);
	var pagesViewed = false;	
	var passScoreObtained = false;
	var attestationComplete = true;
	/* if there is an assessment in the course */
	if (document.assessAttempted) {		
		/* set the score if higher than the LMS score */
		if (document.assessPercentageScore >= score) {
			if (document.assessPercentageScore >= document.assessPassmark)
			{
				if (document.assessPercentageScore > score) {
					document.setPassingScore1 = true;
				}	
			}	
			/* test out: if there is a pre-test in the course and it is being taken */
			if ((document.pretestPresent == 1) && document.takingPretest)
			{
				if (document.assessPercentageScore >= document.preTestPassmark)
				{					
					actionsLMSSetScore(document.assessPercentageScore);
					actionsLMSCommit();
					
				}
			}
			else {					
				actionsLMSSetScore(document.assessPercentageScore);
				actionsLMSCommit();
			}			
			score = document.assessPercentageScore;			
		}
		/* completed test message and test lock-out 2023 */
		if (document.pretestThisSession)
		{
			/* 092923 ensure the progress updates to 100% when the course is completed or passed */
			if (document.takingPretest) {
				/* if the passing score has not yet been obtained */
				if (score >= document.preTestPassmark) {
					passScoreObtained = true;
				}
			}
			/* 092923 ensure the progress updates to 100% when the course is completed or passed */
			else
			{
				/* if the passing score has not yet been obtained */
				if (score >= document.assessPassmark) {
					passScoreObtained = true;
				}
			}
		}
		else
		{
			/* if the passing score has not yet been obtained */
			if (score >= document.assessPassmark) {
				passScoreObtained = true;
			}
		}

	}
	/* completed test message and test lock-out 2023 */
	if (document.pretestThisSession)
	{
		/* 092923 ensure the progress updates to 100% when the course is completed or passed */
		if (document.takingPretest) {
			/* if the passing score has not yet been obtained */
			if (score >= document.preTestPassmark) {
				passScoreObtained = true;
			}
		}
		/* 092923 ensure the progress updates to 100% when the course is completed or passed */
		else
		{
			/* if the passing score has not yet been obtained */
			if (score >= document.assessPassmark) {
				passScoreObtained = true;
			}
		}
	}
	else
	{
		/* if the passing score has not yet been obtained */
		if (score >= document.assessPassmark) {
			passScoreObtained = true;
		}
	}
	pagesViewed = checkViewedPages();
	/* if there is an attestation and it has not yet been completed */
	if ((document.attestationPresent == 1) && !document.attestationAttempted) {
		attestationComplete = false;
	}

	/* if the attestation has been completed, the assessment has been passed and all pages have been viewed */
	if ((attestationComplete && passScoreObtained && pagesViewed) || (attestationComplete && passScoreObtained && (document.trackPagesViewed == false)) || (attestationComplete && ($('.testStart').length < 1) && pagesViewed)) {
		/* set lesson status to completed if not already passed or completed */
		if (lesson_status!=lms_pass_status1 && lesson_status!=lms_pass_status2) {
			actionsLMSSetLessonStatus("completed",true);
			actionsLMSCommit();			
		}
		/* added to commit current session time at time of completion */
		if (startTime != 0 && startTime != "") {
			var currentTime = new Date().getTime();
			var elapsedSeconds = ((currentTime - startTime) / 1000);
		}
		if(lms_type == "scorm_1_2"){
			var formattedTime = convertSecondsToCMITimeSpan(sessionTime);
		}else if(lms_type == "scorm_2004"){
			var formattedTime = ConvertMilliSecondsIntoSCORM2004Time(sessionTime*1000);
		}			
		actionsLMSSetSessionTime(formattedTime);		
	}
}

/*
	Function: doBookMark
	Arguments: the last section that was accessed
	Description: if the section has changed from the last section that was accessed 
			     then sets this new section as lesson location in the LMS
	Returns: nothing
*/
function doBookMark(lastLandscape){
	/* only set bookmark when page changes */
	/* test out: if there is a pre-test in the course */
	if (document.pretestPresent == 1)
	{
		/* test out: do not bookmark the pre-test upon leaving it */
		if (document.pretestDone) {
			if(int_tracking.int_lesson_location != lastLandscape){	
				int_tracking.int_lesson_location = lastLandscape;	
				/* 20221130 Update to language selection and bookmark functionality replaced LMSAPI with parent.document.scormAPI as API is now at sco.html */
				if(parent.document.scormAPI!=null){
					/* do not bookmark assessment question or results page */					
					actionsLMSSetLessonLocation();			
					actionsLMSCommit();
				}
				/* pause all videos */
				pauseAllVideos();
			}
		}
	}
	else 
	{
		if(int_tracking.int_lesson_location != lastLandscape){	
			int_tracking.int_lesson_location = lastLandscape;	
			/* 20221130 Update to language selection and bookmark functionality replaced LMSAPI with parent.document.scormAPI as API is now at sco.html */
			if(parent.document.scormAPI!=null){
				/* do not bookmark assessment question or results page */
				actionsLMSSetLessonLocation();
				actionsLMSCommit();
			}
			/* pause all videos */
			pauseAllVideos();
		}
	}	
}

/*
	Function: recordPercentComplete
	Arguments: 	
		pageNum: the number of the page being recorded
		totalPages: the total number of pages to be recorded
		resetPg: if true then set the page as NOT visited
		end: if true the course is carrying out finishing actions on the LMS	
	Description: records a page that the user visits in suspend data in the LMS
	Returns: nothing
*/
function recordPercentComplete(pageNum, totalPages, resetPg, end) {	
	if(pageNum != null){
		var sRecordedPages = "";
		var sPages = "";
		var i = 0;
		var sNewString = "";		
		sRecordedPages = jftrim(actionsLMSGetSuspendData());		
		//console.log("recordPercentComplete");
		document.build_menu_data = sRecordedPages
		/* check to see if suspend data has %_Data: */
		var re = /%_Data:([01]*)/im
		var res = re.exec(sRecordedPages)
		/* if it is blank then create a string filled with '0's, to the number of totalPages */
		if (res == null) {
			for (i=0; i<totalPages; i++) {
				sPages += "0";
			}
			/* test out: if there is a pre-test in the course */
			if (document.pretestPresent == 1 || document.topicPreTest || document.trackSections)
			{
				/* test out: store if the pre-test has been attempted and the topics that have been tested out of in suspend data */
                /* 20190102 Updated to track post-test attempts */
				/* 25/03/2024 testing out of sections of content */
				sRecordedPages = document.pretestAttempted + "|" + document.topicsPretestedOut + "|" + document.topicTestAttempted + "|" + document.sectionCompleted + "%_Data:" + sPages + "|" + document.assessAttempts + "|" + document.userBranch + "|" + document.hiddenContentArr;
			}
			else
			{				
                /* 20190102 Updated to track post-test attempts */
				/* 25/03/2024 testing out of sections of content */
				sRecordedPages = "%_Data:" + sPages + "|" + document.assessAttempts + "|" + document.userBranch + "|" + document.hiddenContentArr;
			}	
		} else {			
			sPages = RegExp.$1;
		}
		
		if(end){
			sNewString = sPages;
		}
		else {
			if (resetPg) {
				sNewString = setChar(sPages, "0", pageNum);				
			}
			else {
				sNewString = setChar(sPages, "1", pageNum);
			}			
		}
		
		var currentbreaker = $('div.breaker:eq('+currentSec+')').index('.section')
		var nextbreaker = $('div.breaker:eq('+(currentSec+1)+')').index('.section')
		if(nextbreaker == -1){
			nextbreaker = document.subsectionCount 
		}
			for(i=currentbreaker; i<nextbreaker; i++){
				var startTopic = $('div.breaker:eq('+currentSec+')').index('.section');
				var endTopic = $('div.breaker:eq('+(currentSec+1)+')').index('.section');				
				if(document.trackingArr[i]==1){
					for(j=startTopic; j<(i); j++){						
						var currentsection = $('.section').eq(j);						
						if(!currentsection.is('.testQues, .testStart')){
							var j_1 = Number(currentsection.attr("id").split("_")[1])-1;
							/* test out: if there is a pre-test in the course */
							if (document.pretestPresent == 1)
							{
								/* test out: if not currently taking the pre-test track the page */
								if (!document.takingPretest) {
									document.trackingArr[j_1]= "1";
								}
							}
							else {
								document.trackingArr[j_1]= "1";
							}	
						}
					}
				}
			}
			for (var i = 0; i < document.trackingArr.length; i++){
				if (document.trackingArr[i] === undefined){				
					document.trackingArr[i] = 0;
				}
			}			
			document.trackingArr[0] = '1';
			var trackingString = document.trackingArr.toString()
			trackingString = trackingString.replace(/,/g,'')
			for (var i = trackingString.length; i < sNewString.length; i++){
				trackingString +='0'
			}
			sNewString = trackingString;
		
		/* check course completion for if requirements are all pages viewed and no assessment */
		checkCourseCompletion();
			
		/* ensure to not track assessment questions */	
		var first_q = $('.section.testQues').first().index('.section')
		var testResults = $('.testResults').index('.section')
		var status = actionsLMSGetLessonStatus();
		if(status !== lms_pass_status1 && status !== lms_pass_status2 && $('.testStart').length > 0){
			for(i=first_q; i<testResults; i++){				
				sNewString = sNewString.substr(0, i) + "0" + sNewString.substr(i+1);
			} 
		}
		/* obtain page lock states array from suspend_data */
		document.subsectionLockStateArray = sNewString.split(""); 
		/* test out: if there is a pre-test in the course */
		if (document.pretestPresent == 1 || document.topicPreTest || document.trackSections)
		{		
			/* test out: store if the pre-test has been attempted and the topics that have been tested out of in suspend data */	
            /* 20190102 Updated to track post-test attempts */
			//sNewString = document.pretestAttempted + "|" + document.topicsPretestedOut + "|" + document.topicTestAttempted + "|" + document.sectionCompleted + "%_Data:" + sNewString + "|" + document.assessAttempts + "|" + document.userBranch;
			/* 25/03/2024 testing out of sections of content */
			sNewString = document.pretestAttempted + "|" + document.topicsPretestedOut + "|" + document.topicTestAttempted + "|" + document.sectionCompleted + "%_Data:" + sNewString + "|" + document.assessAttempts + "|" + document.userBranch + "|" + document.hiddenContentArr;
		}
		else {			
            /* 20190102 Updated to track post-test attempts */
			//sNewString = "%_Data:" + sNewString + "|" + document.assessAttempts + "|" + document.userBranch;
			/* 25/03/2024 testing out of sections of content */
			sNewString = "%_Data:" + sNewString + "|" + document.assessAttempts + "|" + document.userBranch + "|" + document.hiddenContentArr;
		}
		/* set the LMS suspend data */
		actionsLMSSetSuspendData(sNewString);
		actionsLMSCommit();
	}
}

/*
	Function: trackSectionComplete
	Arguments: none
	Description: tracks data to the LMS for when a section is complete
	Returns: none
*/
function trackSectionComplete(n)
{
	//console.log("here");
	/* not mobile devices so check we can commit tracking data */
	if((n) % parent.lms_save_interval==0 || (($('#sec_'+n).next('.section').hasClass('breaker') || $('#sec_'+n).hasClass('testResults')) && document.audioComplete && document.intComplete)){
		recordPercentComplete(n, document.subsectionCount, false);
		courseWriteTimer(true); /* only called now when course closes on desktop */
		/* commit date to the LMS */
		actionsLMSCommit();
	}else{
		recordPercentComplete(n, document.subsectionCount, false);
	}
}

/*
	Function: closeErrorPopupOrCourse
	Arguments: none
	Description: closes the course if is an error popup otherwise hides the popup
	Returns: none
*/
function closeErrorPopupOrCourse()
{
	if (document.errorMessagePresent) {
		hideErrorMessage();
	}
	else {		
		boxClose();
	}
}

/*
	Function: showErrorMessage
	Arguments: errTitle, errStr, errStr2, errStr3 - strings of LMS error message content
	Description: displays an LMS error message
	Returns: nothing
*/
function showErrorMessage(errTitle, errStr, errStr2, errStr3) {
	/* 011623 show LMS error message */
	/*if (isiPad || isAndroidTablet || isAndroidPhone || isiPhone) {
		var errorMessagePrint = "";
	}
	else {
		var errorMessagePrint = "<a href='javascript:void(0);' class='button button-primary print_btn' style='right: 0px;' onclick='printErrorMessage();' onkeypress='printErrorMessage();'	title='" + localiseString('print_btn') + "'>" + localiseString('print_btn') + "</a>";
	}*/
	var errorMessageClose = "<a href='javascript:void(0);' class='button button-primary error_close_btn' onclick='closeErrorPopupOrCourse();' onkeypress='closeErrorPopupOrCourse();' title='" + localiseString('close_btn') + "'>" + localiseString('close_btn') + "</a>"; /* 011623 show LMS error message */
	var errorMessage = "";
	var interfaceItem = document.getElementById("footerTextArea");
	var preErrorPopupBg = document.getElementById("preErrorLBBg");		
	/*errorMessage = "<p>" + errStr + "</p><p>" + errStr2 + "</p><p>" + errStr3 + "</p><p>" + errorMessagePrint + "</p>";*/ /* 011623 show LMS error message */
	errorMessage = "<p>" + errStr3 + "</p><p>" + errorMessageClose + "</p>"; /* 011623 show LMS error message */
	interfaceItem.innerHTML = "";
	interfaceItem.style.backgroundColor = "";
	preErrorPopupBg.style.visibility = "hidden";
	document.errorMessagePresent = true;
	document.errorNotifyPresent = false;
	$(window).bind('mousewheel',function(){ return false; });
	boxPop(null,'error',errTitle,errorMessage);
}

/*
	Function: hideErrorMessage
	Arguments: none
	Description: hides the LMS error message and re-adjusts scrolling
	Returns: nothing
*/
function hideErrorMessage()
{
	closeWindow();
	$(window).unbind('mousewheel');
}

/*
	Function: printErrorMessage
	Arguments: none
	Description: prints the course window
	Returns: nothing
*/
function printErrorMessage()
{
	window.print();
}

/*
	Function: closeWindow
	Arguments: none
	Description: closes the window up to the top level
	Returns: nothing
*/
function closeWindow(){
	window.setTimeout("window.close();", 400);
    window.setTimeout("parent.window.close();", 500);
    window.setTimeout("parent.parent.window.close();", 600);
    window.setTimeout("parent.parent.parent.window.close();", 700);
	window.setTimeout("window.top.close();", 800);
}

/*
	Function: jftrim
	Arguments: string
	Description: clears white space from the string
	Returns: string with white space removed
*/
function jftrim(s) {
    if (s == null) {
        w = new String("");
    } else {
	    w = new String(s);
		if (w.length != 0) {
			while (w.substring(w.length - 1, w.length) == " ") {
				w = w.substring(0, w.length - 1);
			}
		}
	}
    return w;
}

/*
	Function: setChar
	Arguments:
		str: string to modify
		char: character to insert
		pos: position to insert the character (1-indexed)	
	Description: inserts a character in a specific position in a string
	Returns: string with character inserted
*/
function setChar(str, chr, pos) {	
	var preStr	
	var postStr	
	preStr = str.slice(0, pos - 1);	
	postStr = str.slice(pos);	
	return preStr + chr + postStr;
}

/*
	Function: convertSecondsToCMITimeSpan
	Arguments: number of seconds		
	Description: converts seconds into hours, minutes, and seconds in
				 CMITimespan type format - HHHH:MM:SS.SS (Hours has a max of 4 digits &
				 Min of 2 digits
	Returns: CMITimeSpan string HHHH:MM:SS.SS format
*/
function convertSecondsToCMITimeSpan(ts)
{
   var sec = (ts % 60);
   ts -= sec;
   var tmp = (ts % 3600);  /* # of seconds in the total # of minutes */
   ts -= tmp;              /* # of seconds in the total # of hours */
   /* convert seconds to conform to CMITimespan type (e.g. SS.00) */
   sec = Math.round(sec*100)/100;   
   var strSec = new String(sec);
   var strWholeSec = strSec;
   var strFractionSec = "";
   if (strSec.indexOf(".") != -1)
   {
      strWholeSec =  strSec.substring(0, strSec.indexOf("."));
      strFractionSec = strSec.substring(strSec.indexOf(".")+1, strSec.length);
   }   
   if (strWholeSec.length < 2)
   {
      strWholeSec = "0" + strWholeSec;
   }
   strSec = strWholeSec;
   if ((ts % 3600) != 0 )
      var hour = 0;
   else var hour = (ts / 3600);
   if ( (tmp % 60) != 0 )
      var min = 0;
   else var min = (tmp / 60);	
   if ((new String(hour)).length < 2)
      hour = "0"+hour;  
   if ((new String(min)).length < 2)
      min = "0"+min;   
   var result = hour+":"+min+":"+strSec;
   return result;
}

/*

    resetCourse funciton
    Called when user fails assessment 
    and attempts match document.assessAttempts
    
    Funciton will reset users tracking data and lock down course and menu.

*/

function resetCourse(){
    
    document.menuLockedDown = true;
    document.courseLockedDown = true;
    document.assessAttempts = 0;
    
    
    for (var i = 0; i < document.trackingArr.length; i++){
        document.trackingArr[i] = 0;
    }		
    
    var sTopics = "";
	
	var secArr = document.sectionCompleted.split("")
	
	var sSecs = "";
    
    var sRecordedPages = "";
    var sPages = "";
    var i = 0;
    var sNewString = "";		
    sRecordedPages = jftrim(actionsLMSGetSuspendData());		

    document.build_menu_data = sRecordedPages
    /* check to see if suspend data has %_Data: */
    var re = /%_Data:([01]*)/im
    var res = re.exec(sRecordedPages)
    
    for(var j = 0; j!= document.topicsCount; j++){
        sTopics += "0";
    }
	
	for(var j = 0; j!= secArr.length; j++){
        sSecs += "0";
    }
    
    for (i=0; i<document.subsectionCount; i++) {
        if(i == 0){
            sPages += "1";
        }else{
            sPages += "0";
        }
    }
    
    if (document.pretestPresent == 1 || document.topicPreTest || document.trackSections){
        /* 20190102 Updated to track post-test attempts */
        /* 20190102 Updated to track post-test attempts */
        //sRecordedPages = document.pretestAttempted + "|" + sTopics + "|" + sTopics + "|" + sSecs + "%_Data:" + sPages + "|" + document.assessAttempts + "|" + document.userBranch;
		/* 25/03/2024 testing out of sections of content */
		sRecordedPages = document.pretestAttempted + "|" + sTopics + "|" + sTopics + "|" + sSecs + "%_Data:" + sPages + "|" + document.assessAttempts + "|" + document.userBranch + "|" + document.hiddenContentArr;
    }else{				
        /* 20190102 Updated to track post-test attempts */
        /* 20190102 Updated to track post-test attempts */
        //sRecordedPages = "%_Data:" + sPages + "|" + document.assessAttempts + "|" + document.userBranch;
		/* 25/03/2024 testing out of sections of content */
		sRecordedPages = "%_Data:" + sPages + "|" + document.assessAttempts + "|" + document.userBranch + "|" + document.hiddenContentArr;
    }	
    
    actionsLMSSetValue('cmi.core.lesson_location', '');	
    
    actionsLMSSetSuspendData(sRecordedPages);
	actionsLMSCommit();
    lockMenu();
    resetInteractions();

}

/*
    retakeCourse funciton
    Called on click of button on results page after user fails assessment 
    and attempts match document.assessAttempts
    
    Funciton will take user back to menu
    
*/

function retakeCourse(){
    
    retakeAssessment();
    
    $('.topic_nav_button').css('visibility','visible')

    $('#home_nav').trigger('click');
    
}

/*
    lockMenu Function
    Lockdown all but first menu item
    
    //20190205 Updated to reset progress and lock icons
*/
function lockMenu(){
    for (var i = 0; i < document.topicsCount; i++){	
        
        if(i == 0){
			/* 20230503 New Menu Updates */
            $('.topic_select .top_wrapper').eq(i).addClass('unlocked');
			$('.topic_select .heading_area img').eq(i).attr('src', 'images/menu_topic_'+(i)+'.png');
        }else{
            
            $('.topic_select .overlay').eq(i).css('display', 'block');
            $('.burger_select .overlay').eq(i).css('display', 'block');
            
            $('.select_bottom:eq('+i+') img').attr('src', 'images/general_int/topic_locked.png');
            $('.burger_select:eq('+i+') img').attr('src', 'images/custom_int/burger_locked.png');

        }
        
        
    }

	/* 20240130 accessibility 2024 */
	$('.topic_select').each(function(index, element) {
		var tempTopicSelectTxt = '';
		if($(this).find('.select_bottom .start_img').attr('src') != 'images/general_int/topic_locked.png'){
			tempTopicSelectTxt = localiseString('topic_incomplete') + " " + localiseString('topic_start');
		}
		else {
			tempTopicSelectTxt = localiseString('topic_incomplete') + " " + localiseString('topic_locked');
		}
		$(this).attr('title',($(this).find('.select_title h3').html() + " " + tempTopicSelectTxt));
		$(this).attr('alt',tempTopicSelectTxt);
		$(this).find('.select_bottom .progress').attr('title','');
		$(this).find('.select_bottom .progress').attr('alt','');
		$(this).find('.select_bottom .start_img').attr('title',($(this).find('.select_title h3').html() + " " + tempTopicSelectTxt));
		$(this).find('.select_bottom .start_img').attr('alt',tempTopicSelectTxt);
	});
	
	$('.burger_select').each(function(index, element) {
		var tempTopicSelectTxt = '';
		if($(this).find('.burger_start_img').attr('src') != 'images/custom_int/burger_locked.png'){
			tempTopicSelectTxt = localiseString('topic_incomplete') + " " + localiseString('topic_start');
		}
		else {
			tempTopicSelectTxt = localiseString('topic_incomplete') + " " + localiseString('topic_locked');
		}		
		$(this).find('.burger_select_title').attr('title',($(this).find('.burger_select_title').html() + " " + tempTopicSelectTxt));		
		$(this).attr('title',($(this).find('.burger_select_title').html() + " " + tempTopicSelectTxt));
		$(this).attr('alt',tempTopicSelectTxt);
		$(this).find('.burger_start_img').attr('title',($(this).find('.burger_select_title').html() + " " + tempTopicSelectTxt));
		$(this).find('.burger_start_img').attr('alt',tempTopicSelectTxt);
	});
 
    $('.progress').removeClass('progress_started');
    $('.progress').removeClass('progress_complete');
    $('.burger_progress').removeClass('burger_progress_started');
    $('.burger_progress').removeClass('burger_progress_complete');
}

/*
    resetInteractions Functions
    Will reset all interactions to their intial states, and reset unlocking data 
    so user has to complete them before moving forward

*/
function resetInteractions(){
    
    document.audioComplete = false; 
    document.intComplete = false;
    
    $(".section").attr('data-clicked',0); 
    $('.hotspot_btn').attr('data-hotspot',0);
    $('.slider_txt').attr('data',0);
    $('.expando_btn').attr('data',0);
    $('.submit_btn').attr('data',0);
    
    $('.complete_arrow').removeClass('unlocked');
    
    
    /* Slider */
    for(var i = 0; i!= currSlideArr.length; i++){
        currSlideArr[i] = undefined;
    }
    $('.slide_focus').removeClass('focus');
    $('.slide_left').addClass('disabled');
    $('.slide_right').removeClass('disabled');
    
    
    $('.sec_rest_wrapper').find('.section').each(function(index, element) {
        
        $(this).find('.slider_txt').each(function(index, element) {	

            $(this).css('display','none');

            if(index == 0){
                $(this).removeClass('slider_current');
                $(this).removeClass('slider_hidden');
                $(this).addClass('slider_current');
                $(this).css('display','block');
            }else{
                $(this).removeClass('slider_hidden');
                $(this).removeClass('slider_current');
                $(this).addClass('slider_hidden');
            }

        });
        $(this).find('.slide_focus').each(function(index, element) {	
            if(index == 0){
                $(this).addClass('focus')
            }
        });
    });
    
    
    /* Slider */
    
    
    /* Inline Questions */
    
    $('.section').find('.submit_btn').each(function(index, element) {
        
        var secNum = Number($(this).attr('id').split('_')[2]);
        
        var tNum = $(this).attr('onClick').split(',')[3];
        
        tNum = Number(tNum.split(')')[0]);
        
        if(secNum < document.testIntroSubsection){
            //reSetupClickableOptionsInlineQues('sec_'+secNum)
            resetInQues(secNum,tNum);
        }
        
    });

    /* Inline Questions */
    
    
    /* Hospots */
    
    $('.hotspot_btn_label').addClass('hotspot_btn_label_cutoff');
    $('.hotspot_btn_label').removeClass('hotspot_visited');
    $('.hotspot_reveal').hide();
    $('.hotspot_btn_ind').hide();
    
	$('.section').find('.hotspot_btn').each(function(index, element) {
    
        var imgEle, img, ext
        $(this).find('img').each(function(index, element) {
            imgEle = $(this);
            img = $(this).attr('src').split('.')[0];
            ext = $(this).attr('src').split('.')[1];
        });

        if(img.indexOf('_visited') != -1){
            img = img.split('_visited')[0];
            $(imgEle).attr('src', img + '.' + ext);
        }
        
    });
    
    /* Hospots */
    
    
    /* Expando */
    lastExpID = "";
    if(document.useTransitions){
        $('.expando_reveal').children('.expando_reveal_content').hide();
    }
    $('.expando_reveal').hide();
    $('.expando_btn').show();	
    $('.expando_btn').removeClass('expando_btn_visited');
    
    /* Expando */
    
    
    /* Video */
    $('.section').find('.video_player').each(function(index, element) {
    
        var vidID = $(this).attr('id')
        
        var video = document.getElementById(vidID);
        video.pause();
        video.currentTime = 0;
        video.load();
        
    });
    /* Video */
    
}


// SCORM 2004 requires timeinterval to be formatted as:
// P[yY][mM][dD][T[hH][nM][s[.s]S]]
function ConvertMilliSecondsIntoSCORM2004Time(intTotalMilliseconds){
	var ScormTime = "";

	var HundredthsOfASecond;	// decrementing counter - work at the hundreths of a second level because that is the maximum precision required

	var Seconds;	// 100 hundreths of a seconds
	var Minutes;	// 60 seconds
	var Hours;		// 60 minutes
	var Days;		// 24 hours
	var Months;		// assumed to be an "average" month (figures a leap year every 4 years) = ((365*4) + 1) / 48 days - 30.4375 days per month
	var Years;		// assumed to be 12 "average" months

	var HUNDREDTHS_PER_SECOND = 100;
	var HUNDREDTHS_PER_MINUTE = HUNDREDTHS_PER_SECOND * 60;
	var HUNDREDTHS_PER_HOUR   = HUNDREDTHS_PER_MINUTE * 60;
	var HUNDREDTHS_PER_DAY    = HUNDREDTHS_PER_HOUR * 24;
	var HUNDREDTHS_PER_MONTH  = HUNDREDTHS_PER_DAY * (((365 * 4) + 1) / 48);
	var HUNDREDTHS_PER_YEAR   = HUNDREDTHS_PER_MONTH * 12;

	HundredthsOfASecond = Math.floor(intTotalMilliseconds / 10);

	Years = Math.floor(HundredthsOfASecond / HUNDREDTHS_PER_YEAR);
	HundredthsOfASecond -= (Years * HUNDREDTHS_PER_YEAR);

	Months = Math.floor(HundredthsOfASecond / HUNDREDTHS_PER_MONTH);
	HundredthsOfASecond -= (Months * HUNDREDTHS_PER_MONTH);

	Days = Math.floor(HundredthsOfASecond / HUNDREDTHS_PER_DAY);
	HundredthsOfASecond -= (Days * HUNDREDTHS_PER_DAY);

	Hours = Math.floor(HundredthsOfASecond / HUNDREDTHS_PER_HOUR);
	HundredthsOfASecond -= (Hours * HUNDREDTHS_PER_HOUR);

	Minutes = Math.floor(HundredthsOfASecond / HUNDREDTHS_PER_MINUTE);
	HundredthsOfASecond -= (Minutes * HUNDREDTHS_PER_MINUTE);

	Seconds = Math.floor(HundredthsOfASecond / HUNDREDTHS_PER_SECOND);
	HundredthsOfASecond -= (Seconds * HUNDREDTHS_PER_SECOND);

	if (Years > 0) {
		ScormTime += Years + "Y";
	}
	if (Months > 0){
		ScormTime += Months + "M";
	}
	if (Days > 0){
		ScormTime += Days + "D";
	}

	//check to see if we have any time before adding the "T"
	if ((HundredthsOfASecond + Seconds + Minutes + Hours) > 0 ){

		ScormTime += "T";

		if (Hours > 0){
			ScormTime += Hours + "H";
		}

		if (Minutes > 0){
			ScormTime += Minutes + "M";
		}

		if ((HundredthsOfASecond + Seconds) > 0){
			ScormTime += Seconds;

			if (HundredthsOfASecond > 0){
				ScormTime += "." + HundredthsOfASecond;
			}

			ScormTime += "S";
		}

	}

	if (ScormTime == ""){
		ScormTime = "0S";
	}

	ScormTime = "P" + ScormTime;

	return ScormTime;
}


function doBranchCompletion(){
	var lesson_status = actionsLMSGetLessonStatus();
	
	if (lesson_status!=lms_pass_status1 && lesson_status!=lms_pass_status2) {
		actionsLMSSetLessonStatus("completed",true);
		actionsLMSCommit();			
	}
	
}

/* 25/03/2024 testing out of sections of content */
function hideTestedOutContent(secNum,inlineCorr) {
	if (document.hideTestOutContent) {
		var secId = "sec_" + secNum;
		var secList = $("#" + secId).attr("data-testOutList");		
		/* if this inline question is one that has sections of content that can be tested-out of */
		if (secList !== undefined)
		{
			/* always hide question on return to course in new session */
			document.hiddenContentArr.push(secNum);
			/* 20240319 pre-test that appears after first topic */
			/* hide Pre-test after Topic One Intro page */
			if (secList == secNum)
			{
				hidePage(secNum);
			}
			/* if question answered correctly then hide tested-out content in this and new sessions */
			if (inlineCorr)
			{
				if (secList){
					var secListArr = secList.split('|');
					for (var i = 0; i < secListArr.length; i++)
					{
						hidePage(secListArr[i]);
						document.hiddenContentArr.push(secListArr[i]);
					}
				}
			}
		}	
	}
}

/* 25/03/2024 testing out of sections of content */
function hidePage(secNum){
	document.lockedArr[secNum-1] = 0;
	$('#sec_'+ secNum).css('margin-top','-1px');
	$('#sec_'+ secNum).css('background-image','none');
	$('#sec_'+ secNum).css('height','1px');
	$('#sec_'+ secNum).css('padding-top','0px');
	$('#sec_'+ secNum).css('padding-bottom','0px');
	$('#sec_'+ secNum).find('.container').html('');
	$('#sec_'+ secNum).find('.container').css('height','1px');	
	$('#sec_'+ secNum).find('.container').css('padding-bottom','0px');
	$('#sec_'+ secNum).find('.full_screen_img').html('');
	$('#sec_'+ secNum).find('.full_screen_img').css('margin-bottom','50px');
	$('#sec_'+ secNum).find('.video_holder').html('');
	$('#sec_'+ secNum).find('.video_holder').removeClass('video_holder');
	$('#sec_'+ secNum).find('.image_hotspot_holder').html('');
}