

//Adapted from MM scorm get API functions.
//parameters:
//trackTime: boolean defining if time should be tracked.
//pageTracker: a PageTracker object if the course percent complete is to be tracked.
//makeBookmarks: should the sco make bookmarks? boolean.
function Scorm(trackTime,pageTracker,makeBookmarks){

	this.trackTime = trackTime;
	this.pageTracker = pageTracker;
	this.startTime = new Date();
	this.mm_getAPI = function mm_getAPI(){
		var myAPI = findAPI(window, 0);
		//showDebuggerInfo();
		//debug('myAPI' + myAPI);
		return myAPI;
	}
	// returns LMS API object (or null if not found)
	function findAPI(win, depth)
	{
		var myAPI = win.API;
		// Did we find it here ?
		if (myAPI != null) return myAPI;
		// One more try, limit depth of search to 10.
		depth++;
		if (depth > 10) return null;
	
		// Try win.parent and recurse.
		if (win.parent != null && typeof(win.parent) != "undefined"){
			myAPI = findAPI(win.parent, depth);
			if (myAPI != null) return myAPI;
		}
		// Try win.opener and recurse.
		if (win.opener != null && typeof(win.opener) != "undefined"){
			myAPI = findAPI(win.opener, depth);
			if (myAPI != null) return myAPI;
		}
		return myAPI;
	}
	this.init = function(){
		if(this.api != null){
			this.api.LMSInitialize('');
			document.initialized=true;
			//set to incomplete if not already complete
			if(this.api.LMSGetValue("cmi.core.lesson_status") != "passed"){
				this.api.LMSSetValue("cmi.core.lesson_status","incomplete");
				this.api.LMSCommit("");
			}
			document.initialTracking = "";
			//alert("document.initialTracking :"+document.initialTracking)
			//get the percent complete data and apply it to the Course if neccessary
			if(this.pageTracker != null){
				var suspend_data = this.api.LMSGetValue("cmi.suspend_data");
				if(suspend_data.search(/^\s*$/) != -1){
	 				//there is no suspend_data. do nothing.
				}else{
					//there is data so cut off the prefix: '%_Data:'
					suspend_data = suspend_data.split('%_Data:')[1];
					document.initialTracking = suspend_data;
					//this.pageTracker.applyPercentCompleteString(suspend_data);
				}
			}			
		}
	}
	this.report = function(){
		var str = this.pageTracker.getTrackString();
		var nstr = '';
		for(var i=0;i<str.length;i++){
			nstr+=str.charAt(i)
			if(i == 40) nstr+= '\n';
		}
		alert(nstr);
	}
	this.end = function(){
		if(document.initialized){
			if(this.api != null){
				// commit time if neccessary
				if(this.trackTime){
					var d = new Date();
					var sessionTime = d - this.startTime;
					this.api.LMSSetValue("cmi.core.session_time", this.convertSecondsToCMITimeSpan(sessionTime/1000));
				}
				// commit percent complete if neccessary
				//if(this.pageTracker != null){
				//	if(this.pageTracker.finished())
				//		this.api.LMSSetValue("cmi.core.lesson_status","completed");
					//this.api.LMSSetValue("cmi.suspend_data", '%_Data:' + this.pageTracker.getTrackString()); // andy 16-01-07 added flash string below. need to test
					this.api.LMSSetValue("cmi.suspend_data", '%_Data:' + document.trackStr);
					//alert("tracking for scorm:" + document.trackStr);
				//}
				this.api.LMSSetValue("cmi.core.exit", "");
				this.api.LMSCommit("");
				this.api.LMSFinish("");
				document.initialized=false;
			}
		}
	}
	this.setScore = function(args){
		//alert("setScore"+args);
		if(this.api != null){
			// set the score if it's less than any previously recorded score.
			cur_score = this.api.LMSGetValue("cmi.core.score.raw");
			if(cur_score==undefined||cur_score==null) cur_score=0;
			mastery_score = this.api.LMSGetValue("cmi.student_data.mastery_score");
			if(mastery_score=="null"||mastery_score==null) mastery_score = document.passMark;
			// 
			//alert("cur_score"+cur_score);
			//alert("mastery_score"+mastery_score);
			if(Number(args)>=Number(cur_score)){
			//alert("args>=cur_score : args = "+args);
			this.api.LMSSetValue("cmi.core.score.raw", args);
				if(mastery_score!="null"){
					if(args>=mastery_score){
						this.api.LMSSetValue("cmi.core.lesson_status","passed");
					}
				}else if(Number(args)>=70){
						this.api.LMSSetValue("cmi.core.lesson_status","passed");
				}
			}
			this.api.LMSCommit("");
		}
	}
	this.setTracking = function(){
		if(this.api != null){
			this.api.LMSSetValue("cmi.suspend_data", '%_Data:' + document.trackStr);
		
		// are we at the Pass mark?
		var suspend_data = this.api.LMSGetValue("cmi.suspend_data");
		if(suspend_data.search(/^\s*$/) != -1){
	 			//there is no suspend_data. do nothing.
		}else{
				//there is data so cut off the prefix: '%_Data:'
			suspend_data = suspend_data.split('%_Data:')[1];
			//var str = document.trackStr;
			var count = 0;
			for(var i=0; i<suspend_data.length; i++){
				if(suspend_data.charAt(i) == '1')
					count +=1;
				}
				var percentViewed = Math.round(count/(suspend_data.length/100));
				document.menu.SetVariable('debug', percentViewed);
				document.menu.SetVariable('trackingData', suspend_data);
				if(percentViewed<document.passMark){
					this.api.LMSSetValue("cmi.core.lesson_status","incomplete");
					this.api.LMSCommit("");
				}else{
					this.api.LMSSetValue("cmi.core.lesson_status","completed");
					this.api.LMSCommit("");
				}
			}
		}
	}
	
	// Function: convertSecondsToCMITimeSpan()
	// Parameters: ts - number of seconds
	// Returns: CMITimeSpan string HHHH:MM:SS.SS format
	//
	// Description:  this function will convert 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
	//
	this.convertSecondsToCMITimeSpan = function(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 (strFractionSec.length)
	   {
		  strSec = strSec+ "." + strFractionSec;
	   }
	
	   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;
	}
	//bookmark recives a Page object and sends its URL to the LMS.
	this.setBookmark = function(page){
		var api = this.api;
		if(api != null && makeBookmarks){		
			/*TG. 08/03/06. Custom for ML. Commit the last page visited *AND* a string of 1s and 0s representing which topics have been viewed.*/
			var topicCompleteStr = "";
			for(var i=0;i<document.course.topics.length;i++){
				var complete = document.course.topics[i].complete();
				if(complete){
					topicCompleteStr += "1";
				}else{
					topicCompleteStr += "0";
				}
			}			
			var url = page.url;
			api.LMSSetValue("cmi.core.lesson_location", url + "--topicsComplete::" + topicCompleteStr);
			api.LMSCommit("");
		}
	}
	//gets a bookmarked page from the LMS.
	this.getBookmark = function(){
		var api = this.api;
		var lesson_location = '';
		if(api != null && makeBookmarks){		
			lesson_location = api.LMSGetValue("cmi.core.lesson_location");
		}
		if(lesson_location.search(/^\s*$/) != -1){
 			//there is no suspend_data. return null.
			return null;
		}else{
			//TG 08/03/2006: Custom for another course - parse out the htm page from the 1s and 0s string.
			var htmlPage = lesson_location.split("--topicsComplete::")[0];
			if(htmlPage == ""){
				return null;
			}else{
				return htmlPage;				
			}
		}
	}
	this.api = this.mm_getAPI();
	this.init();
}

