var apiHandle       = null;
var findAPITries    = 0;
var _Debug          = false;
var _NoError        = 0;
var apiErr          = false;
var terminateCalled = false;


function doSCORMInitialize() {
	var api = getAPIHandle();
	if (api == null) {
		return "false";
	}

	var result = "false";

	if (scormVer == "2004") {
		result = api.Initialize("");
	}
	else {
		result = api.LMSInitialize("");
	}
	terminateCalled = false;

	if (result.toString() != "true") {
		var err = ErrorHandler();
	}
	return result.toString();
}

function doSCORMTerminate() {
	if (terminateCalled) {
		return;
	}

	var api = getAPIHandle();
	if (api == null) {
		return "false";
	}

	var result = "false";

	if (scormVer == "2004") {
		result = api.Terminate("");
	}
	else {
		result = api.LMSFinish("");
	}
	terminateCalled = true;

	if (result.toString() != "true") {
		var err = ErrorHandler();
	}
	return result.toString();
}


function doSCORMCommit() {
	if (terminateCalled) {
		return;
	}

	var api = getAPIHandle();
	if (api == null) {
		return "false";
	}

	var result = "false";

	if (scormVer == "2004") {
		result = api.Commit("");
	}
	else {
		result = api.LMSCommit("");
	}

	if (result.toString() != "true") {
		var err = ErrorHandler();
	}
	return result.toString();
}


function doSCORMGetValue(name) {
	//alert(args);
	if (terminateCalled) {
		return;
	}

	var api = getAPIHandle();
	if (api == null) {
		return "";
	}

	var value = "";
	if (scormVer == "2004") {
		value = api.GetValue(name);
	}
	else {
		value = api.LMSGetValue(name);
	}

	var err = ErrorHandler();
	if (err != _NoError) {
		return "";
	}

	return value.toString();
}

function doSCORMSetValue(name, value) {
	if (terminateCalled) {
		return;
	}

	var api = getAPIHandle();
	if (api == null) {
		return "";
	}

	var result = "false";
	if (scormVer == "2004") {
		result = api.SetValue(name, value);
	}
	else {
		result = api.LMSSetValue(name, value);
	}
	if (result.toString() != "true") {
		var err = ErrorHandler();
	}
	return;
}


/*******************************************************************************
**
** Error Handling Functions
**
*******************************************************************************/


function ErrorHandler() {
	if (scormVer == "2004") {
		return ErrorHandler_SCORM2004();
	}
	else {
		return ErrorHandler_SCORM12();
	}
}


function ErrorHandler_SCORM12() {
	var api = getAPIHandle();
	if (api == null) {
		if (_Debug) {
			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 = api.LMSGetLastError().toString();
	if (errCode != _NoError) {
		if (_Debug == true) {

			// an error was encountered so display the error description
			var errDescription = api.LMSGetErrorString(errCode);
/*
DOUBLE CHECK TO SEE IF 1.2 WANTS null OR ""

			errDescription += "\n";
			//  Passing null to LMSGetDiagnostic, we get any available
			//  diagnostics on the previous error.
			errDescription += api.LMSGetDiagnostic(null);
*/
			alert(errDescription);
		}

	}
	return errCode;
}

function ErrorHandler_SCORM2004() {
	var api = getAPIHandle();
	if (api == null) {
		if (_Debug) {
			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 = api.GetLastError().toString();
	if (errCode != _NoError) {
		if (_Debug == true) {
			// an error was encountered so display the error description
			var errDescription = api.GetErrorString(errCode);

			errDescription += "\n";
			//  Passing "" to GetDiagnostic, we get any available
			//  diagnostics on the previous error.
			errDescription += api.GetDiagnostic("");

			alert(errDescription);
		}

	}
	return errCode;
}



function detectSCORMVersion() {
	parameterMode = "LMS";
	scormVer      = "2004";
	apiHandle     = getAPI(true);
	if ((apiHandle != null) && (apiHandle != undefined)) {
		setSCORMParamNames();
		return;
	}

	scormVer  = "1.2";
	apiHandle = getAPI(true);
	if ((apiHandle != null) && (apiHandle != undefined)) {
		setSCORMParamNames();
		return;
	}

	parameterMode = "cookie";
	scormVer      = "";
}

function setSCORMParamNames() {
	MODE_PARAM   = (scormVer == "1.2") ? "cmi.core.lesson_mode"   : "cmi.mode";
	DATA_PARAM   = (scormVer == "1.2") ? "cmi.suspend_data"       : "cmi.suspend_data";
	TIME_PARAM   = (scormVer == "1.2") ? "cmi.core.session_time"  : "cmi.session_time";
	EXIT_PARAM   = (scormVer == "1.2") ? "cmi.core.exit"          : "cmi.exit";
	ENTRY_PARAM  = (scormVer == "1.2") ? "cmi.core.entry"         : "cmi.entry";  // VERIFY 1.2 PARAM
}

/******************************************************************************
**
** Function getAPIHandle()
** Inputs:  None
** Return:  value contained by APIHandle
**
** Description:
** Returns the handle to API object if it was previously set,
** otherwise it returns null
**
*******************************************************************************/
function getAPIHandle() {
	if (apiHandle == null) {
		apiHandle = getAPI();
	}
	return apiHandle;
}


function getAPI(ignoreErr) {
	var theAPI;

	if (scormVer == "2004") {
		theAPI = findAPI_SCORM2004(window);
	}
	else {
		theAPI = findAPI_SCORM12(window);
	}

	if ( (theAPI == null) && (window.opener != null) && (typeof(window.opener) != "undefined") ) {
		if (scormVer == "2004") {
			theAPI = findAPI_SCORM2004(window.opener);
		}
		else {
			theAPI = findAPI_SCORM12(window.opener);
		}
	}
	if (!ignoreErr) {
		if (theAPI == null) {
			displayAPIWarning();
		}
		else if (apiErr) {
			//  A previous call to getAPI encountered an error, but we now seem to have contact.
			alert("Established connection with LMS SCORM API.");
			apiErr = false;
		}
	}
	//alert(theAPI);
	return theAPI;
}

function findAPI_SCORM2004(win) {
	while ( (win.API_1484_11 == null)&&(win.parent != null)&&(win.parent != win) ) {
		findAPITries++;

		if ( findAPITries > 500 ) {
			if (_Debug) {
				alert("Error finding SCORM 1.3 API -- too deeply nested.");
			}
			return null;
		}
		win = win.parent;
	}

	return win.API_1484_11;
}

function findAPI_SCORM12(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) {
			if (_Debug) {
				alert("Error finding SCORM 1.2 API -- too deeply nested.");
			}
			return null;
		}

		win = win.parent;
	}
	return win.API;
}

function displayAPIWarning() {
	if (apiErr) {
		return;
	}
	alert("Unable to find a SCORM API adapter.  Will not be able to communicate with the LMS.");
	apiErr = true;
}

