/************************************************************************************************
**
** FileName: CoursePlayer.js
**
************************************************************************************************/

/************************************************************************************************
**Description, etc. etc.
**
**Document the High Level Functions
**1.updateTopicInfo
**2.updateQuestionInfo
**3.updateExerciseInfo
**4.getExamStatus
**5.getItemStatus
**6.getItemScore
**
**Document the Low Level Functions (LMS wrapper functions)
**1.LMSInitialize
**2.LMSFinish
**3.LMSSetValue
**4.LMSGetValue
**5.LMSCommit
**6.LMSGetLastError
**7.LMSGetErrorString
**8.LMSGetDiagnostic
**9.isLMSInitialized
**10.ErrorHandler
**
**Documentation for Flash Courseware
**
**Documentation for AT Courseware
**
**Examples:
**Usage: Executable course content can call the Course Player
**      functions as follows:
**
**    javascript (High Level API interaction):
**          var result = updateTopicInfo(id,mastery_time);
**          if (result != true) 
**          {
**             // handle error
**          }
**
**    javascript (Low Level API interaction):
**  	    retval = LMSInitialize();
**          if (result != true) 
**          {
**             // handle error
**          }
**
**    Flash:

**
**    authorware
**          result := ReadURL("javascript:doLMSInitialize()", 100)
**
************************************************************************************************/


var _Debug = false;  // set this to false to turn debugging off
                     // and get rid of those annoying alert boxes.

// Define exception/error codes
var _NoError = 0;
var _GeneralException = 101;
var _ServerBusy = 102;
var _InvalidArgumentError = 201;
var _ElementCannotHaveChildren = 202;
var _ElementIsNotAnArray = 203;
var _NotInitialized = 301;
var _NotImplementedError = 401;
var _InvalidSetValue = 402;
var _ElementIsReadOnly = 403;
var _ElementIsWriteOnly = 404;
var _IncorrectDataType = 405;


/************************************************************************************************
** Locate API
************************************************************************************************/
var api="SeedPlayer";
var APIWin;


function returnAPIWin()
{
	if (api=="SeedPlayer"){
		APIWin = new SCORMAPI();
	}
	else{
		alert("No seed player");
	}
	return APIWin; // May be NULL
}


function doOnUnload(id)
{
	updateTopicInfo(id);
}
// begin oVeRLoRDz added July 25 2004
function doOnUnloadQuestion(szMaxScoreMethodName, szRawScoreMethodName, id)
{
	updateQuestionInfo(id, szMaxScoreMethodName, szRawScoreMethodName);
}

// end oVeRLoRDz added July 25 2004
	


/************************************************************************************************
** High Level Course API
************************************************************************************************/
function updateTopicInfo(id)
{
	var retval;
	var mastery_time = calculateTimer();
	//in case there is something wrong
	if (id=="") return false;

	retval = LMSInitialize();
	if (retval) retval = LMSSetValue("cmi.objectives.0.id", id);
	if (retval) retval = LMSSetValue("cmi.objectives.0.mastery_time", parseInt(mastery_time));
	if (retval) retval = LMSSetValue("cmi.objectives.0.status.0", "completed");
	if (retval) retval = LMSSetValue("cmi.suspend_data", "");
	if (retval) retval = LMSFinish();
	//alert("finish");
	//VyTTT changed on 5/13/20004
	//UpdatePercentComplete();
	//end
		
	return retval;
}

function updateQuestionInfo(id, szMaxScoreMethodName, szRawScoreMethodName)
{
	var retval, maxScore, rawScore;
	var mastery_time = calculateTimer();



	//in case there is something wrong
	if (id=="") return false;

	//alert(mastery_time);
	maxScore = eval(szMaxScoreMethodName);
	rawScore = eval(szRawScoreMethodName);
	
	retval = LMSInitialize();
	if (retval) retval = LMSSetValue("cmi.objectives.0.id", id);
	if (retval) retval = LMSSetValue("cmi.objectives.0.mastery_time", parseInt(mastery_time));
	if (retval) retval = LMSSetValue("cmi.objectives.0.scores.0.raw", rawScore);
	if (retval) retval = LMSSetValue("cmi.objectives.0.scores.0.max", maxScore);
	if (retval) retval = LMSSetValue("cmi.objectives.0.status.0", "completed");
	if (retval) retval = LMSSetValue("cmi.suspend_data", "");
	if (retval) retval = LMSFinish();
	//VyTTT changed on 5/13/20004
	//UpdatePercentComplete();
	//end		
	BuildAssessment();
	UpdateAssessment(strAssess);

	return retval;
}

