// version: 2006-03-21
var _Debug = true;
// set this to false to turn debugging off
// and get rid of those annoying alert boxes.
// Define exception/error codes

var _continueOnError = false; // Set this to false if continueOnError should not be possible


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;
//var _usescorm = ${usescorm};

// local variable definitions
var apiHandle = null;
var API = null;
var findAPITries = 0;

// initializing of global xmlhttp object used for xmlhttprequest whend sending exitAu for AICC-loging
var xmlhttp;

function noContinueOnError() {
 return !_continueOnError;
}

/**
* Initiates LMS
*/
function doLMSInitialize(scoid) {
	if (isAPIAvailable()) {
		var api = getAPIHandle();
		if (api == null) {
			errorHandle();
			 return "false";
		}
		var temp;
		temp = String(scoid);
		if (temp == "undefined") {
			temp = "";
		}
		var result = api.LMSInitialize(temp);
		if (result.toString() != "true") {
				errorHandle();
		}
		return result.toString();
	}
}

/**
* Tells the LMS that the application has been closed
*/
function doLMSFinish(indata) {
	if (isAPIAvailable()) {
		var api = getAPIHandle();
		if (api == 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 = api.LMSFinish("");
			if (result.toString() != "true") {
				var err = errorHandle();
			}
		}
		return result.toString();
	} else {
		checkCallExitAu();
	}
}

function doLMSGetValue(name, scoid) {
	if (isAPIAvailable())	{
		// if name is not defined, find scopath in url instead of through cmi.launch_data
		if (name == "" || name == undefined) {
			var lmsUrl = unescape(document.URL.replace(/\\/g,"\/"));
			var scoPath = "";
			if (lmsUrl.indexOf("pathtosco=") != -1) {
				scoPath = lmsUrl.substring(lmsUrl.indexOf("pathtosco="),lmsUrl.length);
				var endIndex = scoPath.length;
				if (scoPath.indexOf("&") != -1) {
					endIndex = scoPath.indexOf("&");
				}
				scoPath = scoPath.substring(10,endIndex);
				return scoPath;
			} else {
				return doLMSGetValue("cmi.launch_data");
			}

		} else {
			var api = getAPIHandle();
			if (api == null) {
				alert("Unable to locate the LMS's API Implementation.\nLMSGetValue was not successful.");
				return "";
			} else {
				var value;
				temp = String(scoid);
				if (temp == "undefined" || temp == "") {
					value = api.LMSGetValue(name);
				} else {
					value = api.LMSGetValue(name, temp);
				}
				var errCode = api.LMSGetLastError().toString();
				if (errCode != _NoError) {
					// an error was encountered so display the error description
					errorHandle();
				} else {
					return value.toString();
				}
			}
		}
	}
}

/**
* Sends data to the LMS
*/
function doLMSSetValue(name, value, scoid) {
	var api = getAPIHandle();
	if (api == null) {
		errorHandle();
		return;
	} else {
		var result;
		temp = String(scoid);
		if (temp == "undefined" || temp == "") {
			result = api.LMSSetValue(name, value);
		} else {
			result = api.LMSSetValue(name, value, temp);
		}
		if (result.toString() != "true") {
			  errorHandle();
		}
	}
	return result.toString();
}
function doLMSCommit() {
	var api = getAPIHandle();
	if (api == null) {
		  errorHandle();
	} else {
		var result = api.LMSCommit("");
		if (result != "true") {
			  errorHandle();
		}
	}
	return result.toString();
}
function doLMSGetLastError() {
	var api = getAPIHandle();
	if (api == 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 _GeneralError;
	}
	return api.LMSGetLastError().toString();
}
function doLMSGetErrorString(errorCode) {
	var api = getAPIHandle();
	if (api == null) {
		alert("Unable to locate the LMS's API Implementation.\nLMSGetErrorString was not successful.");
	}
	return api.LMSGetErrorString(errorCode).toString();
}
function doLMSGetDiagnostic(errorCode) {
	var api = getAPIHandle();
	if (api == null) {
		alert("Unable to locate the LMS's API Implementation.\nLMSGetDiagnostic was not successful.");
	}
	return api.LMSGetDiagnostic(errorCode).toString();
}
function LMSIsInitialized() {
	// 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
	var api = getAPIHandle();
	if (api == null) {
		alert("Unable to locate the LMS's API Implementation.\nLMSIsInitialized() failed.");
		return false;
	} else {
		var value = api.LMSGetValue("cmi.core.student_name");
		var errCode = api.LMSGetLastError().toString();
		if (errCode == _NotInitialized) {
			return false;
		} else {
			return true;
		}
	}
}

