// version: 2009-04-23
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 _api_initialized = false;
var lmsloggerWindow;
var lmsloggerConsole;
var courseloggerWindow;
var courseloggerConsole;

//var _usescorm = ${usescorm};

// local variable definitions
var apiHandle = null;
var API = null;
var findAPITries = 0;
var intervalID = null;

// initializing of global xmlhttp object used for xmlhttprequest whend sending exitAu for AICC-loging
var xmlhttp;

//local variables used by flash to try and keep track of how many multiple connections are in use
var uselmsConsole = false;							//if true, creates a new window to dump lms specific debuginfo into
var usecourseConsole = false;						//if true, creates a new window to dump course specific debuginfo into

if (uselmsConsole == true) {
	createlmsConsole();
}

if (usecourseConsole == true) {
	createcourseConsole();
}

function createlmsConsole() {
	uselmsConsole = true;
	lmsloggerWindow = window.open("",'mintralmsloggerWindow',"width=900,height=300,left=0,top=0, resizable=yes, scrollbars=yes");
	lmsloggerConsole = lmsloggerWindow.document;
	lmsloggerConsole.open ("text/html", "replace");
	lmsloggerConsole.write ("<HTML><HEAD><TITLE>Mintra LMS output console v0.4</TITLE></HEAD><BODY>");
	lmsloggerConsole.write ("<basefont size='2' face='Verdana'");
	lmsconsoleTrace (5, "Mintra course started " + new Date().getDate() + "/" + (new Date().getMonth()+1) + "-" + new Date().getFullYear(), "LMS specific output");
}

function createcourseConsole() {
	usecourseConsole = true;
	courseloggerWindow = window.open("",'mintracourseloggerWindow',"width=900,height=400,left=0,top=330, resizable=yes, scrollbars=yes");
	courseloggerConsole = courseloggerWindow.document;
	courseloggerConsole.open ("text/html", "replace");
	courseloggerConsole.write ("<HTML><HEAD><TITLE>Mintra course output console v0.4</TITLE></HEAD><BODY>");
	courseloggerConsole.write ("<basefont size='2' face='Verdana'");
	courseconsoleTrace (5, "Mintra course started " + new Date().getDate() + "/" + (new Date().getMonth()+1) + "-" + new Date().getFullYear(), "Course specific output");
}



//function to save xml sent from flash to the client machine
function doXMLSaveAs(stringFromFlash){
//if InternetExplorer
	if (document.execCommand){
		doc = window.open("","newWin", "status=1,width=100,height=100");					  //open new window
		doc.document.write(stringFromFlash);
		var saveSuccess = doc.document.execCommand("SaveAs", false, 'studentList' + ".xml");	  		//auto-invoke the "save as" dialogBox on the new window	
	}else{
		alert('Feature available only in Internet Exlorer.');
	}
	
	if(saveSuccess){																		   //if save-as ok, close the new window and inform the user
		doc.close ();
		alert('XML file saved ok!');
		}
}


//takes content of clipboard and adds data to it
//tracemode: 0=black, 1=red, 2=yellow, 3=green, 4=blue
//tracecommand is always in bold
function lmsconsoleTrace (traceColor, traceCommand, traceDetails) {
	var debuggerLog = "";
	var date = new Date();
	var clockHours = date.getHours().toString();
	var clockMinutes = date.getMinutes().toString();
	var clockSeconds = date.getSeconds().toString();
	var clockMilliseconds = date.getMilliseconds().toString();
	var colorList = ["black", "red", "green", "#92D050", "blue", "#FF6600", "Turquoise", "Pink", "Brown", "Light Green", "#0066CC", "#3399FF", "#33CCFF"];
	var traceDelimiter = "<font color='black'>... ";

	if (traceColor == undefined) {
		traceColor = 0;
	}

	//need xx format
	if (clockHours.length == 1) {
		clockHours = "0" + clockHours;
	}
	if (clockMinutes.length == 1) {
		clockMinutes = "0" + clockMinutes;
	}
	if (clockSeconds.length == 1) {
		clockSeconds = "0" + clockSeconds;
	}
	if (clockMilliseconds.length == 1) {
		clockMilliseconds = "00" + clockMilliseconds;
	} else if (clockMilliseconds.length == 2) {
		clockMilliseconds = "0" + clockMilliseconds;
	}
	
	var clock = "[" + clockHours + ":" + clockMinutes + ":" + clockSeconds + "," + clockMilliseconds + "]";

	//create log to output, but only if in use
	if (uselmsConsole == true) {
		debuggerLog += "<br>" + clock;									//timestamp
		debuggerLog += "<font color='" + colorList[traceColor] + "'>";	//color
		debuggerLog += "  <b>" + traceCommand + "</b></font>";			//command
		debuggerLog += traceDelimiter + traceDetails;					//detail info
		debuggerLog += "</font>";
		if ( lmsloggerConsole != undefined ) {
			lmsloggerConsole.write (debuggerLog);
		}
		
		lmsloggerWindow.scrollBy (0, 100);								//scroll automatically / autoscroll
	}
}

