var findAPITries = 0;
var maxTries = 500;
//Scorm 2004 FindAPI
function ScanForAPI(win){
    while ((win.API_1484_11 == null) && (win.parent != null) &&
    (win.parent != win)) {
        nFindAPITries++;
        if (nFindAPITries > maxTries) {
            return null;
        }
        win = win.parent;
    }
    return win.API_1484_11;
}

function GetAPI(win){
    if ((win.parent != null) && (win.parent != win)) {
        API = ScanForAPI(win.parent);
    }
    if ((API == null) && (win.opener != null)) {
        API = ScanForAPI(win.opener);
    }
}


//Scorm 1.2 FindAPI
function findAPI(win){
    // Check to see if the window (win) contains the API
    // if the window (win) does not contain the API and
    // the window (win) has a parent window and the parent window
    // is not the same as the window (win)
    while ((win.API == null) &&
    (win.parent != null) &&
    (win.parent != win)) {
        // increment the number of findAPITries
        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;
        }
        
        // set the variable that represents the window being
        // being searched to be the parent of the current window
        // then search for the API again
        win = win.parent;
    }
    return win.API;
}

function getAPI(){
    // start by looking for the API in the current window
    var theAPI = findAPI(window);
    
    // if the API is null (could not be found in the current window)
    // and the current window has an opener window
    if ((theAPI == null) &&
    (window.opener != null) &&
    (typeof(window.opener) != "undefined")) {
        // try to find the API in the current window�s opener
        theAPI = findAPI(window.opener);
    }
    // if the API has not been found
    if (theAPI == null) {
        // Alert the user that the API Adapter could not be found
        alert("Unable to connect to the SCORM API.");
    }
    return theAPI;
}


//Constants
var SCORM_TRUE = "true";
var SCORM_FALSE = "false";
var SCORM_NO_ERROR = "0";

//Since the Unload handler will be called twice, from both the onunload
//and onbeforeunload events, ensure that we only call LMSFinish once.
var finishCalled = false;
//Track whether or not we successfully initialized.
var initialized = false;

var API = null;

function ScormProcessInitialize(){
    var result;
    
    API = (Author.scormType == 0) ? getAPI() : GetAPI(window);
    
    if (API == null) {
        alert("ERROR - Could not establish a connection with the LMS.\n\nYour results may not be recorded.");
        return false;
    }
    
    result = (Author.scormType == 0) ? API.LMSInitialize("") : API.Initialize("");
    
    if (result == SCORM_FALSE) {
        var errorNumber = (Author.scormType == 0) ? API.LMSGetLastError() : API.GetLastError();
        var errorString = (Author.scormType == 0) ? API.LMSGetErrorString(errorNumber) : API.GetErrorString(errorNumber);
        var diagnostic = (Author.scormType == 0) ? API.LMSGetDiagnostic(errorNumber) : API.GetDiagnostic(errorNumber);
        
        var errorDescription = "Number: " + errorNumber + "\nDescription: " + errorString + "\nDiagnostic: " + diagnostic;
        
        alert("Error - Could not initialize communication with the LMS.\n\nYour results may not be recorded.\n\n" + errorDescription);
        return false;
    }
    
    initialized = true;
    return true;
}

function ScormProcessFinish(){

    var result;
    
    //Don't terminate if we haven't initialized or if we've already terminated
    if (initialized == false || finishCalled == true) {
        return;
    }
    
    result = (Author.scormType == 0) ? API.LMSFinish("") : API.Terminate("");
    
    finishCalled = true;
    
    if (result == SCORM_FALSE) {
        var errorNumber = (Author.scormType == 0) ? API.LMSGetLastError() : API.GetLastError();
        var errorString = (Author.scormType == 0) ? API.LMSGetErrorString(errorNumber) : API.GetErrorString(errorNumber);
        var diagnostic = (Author.scormType == 0) ? API.LMSGetDiagnostic(errorNumber) : API.GetDiagnostic(errorNumber);
        
        var errorDescription = "Number: " + errorNumber + "\nDescription: " + errorString + "\nDiagnostic: " + diagnostic;
        
        alert("Error - Could not terminate communication with the LMS.\n\nYour results may not be recorded.\n\n" + errorDescription);
        return;
    }
}

function ScormProcessGetValue(element){

    var result;
    
    if (initialized == false || finishCalled == true) {
        return;
    }
    
    result = (Author.scormType == 0) ? API.LMSGetValue(element) : API.GetValue(element);
    
    if (result == "") {
    
        var errorNumber = (Author.scormType == 0) ? API.LMSGetLastError() : API.GetLastError();
        
        if (errorNumber != SCORM_NO_ERROR) {
            var errorString = (Author.scormType == 0) ? API.LMSGetErrorString(errorNumber) : API.GetErrorString(errorNumber);
            var diagnostic = (Author.scormType == 0) ? API.LMSGetDiagnostic(errorNumber) : API.GetDiagnostic(errorNumber);
            
            
            var errorDescription = "Number: " + errorNumber + "\nDescription: " + errorString + "\nDiagnostic: " + diagnostic;
            
            alert("Error - Could not retrieve a value from the LMS.\n\n" + errorDescription);
            return "";
        }
    }
    
    return result;
}

function ScormProcessSetValue(element, value){

    var result;
    
    if (initialized == false || finishCalled == true) {
        return;
    }
    
    result = (Author.scormType == 0) ? API.LMSSetValue(element, value) : API.SetValue(element, value);
    
    if (result == SCORM_FALSE) {
        var errorNumber = (Author.scormType == 0) ? API.LMSGetLastError() : API.GetLastError();
        var errorString = (Author.scormType == 0) ? API.LMSGetErrorString(errorNumber) : API.GetErrorString(errorNumber);
        var diagnostic = (Author.scormType == 0) ? API.LMSGetDiagnostic(errorNumber) : API.GetDiagnostic(errorNumber);
        
        
        var errorDescription = "Number: " + errorNumber + "\nDescription: " + errorString + "\nDiagnostic: " + diagnostic;
        
        alert("Error - Could not store a value in the LMS.\n\nYour results may not be recorded.\n\n" + errorDescription);
        return;
    }
    
}