function updateExerciseInfo(id, nResult)
{
	var retval;
	var mastery_time = calculateTimer();

	//in case there is something wrong
	if (id=="") return false;

	retval = LMSInitialize();
	if (retval) retval = LMSSetValue("cmi.objectives.0.id", id);
	if (retval) retval = LMSSetValue("cmi.objectives.0.mastery_time", parseInt(mastery_time));
	if (retval && parseInt(nResult) != -1)	//not specified
	{
		retval = LMSSetValue("cmi.objectives.0.scores.0.raw", nResult);
	}
	if (retval) retval = LMSSetValue("cmi.objectives.0.status.0", "completed");
	if (retval) retval = LMSSetValue("cmi.suspend_data", "");
	if (retval) retval = LMSFinish();

	UpdateAssessment(strAssess);

	return retval;
}

function getExamStatus(id)
{
	// Mr TNT _ June 29 th, 2005
	// purpose: 'blinking' problem
	
	//in case there is something wrong
	if (id == "") return false;
	
	var i;
	var returnValue;
	
	for (i=0; i < top.DisplayFrame.rootObj.nChildren; i++){
		if (top.DisplayFrame.rootObj.children[i].itemID == id)
		{
			switch (top.DisplayFrame.rootObj.children[i].itemStatus.toString()){
				case "1": 
					returnValue = "not attempted";
					break;
				case "2":
					returnValue = "incompleted";
					break;
				case "3":
					returnValue = "completed";
					break;
			}
			
			return returnValue;
		}
	}
	
	return false;
	
/*
	//in case there is something wrong
	if (id=="") return false;

	var retval, retval_exam;
	retval = LMSInitialize();
	if (retval) retval = LMSSetValue("cmi.objectives.0.id", id);
	if (retval) retval_exam = LMSGetValue("cmi.objectives.0.status.0");
	if (retval_exam) retval = LMSFinish();
	return retval_exam;
*/
}

function getItemStatus(id)
{

	//in case there is something wrong
	if (id=="") return false;
	
	
	retval = LMSInitialize();
	retval = LMSSetValue("cmi.objectives.0.id", id);
	retval_item = LMSGetValue("cmi.objectives.0.status.0");
	retval = LMSFinish();
	return retval_item;
}

function getItemScore(id)
{
	//in case there is something wrong
	//alert('no score');
	if (id=="") return false;
	
	retval = LMSInitialize();
	retval = LMSSetValue("cmi.objectives.0.id", id);
	retval_itemScore = LMSGetValue("cmi.objectives.0.scores.0.raw");

	//retval = LMSFinish(); //this cause update DB on server, remove this line
	return retval_itemScore;
}
//VuAdd

function getItemMaxScore(id)
{
	//in case there is something wrong
	//alert('no score');
	if (id=="") return false;
	retval = LMSInitialize();
	retval = LMSSetValue("cmi.objectives.0.id", id);
	retval_itemScore = LMSGetValue("cmi.objectives.0.scores.0.max");
	//retval = LMSFinish();
	
	return retval_itemScore;
}


/************************************************************************************************
** Flash Wrapper Function
************************************************************************************************/