//takes content of clipboard and adds data to it
//tracemode: 0=black, 1=red, 2=yellow, 3=green, 4=blue
//tracecommand is always in bold
function courseconsoleTrace (traceColor, traceCommand, traceDetails) {
	var debuggerLog = "";
	var date = new Date();
	var clockHours = date.getHours().toString();
	var clockMinutes = date.getMinutes().toString();
	var clockSeconds = date.getSeconds().toString();
	var clockMilliseconds = date.getMilliseconds().toString();
	var colorList = ["black", "red", "green", "#92D050", "blue", "#FF6600", "Turquoise", "Pink", "Brown", "Light Green", "#0066CC", "#3399FF", "#33CCFF"];
	var traceDelimiter = "<font color='black'>... ";

	if (traceColor == undefined) {
		traceColor = 0;
	}

	//need xx format
	if (clockHours.length == 1) {
		clockHours = "0" + clockHours;
	}
	if (clockMinutes.length == 1) {
		clockMinutes = "0" + clockMinutes;
	}
	if (clockSeconds.length == 1) {
		clockSeconds = "0" + clockSeconds;
	}
	if (clockMilliseconds.length == 1) {
		clockMilliseconds = "00" + clockMilliseconds;
	} else if (clockMilliseconds.length == 2) {
		clockMilliseconds = "0" + clockMilliseconds;
	}
	
	var clock = "[" + clockHours + ":" + clockMinutes + ":" + clockSeconds + "," + clockMilliseconds + "]";

	//create log to output, but only if in use
	if (usecourseConsole == true) {
		debuggerLog += "<br>" + clock;									//timestamp
		debuggerLog += "<font color='" + colorList[traceColor] + "'>";	//color
		debuggerLog += "  <b>" + traceCommand + "</b></font>";			//command
		debuggerLog += traceDelimiter + traceDetails;
		debuggerLog += "</font>";
		if ( courseloggerConsole != undefined ) {
			courseloggerConsole.write (debuggerLog);
		}
		
		courseloggerWindow.scrollBy (0, 100);							//scroll automatically / autoscroll
	}
}

function noContinueOnError() {
 return !_continueOnError;
}

/**
* Initiates LMS
*/
function doLMSInitialize(scoid) {
	lmsconsoleTrace (0, "doLMSInitialize", "scoid = "+scoid);

	if (isAPIAvailable()) {
		var api = getAPIHandle();
		if (api == null) {
			errorHandle("NO API-adapter present (in doLMSInitialize)");
			return "false";
		}
		var temp;
		temp = String(scoid);
		if (temp == "undefined") {
			temp = "";
		}
		
		lmsconsoleTrace (2, "doLMSInitialize", "sending api.LMSInitialize");

		var result = api.LMSInitialize(temp);

		lmsconsoleTrace (3, "doLMSInitialize", "received api.LMSInitialize = " + result);
		
		if (result.toString() != "true") {
			var errCode = api.LMSGetLastError().toString();
			var errorMessage = "General error"
			if (errCode != _NoError) {
				// an error was encountered so display the error description
				errorMessage =  doLMSGetErrorString(errCode)
			}
			errorHandle("ErrorCode: " +errorMessage + "  (in doLMSInitialize)");
		}
		_api_initialized = true;
		if (_usescorm)
			intervalID = setInterval(ifAPINotAvailble, 4000);
		return result.toString();
	}
}

/**
* Tells the LMS that the application has been closed
*/
function doLMSFinish(indata) {
	lmsconsoleTrace (0, "doLMSFinish", "indata = " + indata);
	
	//APIWindow = null;
	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
			
			lmsconsoleTrace (2, "doLMSFinish", "sending api.LMSFinish");

			var result = api.LMSFinish("");

			lmsconsoleTrace (3, "doLMSFinish", "received api.LMSFinish = "+result);

			if (result.toString() != "true") {
				var errCode = api.LMSGetLastError().toString();
				var errorMessage = "General error"
				if (errCode != _NoError) {
					// an error was encountered so display the error description
					errorMessage =  doLMSGetErrorString(errCode)
				}
				errorHandle("ErrorCode: " +errorMessage + "  (in doLMSFinish)");
			}
		}
		return result.toString();
	} else {
		checkCallExitAu();
	}
}

function doLMSGetValue(name, scoid) {
	lmsconsoleTrace (0, "doLMSGetValue", "name = <b>" + name + "</b>, scoid = " + 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 == "") {
					
					lmsconsoleTrace (2, "doLMSGetValue", "sending api.LMSGetValue");

					value = api.LMSGetValue(name);

					lmsconsoleTrace (3, "doLMSGetValue", "received api.LMSGetValue = " + value);
				} else {
					
					lmsconsoleTrace (2, "doLMSGetValue", "sending api.LMSGetValue");

					value = api.LMSGetValue(name, temp);

					lmsconsoleTrace (3, "doLMSGetValue", "received api.LMSGetValue = " + value);
				}
				var errCode = api.LMSGetLastError().toString();
				if (errCode != _NoError) {
					// an error was encountered so display the error description
					errorHandle("ErrorCode: " +doLMSGetErrorString(errCode) + "  (in doLmsGetValue)");
				} else {
					return value.toString();
				}
			}
		}
	}
}

