//
// wrapper na api scorm
//
// Version 1.3
//

var _Interactions = true;       // set this to false to turn interactions off
var _InteractionsText = false;  // set this to false to turn sending question text in interactions off 
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;

// local variable definitions
var apiHandle = null;
var API = null;
var findAPITries = 0;
var isInitialized = false;

var __$$_time = '';
var __$$_suspendData = '';
var __$$_lessonLocation = '';

function doLMSInitialize() {
    var api = getAPIHandle();
   
    if (api == null) {
        alert("Unable to locate the LMS's API Implementation.\nLMSInitialize was not successful.");
        return "false";
    }

    var result = api.LMSInitialize("");

    if (result.toString() != "true") {
        var err = ErrorHandler();
    } 
    else {
       isInitialized = true;
       checkInteractions();
    }

    return result.toString();
}

function doLMSFinish() {
    var result = 'false';
    var api = getAPIHandle();
    
    if (api == null) {
        alert("Unable to locate the LMS's API Implementation.\nLMSFinish was not successful.");
        return "false";
    }
    else if (isInitialized) {
        //Report time, lesson_location i suspend_data to LMS
        updateSCORMValues();
        // Call the LMSFinish function that should be implemented by the API
        result = api.LMSFinish("");
        if (result.toString() != "true") {
            var err = ErrorHandler();
        } 
        else {
           isInitialized = false;
        }
    }

    return result.toString();
}

function doLMSGetValue(name) {
    var api = getAPIHandle();
    
    if (api == null) {
        alert("Unable to locate the LMS's API Implementation.\nLMSGetValue was not successful.");
        return "";
    }
    else {
        var value = api.LMSGetValue(name);
        var errCode = api.LMSGetLastError().toString();
        
        if (errCode != _NoError) {
            // an error was encountered so display the error description
            var errDescription = api.LMSGetErrorString(errCode);
            alert("LMSGetValue(" + name + ") failed. \n" + errDescription);
            return "";
        }
        else {        
            return value.toString();
        }
    }
}

function doLMSSetValue(name, value) {
    var api = getAPIHandle();
    
    if (api == null) {
        alert("Unable to locate the LMS's API Implementation.\nLMSSetValue was not successful.");
        return;
    }
    else {
        var result = api.LMSSetValue(name, value);
        if (result.toString() != "true")
        {
            var err = ErrorHandler();
        }
    }

    return;
}

function doLMSCommit() {
    var api = getAPIHandle();
    
    if (api == null) {
        alert("Unable to locate the LMS's API Implementation.\nLMSCommit was not successful.");
        return "false";
    }
    else {
        //Report time, lesson_location i suspend_data to LMS
        updateSCORMValues();

        var result = api.LMSCommit("");
        if (result != "true") {
            var err = ErrorHandler();
        }
    }

    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;
        }
    }
}

function ErrorHandler() {
    var api = getAPIHandle();
   
    if (api == 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 = api.LMSGetLastError().toString();
  
    if (errCode != _NoError) {
        // an error was encountered so display the error description
        var errDescription = api.LMSGetErrorString(errCode);

        if (_Debug == true) {
            errDescription += "\n";
            errDescription += api.LMSGetDiagnostic(null);
            // by passing null to LMSGetDiagnostic, we get any available diagnostics
            // on the previous error.
        }
        alert(errDescription);
    }

    return errCode;
}

function getAPIHandle()
{
    if (apiHandle == null) {
        apiHandle = getAPI();
    }
    return apiHandle;
}

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;
}

function getAPI()
{
    var theAPI = findAPI(window);
  
    if (theAPI == null && window.top.opener != null && typeof(window.top.opener) != "undefined") {
        theAPI = findAPI(window.top.opener);
    }
    if (theAPI == null) {
        alert("Unable to find an API adapter");
    }
  
    return theAPI;
}