function DoFSCommand(command,args,objFlash)
{
	// Check for special case functions:
	if (command == "exit")
	{
		if (confirm("Do you really want to exit this course?"))
		{
			szParentReload = true;
			this.top.frames.DisplayFrame.close();
		}
		return true;
	}


	if (command == "getExamStatus")
	{
		var arrArgs = args.split(";");		
		var examStatus, itemStatus;

		examStatus = getExamStatus(arrArgs[0]);
		itemStatus = getItemStatus(arrArgs[5]);
		
		if (_Debug ==  true) {
			alert("get Question Status\n"+arrArgs[0]+"\nExam Status: "+examStatus);
		}

		if (examStatus == "not attempted"){
			objFlash.TGotoFrame(arrArgs[1],arrArgs[2]);
		}
		else {
			objFlash.TGotoFrame(arrArgs[3],arrArgs[4]);
		}
		return true;

	}
	if (command == "getResult"){
		var numOfCorrect;
		numOfCorrect = 0;
		if (getItemScore("Exam_Pool1") != 0) numOfCorrect = numOfCorrect + 1;
		if (getItemScore("Exam_Pool2") != 0) numOfCorrect = numOfCorrect + 1;
		if (getItemScore("Exam_Pool3") != 0) numOfCorrect = numOfCorrect + 1;
		if (getItemScore("Exam_Pool4") != 0) numOfCorrect = numOfCorrect + 1;
		if (getItemScore("Exam_Pool5") != 0) numOfCorrect = numOfCorrect + 1;
		if (getItemScore("Exam_Pool6") != 0) numOfCorrect = numOfCorrect + 1;
		if (getItemScore("Exam_Pool7") != 0) numOfCorrect = numOfCorrect + 1;
		if (getItemScore("Exam_Pool8") != 0) numOfCorrect = numOfCorrect + 1;
		if (getItemScore("Exam_Pool9") != 0) numOfCorrect = numOfCorrect + 1;
		if (getItemScore("Exam_Pool10") != 0) numOfCorrect = numOfCorrect + 1;
		//alert(numOfCorrect);
		switch (numOfCorrect){
			case 0: 
				objFlash.TGotoLabel("/resultsClip", "m0");
				break;
			case 1: 
				objFlash.TGotoLabel("/resultsClip", "m1");
				break;
			case 2: 
				objFlash.TGotoLabel("/resultsClip", "m2");
				break;
			case 3: 
				objFlash.TGotoLabel("/resultsClip", "m3");
				break;
			case 4: 
				objFlash.TGotoLabel("/resultsClip", "m4");
				break;
			case 5: 
				objFlash.TGotoLabel("/resultsClip", "m5");
				break;
			case 6: 
				objFlash.TGotoLabel("/resultsClip", "m6");
				break;
			case 7: 
				objFlash.TGotoLabel("/resultsClip", "m7");
				break;
			case 8: 
				objFlash.TGotoLabel("/resultsClip", "m8");
				break;
			case 9: 
				objFlash.TGotoLabel("/resultsClip", "m9");
				break;
			case 10: 
				objFlash.TGotoLabel("/resultsClip", "m10");
				break;
		}
		return true;
	}

	// Handler for all other DoFSCommand function calls:
	var arrArgs = args.split(";");
	var FSCommandCall, nArg;
	FSCommandCall = command + "()";
	for (nArg=0;nArg<arrArgs.length-1;nArg++) {
		FSCommandCall += (arrArgs + "[" + nArg + "]" + (i==0?",":""));
	}
	if (_Debug ==  true) {
		alert("Executing DoFSCommand: " + FSCommandCall);
	}

	return eval(FSCommandCall);
}


/************************************************************************************************
** Low Level Functions - LMS API Wrapper
************************************************************************************************/

function LMSInitialize()
{
	
   if (APIWin == null)
   {
      alert("Unable to locate the LMS's API Implementation.\nLMSInitialize was not successful.");
      return "false";
   }

   var result = APIWin.LMSInitialize("");

   if (result.toString() != "true")
   {
      var err = ErrorHandler();
   }

   return result.toString();
   
}


function LMSFinish()
{
   if (APIWin == null)
   {
      alert("Unable to locate the LMS's API Implementation.\nLMSFinish was not successful.");
      return "false";
   }
   else
   {
      // call the LMSFinish function that should be implemented by the API

      var result = APIWin.LMSFinish("");
      if (result.toString() != "true")
      {
         var err = ErrorHandler();
      }

   }

   return result.toString();
}


function LMSGetValue(name)
{
   if (APIWin == null)
   {
      alert("Unable to locate the LMS's API Implementation.\nLMSGetValue was not successful.");
      return "";
   }
   else
   {
      var result = APIWin.LMSGetValue(name);
      if (result.toString() == "false")
      {
         var err = ErrorHandler();
      }	      
      return result;	
   }
}

function LMSSetValue(name, value)
{
   if (APIWin == null)
   {
      alert("Unable to locate the LMS's API Implementation.\nLMSSetValue was not successful.");
      return;
   }
   else
   {
   	  //alert("name=" + name + ",value=" + value);
   	  var result = APIWin.LMSSetValue(name, value);
      //alert("name=" + name + ",result=" + result);
      if (result.toString() != "true")
      {
         var err = ErrorHandler();
      }
   }

   return result;
}