/**
* Sends data to the LMS
*/
function doLMSSetValue(name, value, scoid) {
	lmsconsoleTrace (0, "doLMSSetValue", "name = <b>" + name + "</b>, value = <b>" + value + "</b>, scoid = " + scoid);

	var api = getAPIHandle();
	if (api == null) {
			errorHandle("API Adapter not found (in doLMSSetValue)");
		return;
	} else {
		var result;
		temp = String(scoid);
		if (temp == "undefined" || temp == "") {

			lmsconsoleTrace (2, "doLMSSetValue", "sending api.LMSsetValue");

			result = api.LMSSetValue(name, value);

			lmsconsoleTrace (3, "doLMSSetValue", "received api.LMSsetValue = " + result);
		} else {
			
			lmsconsoleTrace (2, "doLMSSetValue", "sending api.LMSsetValue");

			result = api.LMSSetValue(name, value, temp);

			lmsconsoleTrace (3, "doLMSSetValue", "received api.LMSsetValue = " + result);
		}
		if (result.toString() != "true") {
			var errCode = api.LMSGetLastError().toString();
			var errorMessage = "General error"
			if (errCode != _NoError) {
				// an error was encountered so display the error description
				errorMessage =  doLMSGetErrorString(errCode)
			}
			errorHandle("ErrorCode: " +errorMessage + "  (in doLMSSetValue)");
		}
	}
	return result.toString();
}
function doLMSCommit() {
	lmsconsoleTrace (0, "doLMSCommit", "");

	var api = getAPIHandle();
	if (api == null) {
		  errorHandle();
	} else {
		
		lmsconsoleTrace (2, "doLMSCommit", "sending api.LMSCommit");

		var result = api.LMSCommit("");

		lmsconsoleTrace (3, "doLMSCommit", "received api.LMSCommit = " + result);
		if (result != "true") {
			var errCode = api.LMSGetLastError().toString();
			var errorMessage = "General error"
			if (errCode != _NoError) {
				// an error was encountered so display the error description
				errorMessage =  doLMSGetErrorString(errCode)
			}
			errorHandle("ErrorCode: " +errorMessage + "  (in doLMSCommit)");
		}
	}
	return result.toString();
}
function doLMSGetLastError() {
	lmsconsoleTrace (0, "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

	lmsconsoleTrace (0, "LMSIsInitialized", "");

	var api = getAPIHandle();
	if (api == null) {
		alert("Unable to locate the LMS's API Implementation.\nLMSIsInitialized() failed.");
		return false;
	} else {

		lmsconsoleTrace (2, "LMSIsInitialized", "sending api.LMSGetValue ('cmi.core.student_name')");

		var value = api.LMSGetValue("cmi.core.student_name");

		lmsconsoleTrace (3, "LMSIsInitialized", "received api.LMSGetValue ('cmi.core.student_name') = " + value);

		var errCode = api.LMSGetLastError().toString();
		if (errCode == _NotInitialized) {
			return false;
		} else {
			return true;
		}
	}
}

/**
* Handling errors
*/
function errorHandle(errorString)
{
	 if ( noContinueOnError())	{
		// Set to use scorm, but did not find API 
			document.location.href = "scorm_error.html?errorString=" + errorString;
	   } 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;
	}
	findAPITries =0;
	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;
}


//returns active api window / frame / handle
function findAPIWindow(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;
}

/**
* 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("No API adapter present");
			return false;
		} else {
			try {
				if ( _api_initialized ) {
			 		//value = api.LMSGetValue("cmi.launch_data");
			 	}
			} 
			catch ( e ) { 
				errorHandle("isAPIAvailable failed - "+ e.name +":" +e.message);
				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;
			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" || usecommentsfield == "true") {
			result += doLMSGetValue("cmi.comments");
		}
		
		if ((lessonstatus != "passed") && (lessonstatus != "p") && (lessonstatus != "complete") && (lessonstatus != "completed")&& (lessonstatus != "c")) {
			doLMSSetValue("cmi.core.lesson_status", "incomplete");
		} else {
			doLMSSetValue("cmi.core.lesson_status", lessonstatus);
		}
		doLMSCommit();

		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);
      }
    }
  }
}

//2010-10-10 - Added by fabrice miras
//The function checks if the API is present on a given parent depth level, findAPITries, and return true on success.
function findAPIOpener(win) {
	var _apiHand;
	var y = 0;
	var isfound = false;
	while ((win.API == null) && (win.parent != null) && (win.parent != win)) {
		y++;
		if (findAPITries > y) {
			return null;
		}
		win = win.parent;
		_apiHand = getAPI(win);
		if (_apiHand != undefined) isfound = true;
	}
	return isfound;
}

//Called every 4 seconds. Trigger an error when API is lost.
ifAPINotAvailble = function (){
	var isData =  findAPIOpener(window);
	if (! isData) {
		errorHandle("<strong>The course has lost its connection to the server. It is possible that the STARTCOURSE page was closed.</strong>");
		clearInterval(intervalID);
	}
}