function updateSCORMValues() {
    try {
        var flashObj = getFlashMovieObject();
        
        flashObj.SetVariable("/MNTracker/trackerImpl:prepareJSValues", "");
        // time      
        try {
            var time = flashObj.GetVariable("_root.MNTracker.tempMovie.jsTime");
            if (__$$_time != time && time != 'null' && time != null) {
                doLMSSetValue("cmi.core.session_time", time);
            }
            __$$_time = time;
        } catch(e) {}

        // suspend_data
        try {
            var suspendData = flashObj.GetVariable("_root.MNTracker.tempMovie.jsSuspendData");
            if (__$$_suspendData != suspendData && suspendData != 'null' && suspendData != null) {
                doLMSSetValue("cmi.suspend_data", suspendData);
            }
            __$$_suspendData = suspendData;
        } catch(e) {}

        // lesson_location
        try {
            var lessonLocation = flashObj.GetVariable("_root.MNTracker.tempMovie.jsLessonLocation");
            if (__$$_lessonLocation != lessonLocation && lessonLocation != 'null' && lessonLocation != null) {
                doLMSSetValue("cmi.core.lesson_location", lessonLocation);
            }
            __$$_lessonLocation = lessonLocation;
        } catch(e) {}
        
        // interactions
        try {
            var startIndex = parseInt(flashObj.GetVariable("_root.MNTracker.tempMovie.jsInteractionStartIndex"));
            var count = parseInt(flashObj.GetVariable("_root.MNTracker.tempMovie.jsInteractionsCount"));

            if (_Interactions == true && !isNaN(startIndex) && isFinite(startIndex) 
                        && !isNaN(count) && isFinite(count)) {
                for (var idx = startIndex; idx < count; ++idx) {
                    try {
                        doLMSSetValue("cmi.interactions." + idx + ".id", 
                                      flashObj.GetVariable("_root.MNTracker.tempMovie.jsInteractionId" + idx));
                        doLMSSetValue("cmi.interactions." + idx + ".time", 
                                      flashObj.GetVariable("_root.MNTracker.tempMovie.jsInteractionTime" + idx));
                        doLMSSetValue("cmi.interactions." + idx + ".type", 
                                      flashObj.GetVariable("_root.MNTracker.tempMovie.jsInteractionType" + idx));
                        doLMSSetValue("cmi.interactions." + idx + ".correct_responses.0.pattern", 
                                      flashObj.GetVariable("_root.MNTracker.tempMovie.jsInteractionCResp" + idx));
                        var sResp = flashObj.GetVariable("_root.MNTracker.tempMovie.jsInteractionSResp" + idx);
                        if (sResp != '{}' && sResp != '' && sResp != 'null' && sResp != null && sResp != 'undefined') {
                        	doLMSSetValue("cmi.interactions." + idx + ".student_response", sResp);
                        }
                        doLMSSetValue("cmi.interactions." + idx + ".result", 
                                      flashObj.GetVariable("_root.MNTracker.tempMovie.jsInteractionResult" + idx));
                        doLMSSetValue("cmi.interactions." + idx + ".latency", 
                                      flashObj.GetVariable("_root.MNTracker.tempMovie.jsInteractionLatency" + idx));
                        if (_InteractionsText == true) {              
                            doLMSSetValue("cmi.interactions." + idx + ".text", 
                                          flashObj.GetVariable("_root.MNTracker.tempMovie.jsInteractionText" + idx));
                        }
                    } catch (e) {}
                }
            }
        } catch(e) {}
    } catch(e) {}
}

/* 
 * Flash call function. 
 */
function flashCall(_command,_args){
    //alert(_command + " " + _args);
    doCommand(_command, _args);
}

/**
 * Handler FSCommand do sledzenia
 */
function doCommand(command, args) {
    try {
        switch (command) {
        case "init":
            doLMSInitialize();
            var text = "lesson_location=" + doLMSGetValue("cmi.core.lesson_location") + "\n"
                       + "lesson_status=" + doLMSGetValue("cmi.core.lesson_status") + "\n"
                       + "score=" + doLMSGetValue("cmi.core.score.raw") + "\n"
                       + "suspend_data=" + doLMSGetValue("cmi.suspend_data") + "\n"
                       + "student_name=" + doLMSGetValue("cmi.core.student_name") + "\n"
                       + "interactions_count=" + (_Interactions ? doLMSGetValue("cmi.interactions._count") : 0);
            getFlashMovieObject().SetVariable(args, text);
            break;

        case "set":
            args = new String(args);
            var i = args.indexOf(":");
            doLMSSetValue(args.substr(0, i), args.substr(i + 1));
            break;
    
        case "commit":
            doLMSCommit();
            getFlashMovieObject().SetVariable(args, (doLMSGetLastError() == "0") ? "ok" : "");
            break;

        case "finish":
            doLMSFinish();
            getFlashMovieObject().SetVariable(args, (doLMSGetLastError() == "0") ? "ok" : "");
            break;
        }
    } catch(e) {}
}

/*
 * Zwraca obiekt flasza z uwzglednieniem IE, Firefox
 */
function getFlashMovieObject() {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        return window["swfplayer"];
    } 
    else {
        return document["swfplayer"];
    }
}

/*
 * Sprawdza czy LMS obsluguje interakcje i parametr z tekstem pytania
 */
function checkInteractions() {
	var api = getAPIHandle();
	var value = api.LMSGetValue("cmi._children");
	var dataModel = value.toString();
	if (checkIfPresent(dataModel, "interactions") == false) {
		// Interakcje nie sa obslugiwane
		_Interactions = false;
	} else {
	  var interactionsValue = api.LMSGetValue("cmi.interactions._children");
		var interactionsChildren = interactionsValue.toString();
		if (checkIfPresent(interactionsChildren, "text") == false) {
			// Tekst pytan w interakcjach nie jest obslugiwany
			_InteractionsText = false;
		}
	}
}

/*
 * Sprawdza czy podana wartosc znajduje sie w stringu
 */
function checkIfPresent(data, property) {
	var values = new Array();
	values = data.split(",");
	for (var i = 0; i < values.length; i++) {
		if(values[i] == property) {
			return true;
		}
	}
	return false;
}