function LMSCommit()
{
   if (APIWin == null)
   {
      alert("Unable to locate the LMS's API Implementation.\nLMSCommit was not successful.");
      return "false";
   }
   else
   {
      var result = APIWin.LMSCommit("");
      if (result != "true")
      {
         var err = ErrorHandler();
      }
   }

   return result.toString();
}

function LMSGetLastError()
{
   if (APIWin == null)
   {
      alert("Unable to locate the LMS's API Implementation.\nLMSGetLastError was not successful.");
      //since we can't get the error code from the LMS, return a general error
      return _GeneralException;
   }
   else
      return APIWin.LMSGetLastError().toString();
}


function LMSGetErrorString(errorCode)
{
   if (APIWin == null)
   {
      alert("Unable to locate the LMS's API Implementation.\nLMSGetErrorString was not successful.");
   }
   else
      return APIWin.LMSGetErrorString(errorCode).toString();
}


function LMSGetDiagnostic(errorCode)
{
   if (APIWin == null)
   {
      alert("Unable to locate the LMS's API Implementation.\nLMSGetDiagnostic was not successful.");
   }
   else
      return APIWin.LMSGetDiagnostic(errorCode).toString();
}


function isLMSIsInitialized()
{
   // there is no direct method for determining if the LMS API is initialized
   // for example an LMSIsInitialized function defined on the API so we'll try
   // a simple LMSGetValue and trap for the LMS Not Initialized Error

   if (APIWin == null)
   {
      alert("Unable to locate the LMS's API Implementation.\nLMSIsInitialized() failed.");
      return false;
   }
   else
   {
      var value = APIWin.LMSGetValue("cmi.core.student_name");
      var errCode = APIWin.LMSGetLastError().toString();
      if (errCode == _NotInitialized)
      {
         return false;
      }
      else
      {
         return true;
      }
   }
}

function ErrorHandler()
{
   if (APIWin == null)
   {
      alert("Unable to locate the LMS's API Implementation.\nCannot determine LMS error code.");
      return;
   }

   // check for errors caused by or from the LMS
   //var errCode = APIWin.LMSGetLastError().toString();
   var errCode = APIWin.LMSGetLastError();	
   if (errCode != _NoError)
   {
      // an error was encountered so display the error description      
      var errDescription = APIWin.LMSGetErrorString(errCode);

      if (_Debug == true)
      {
         errDescription += "\n";
         errDescription += APIWin.LMSGetDiagnostic(null);
         // by passing null to LMSGetDiagnostic, we get any available diagnostics
         // on the previous error.
      }

      alert(errDescription);
   }

   return errCode;
}

/************************************************************************************************
** Course Player Utilities
************************************************************************************************/

function convertTime(strTime)
{
	if (strTime.length < 8 )
		return 0;
		 
	var arrTemp = strTime.split(":");
	var duration ;
	duration = parseInt(arrTemp[2]) * 1000; //ss
	duration = parseInt(arrTemp[1]) * 60 * 1000 + duration; // mm
	duration = parseInt(arrTemp[0]) * 60 * 60 * 1000 + duration; // hh
	return duration;
}

//Used to update parent status when child's status is set to 3
function updateParentStatus(id){
	var i, j, arrChildren;
	for (i=0; i<top.frames.DisplayFrame.rootObj.nChildren; i++){
		if (top.frames.DisplayFrame.rootObj.children[i].itemID == id){	
			//alert(top.frames.DisplayFrame.rootObj.children[i].szChildrenIndex);
			arrChildren = top.frames.DisplayFrame.rootObj.children[i].szChildrenIndex.split("_:_");			
			top.frames.DisplayFrame.rootObj.children[i].dirtyFlag = 1;
			top.frames.DisplayFrame.rootObj.children[i].itemStatus = 3;
			for (j=1; j<arrChildren.length - 1; j++){
				//alert(arrChildren[j]);
				if (top.frames.DisplayFrame.rootObj.children[arrChildren[j]].itemStatus!=3){
					//alert(rootObj.children[i].itemID + ":" + rootObj.children[i].itemStatus);
					top.frames.DisplayFrame.rootObj.children[i].itemStatus = 2;
					break;
				}
			}			
			updateParentStatus(top.frames.DisplayFrame.rootObj.children[i].parentID);	
			break;
		}
	}
}

//used to update question info
function updateQuestion(maxScore, rawScore){	
	//alert(updateQuestion);
	updateQuestionInfo(szPrevItemID, maxScore, rawScore); 
}