/**
* Handling errors
*/
function errorHandle()
{
	 if ( noContinueOnError())	{
		// Set to use scorm, but did not find API 
			document.location.href = "scorm_error.html"
	   } else {
		   return false;
	   }

}

/**
* Gets API the handle
*/
function getAPIHandle() {
	if (apiHandle == null) {
		apiHandle = getAPI(window);
	}
	return apiHandle;
}

/**
* Find API in window
*
* @param	win		reference to a window
*/
function findAPI(win) {
	while ((win.API == null) && (win.parent != null) && (win.parent != win)) {
		findAPITries++;
		// Note: 7 is an arbitrary number, but should be more than sufficient
		if (findAPITries>7) {
			//alert("Error finding API -- too deeply nested.");
			return null;
		}
		win = win.parent;
	}
	return win.API;
}

/**
* Get API
*/
function getAPI(vindu) {
	var theAPI = findAPI(vindu);
	if ((theAPI == null) && (typeof (vindu.top.opener) != "undefined") && (!vindu.top.opener.closed)) {
		theAPI = getAPI(vindu.top.opener);
	}
	return theAPI;
}

/**
* COMMENT:
* 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
*/
function isAPIAvailable() {
	if (_usescorm == undefined){
		_usescorm=false;
	}
	if (!_usescorm) {
		return false;
	} else {
		var api = getAPIHandle();
		if (api == null) {
			errorHandle();
			return false;
		} else {
			try { 
				value = api.LMSGetValue("cmi.launch_data");
			} 
			catch ( e ) { 
				errorHandle();
			   return false;
			} 
			return true;
		}
	}
}


function initializesco(ScoIdentifier, jsId) {
	// Brukes i utvidet API-st�tte
	if (isAPIAvailable()) {
		var result = doLMSInitialize(ScoIdentifier);
		var retval;
		if (result == "true") {
			retval = "0";
		} else {
			retval = "1";
		}
		return "ReturnDataFromAPI "+retval+"#newsco#"+"";
	}
}

/**
* Collects any valid LMS values after request from flash application
*/
function getlmsvalues(jsId) {
	var ok = false;
	if (isAPIAvailable()) {
		// har funnet API-adapter
		var result = doLMSInitialize();
		if (result == "true") {
			// initalisering har g�tt bra, hent oppstartsdata
			ok = true;
			// old method:
			//result = doLMSGetValue("cmi.launch_data");
			// new method:
			result = doLMSGetValue();
			return "SCORM#"+result;
		}
	}
	if (!ok) {
		// Har ikke funnet API-adapter
		return unescape(document.URL.replace(/\\/g,"\/"));
	}
}

/**
* Collect data from the LMS and sends it back to the application
*/
function getapidata(usecommentsfield, jsId) {
	if (isAPIAvailable()) {
		// Henter data fra LMS-et og sende det til navigasjonslaget
		var result = "";
		var delim = "#";
		var lessonstatus = doLMSGetValue("cmi.core.lesson_status");
		result += doLMSGetValue("cmi.core.student_name")+delim;
		result += doLMSGetValue("cmi.core.lesson_location")+delim;
		result += doLMSGetValue("cmi.core.score.raw")+delim;
		result += lessonstatus+delim;
		var temp = doLMSGetValue("cmi.suspend_data");
		result += temp+delim;
		// sjekk om man skal bruke commentsfield
		if (usecommentsfield == "1") {
			result += doLMSGetValue("cmi.comments");
		}
		if ((lessonstatus != "passed") && (lessonstatus != "p") && (lessonstatus != "complete") && (lessonstatus != "c")) {
			doLMSSetValue("cmi.core.lesson_status", "incomplete");
		}
		return result;
	}
}

/**
* Sends data sent from application to the LMS
*/
function setapidata(indata, jsId) {
	if (isAPIAvailable()) {
		// Sender data til LMS-et 
		ParameterList = indata.split("##");
		var ok = doLMSSetValue("cmi.core.lesson_status", ParameterList[0]);
		if (ok) {
			ok = doLMSSetValue("cmi.core.session_time", ParameterList[1]);
			ok = doLMSSetValue("cmi.core.lesson_location", ParameterList[2]);

			// flash sends the value 999 if score not should be sent
			if (ParameterList[3] != "999" && ParameterList[3] != 999) {
				ok = doLMSSetValue("cmi.core.score.raw", ParameterList[3]);
			}

			ok = doLMSSetValue("cmi.suspend_data", ParameterList[4]);
			if (ParameterList.length == 6) {
				ok = doLMSSetValue("cmi.comments", ParameterList[5]);
			}
			doLMSCommit();
		}
		return "ReturnDataFromAPI 0##putparam##";
	}
}