// called from flash at start
function setTrackStr(flashstring){
	document.trackStr=flashstring;
}

//called from flash to set a page to visited
function setTrackStrVisited(flashNum){
	alert("setTrackStrVisited(" + flashNum + ") called but commented out");
	//document.trackStr=document.trackStr.substr(0, flashNum-1) add "1" + document.trackStr.substring(flashNum, document.trackStr.length);
		
}

//Class PageTracker. Manages tracking for percent complete.
function PageTracker(flashstring){
	//this.course = course;
	//applyPercentCompleteString(). Called by Scorm object. Applies a string of 1s and 0s to the course.
	this.applyPercentCompleteString = function(percentStr){
		//loop through all pages in the Course sequentially, setting visited to true if neccesary.
	//	var percentStr_index = 0;
		//make sure to get only trackable pages.
	//	var pages = this.course.getTrackablePages();
	//	for(var i in pages){
	//		var page = pages[i];
	//		if(page.track == 1 && percentStr.charAt(percentStr_index) == '1'){
	//			page.setVisited();
	//		}
	//		percentStr_index++;
	//	}
	document.trackStr = percentStr;
	}
	//getTrackString. returns a string of 1s and 0s that describe what pages have been visited.
	this.getTrackString = function(){
	//	var pages = this.course.pages;
	//	var trackStr = '';
	//	for(var i in pages){
	//		var page = pages[i];
	//		if(page.track == 1){
	//			trackStr += String(page.visited);
	//		}
	//	}
		return document.trackStr;
	}
	this.finished = function(){
		//finished if all 1s in the trackString.
		//var str = this.getTrackString();
		var str = trackStr;
		var found0 = false;
		for(var i=0; i<str.length; i++){
			if(str.charAt(i) == '0')
				found0 = true;
		}
		return !found0;
	}	
	this.trackPage = function(page){
		page.setVisited();
	}
}
function Score(course,allowWorse){
	this.getNoOfQuestions = function(){
		var result = 0;
		for(i in this.course.pages){
			if(this.course.pages.trackScore == 1)
				result++;
		}
		return result;
	}
	//calcTotalScore. returns total sum of all scores in the array.
	this.calcTotalScore = function(){
		var result = 0;
		var pages = this.course.pages;
		for(var i in pages){
			var page = pages[i];
			if(page.trackScore == 1){
				result += page.score;
			}
		}
		return result;
	}
	//calcPercent. returns score as percent.
	this.calcPercent = function(){
		var total = this.calcTotalScore();
		return total == 0 ? 0 : Math.ceil((total/this.maxScore) * 100);
	}
	this.addScore = function(page,score){
		debug('add:',page,score)
		if((score<page.score && this.allowWorse == true) || score>page.score)
			page.setScore(score);
	}
	this.calcMaxScore = function(){
		var result = 0;
		var pages = this.course.pages;
		for(var i in pages){
			var page = pages[i];
			//if trackScore = 1 it means we want to track the score of this page (QPage);
			if(page.trackScore == 1){
				result += page.maxScore;
			}
		}
		return result;				
	}
	this.course = course;
	this.maxScore = this.calcMaxScore();
	this.noOfQuestions = this.getNoOfQuestions();
	this.allowWorse = allowWorse;	//can a particular answer be overwritten with a worse answer?	
}