function setcoursecomment(indata) {
	if (isAPIAvailable()) {
	
		 ok =  doLMSSetValue("cmi.course.comment", indata);
		 doLMSCommit();
	}

}

function getcoursecomment() {
	if (isAPIAvailable()) {
		 indata =  doLMSGetValue("cmi.course.comment");
		 timeOutId = setTimeout("shockmessage('navigation','receivecoursecommentFromLMS "+indata  + "')",100)
	}
}


// returns a string with suspenddata for all scos, seperated by @@
 function getallsequencesstatus (scostring, jsId) {
	if (isAPIAvailable()) {
		// St�tte for � hente status p� alle sekvenser i kurset
		var scolist = new Array()
		scolist = scostring.split("#")
		var result = ""
		var temp = ""
		for (var c = 0; c < scolist.length; c++) {
			temp = doLMSGetValue("cmi.suspend_data", scolist[c])
			result = result + temp +"@@"
		}
		// remove last @@
		result = result.substring(0,result.length - 2);
		return result;
	}
}

// returns a string with status for all scos, seperated by "@@"
// scostring: string with id for all scos, seperated  by #
 function getscostatus (scostring, jsId) {
	if (isAPIAvailable()) {
		// St�tte for � hente status p� alle sekvenser i kurset
		var scolist = new Array()
		scolist = scostring.split("#")
		var result = ""
		var temp = ""
		for (var c = 0; c < scolist.length; c++) {	
			temp = doLMSGetValue("cmi.core.lesson_status", scolist[c])
			result = result + temp +"@@";
		}
		// remove last @@
		result = result.substring(0,result.length - 2);
		return result;
	}
}

////////////////////////////////////////
// FUNCTIONS FOR AICC / HACP - LOGING //
////////////////////////////////////////

/**
* Sends exitAu if using AICC-logging
*/
function checkCallExitAu() {
	var url=unescape(document.URL.replace(/\\/g,"\/"));
	if (url.toUpperCase().indexOf("AICC_URL") == - 1) {
		// is not using aicc-logging
		return;
	}

	//aicc_url
	var startIndex = url.toUpperCase().indexOf("AICC_URL") + 9;
	var endIndex = url.indexOf("&", startIndex);
	if (endIndex < startIndex) {
		endIndex = url.length;
	}
	var hacp_aicc_url = url.substring(startIndex, endIndex);
	
	//aicc_sid
	var startIndex = url.toUpperCase().indexOf("AICC_SID") + 9;
	var endIndex = url.indexOf("&", startIndex);
	if (endIndex < startIndex) {
		endIndex = url.length;
	}
	var hacp_aicc_sid = url.substring(startIndex, endIndex);
	exitAUResponse(hacp_aicc_url, hacp_aicc_sid);
}


function exitAUResponse(hacp_aicc_url, hacp_aicc_sid){
	  // Obtain an XMLHttpRequest instance

	  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
	
	  // Set the handler function to receive callback notifications
	  // from the request object
	  var handlerFunction = getReadyStateHandler(xmlhttp, getReturnValue);
	  xmlhttp.onreadystatechange = handlerFunction;
	  // Open an HTTP POST/GET connection to the servlet.
	  // Third parameter specifies request is asynchronous.
	  xmlhttp.open("GET", hacp_aicc_url+"?command=exitau&Version=3.3&Session_id="+hacp_aicc_sid, false);
	  xmlhttp.send();
	  return xmlhttp.responseText;
}

function getReturnValue(xmlhttp){
	return xmlhttp.responseText;
}

function getReadyStateHandler(xmlhttp, responseXmlHandler) {
  return function () {
    if (xmlhttp.readyState == 4) {
      
      // Check that a successful server response was received
      if (xmlhttp.status == 200) {

        // Pass the XML payload of the response to the 
        // handler function
        responseXmlHandler(xmlhttp);

      } else {
        // An HTTP problem has occurred
		alert("An error occured while communicating with the LMS. "+"\n"+"Your progress will not be saved"+"\n"+"Error message:"+xmlhttp.status);
      }
    }
  }
}
