// Unique id and definition for FlashProxy object
var lcId = new Date().getTime();
var proxyCache = new Array();
var proxyInterval = null;
var currentCall = null;
var flashProxy = null;


// Creates flashProxy object if useFlashProxy is true
function initProxy() {
  if (useFlashProxy && flashProxy == null)
    flashProxy = new FlashProxy(lcId,'JavaScriptFlashGateway.swf');
}


/*
 * Initialize (discover) the SCORM API object
 *
 * This object will be nested somewhere within
 * the frameset that a course is launched in
 */
function initAPI() {
  var my_API = null;

  var numTries = 0;
  var numTriesMax = 10;

  while (numTries < numTriesMax && my_API == null) {
    my_API = findAPI(window);

    if (my_API == null && typeof(window.parent) != 'undefined')
      my_API = findAPI(window.parent);

    if (my_API == null && typeof(window.top) != 'undefined')
      my_API = findAPI(window.top);

    if (my_API == null && typeof(window.opener) != 'undefined') {
      if (window.opener != null && !window.opener.closed)
        my_API = findAPI(window.opener);
    }

    numTries++;
  }

  if (my_API == null) {
    window.status = 'Not connected';
  }  
  else {
    window.status = 'Connected';
  
    // Reference newly found API
    scorm_API = my_API;
  }
}


/*
 * Inspects this window and its frames for the SCORM API
 *
 * This function returns null if no API is found
 */
function findAPI(win) {
  // Check current window for API
  if (typeof(win) != 'undefined' ? typeof(win.API) != 'undefined' : false) {
    if (win.API != null)
      return win.API;
  }
  var numFrames = win.frames.length;

  // If no frames exist, we assume the course was not launched from an LMS
  if(numFrames == 0) {
    lmsStatus = false;
  }

  // Look in window's frameset kin (except opener)
  if (numFrames > 0) {
    for (var i = 0 ; i < numFrames; i++) {
      if (typeof(win.frames[i]) != 'undefined' ? typeof(win.frames[i].API) != 'undefined' : false) {
        if (win.frames[i].API != null)
          return win.frames[i].API;
      }
    }
  }

  return null;
}


function callAPI(command, args) {
  //alert('callAPI command,args: '+command+','+args);
  var err = 1;
  var sep, arg1, arg2, value;
  var flashObj = IE ? loader : document.loader;

  //
  // LMSInitialize
  //
  if (command == "LMSInitialize") {
    err = scorm_API.LMSInitialize("");
    if (err == "true") {
      if (useFlashProxy && flashProxy != null)
        flashProxy.call(args,"true");
      else
        flashObj.SetVariable(args,"true");
    }
  }

  //
  // LMSSetValue
  //
  else if (command == "LMSSetValue") {
    sep = args.indexOf(",");
    arg1 = args.substr(0,sep);
    arg2 = args.substr(sep+1);

    err = scorm_API.LMSSetValue(arg1,arg2);
  }

  //
  // LMSGetValue
  //
  else if (command == "LMSGetValue") {
    sep = args.indexOf(",");
    arg1 = args.substr(0,sep);
    arg2 = args.substr(sep+1);
    value = eval('scorm_API.'+command+'(\"'+arg1+'\")');

    if (useFlashProxy && flashProxy != null) {
      //flashProxy.call(arg2,value);

      //for now, cache these calls and send them out
      //one at a time until they are all sent...
      var proxyCall = new Object();
      proxyCall.func = arg2;
      proxyCall.value = value;
      proxyCall.TxRx = false;

      proxyCache.push(proxyCall);
      if (proxyInterval == null)
        proxyInterval = setInterval("sendProxyCall()",100);
    }
    else {
      flashObj.SetVariable(arg2,value);
    }
  }

  //
  // LMSFinish
  //
  else if (command == "LMSFinish") {
    err = scorm_API.LMSFinish(args);
  }

  //
  // LMSCommit
  //
  else if (command == "LMSCommit") {
    err = scorm_API.LMSCommit(args);
  }

  //
  // LMSFlush
  //
  else if ( command == "LMSFlush" ) {
    err = scorm_API.LMSFlush(args);
  }

  //
  // LMSGetLastError
  //
  else if (command = "LMSGetLastError") {
    sep = args.indexOf(",");
    arg1 = args.substr(0,sep);
    arg2 = args.substr(sep+1);
    value = scorm_API.LMSGetLastError();

    // pass error info back to the player
    if (useFlashProxy && flashProxy != null)
      flashProxy.call(arg2,value);
    else
      flashObj.SetVariable(arg2,value);
  }

  else {
    //for LMSGetErrorString, LMSGetDiagnostic
    sep = args.indexOf(",");
    arg1 = args.substr(0, sep);
    arg2 = args.substr(sep+1);
    value = eval('scorm_API.'+command+'(\"'+arg1+'\")');

    if (sep != 0 && arg2 != "") {
      if (useFlashProxy && flashProxy != null)
        flashProxy.call(arg2,value);
      else
        flashObj.SetVariable(arg2,value);
    }
    else {
      err = "-2: No Flash variable specified";
    }
  }

  //handle LMS error returns
  if ((err == 0 || err == "false") && displayErrors)  {
    if (!confirm('LMS API adapter returned error code: '+err+'\n When calling '+command+' with '+args+'\n\nSelect cancel to disable future warnings.'))
      displayErrors = false;
  }
}


function sendProxyCall() {
  //log('sendProxyCall() proxyCache.length: '+proxyCache.length);
  if (proxyCache.length > 0 && (currentCall == null || currentCall.TxRx)) {
    currentCall = proxyCache.pop();
    flashProxy.call(currentCall.func,currentCall.value);

    //for debug purposes
    //log('flashProxy.call("'+currentCall.func+'","'+currentCall.value+'")');
  }

  //clear interval if none left to send
  if (proxyCache.length == 0)
    clearInterval(proxyInterval);
}


//called indirectly by ActionScript to acknowledge a proxy call was received
function proxyCallReceived(func) {
  if (currentCall != null && currentCall.func == func) {
    currentCall.TxRx = true;

    //for debug purposes
    //log('received notification that ['+func+'] was called...');
  }
}


function updateLMS() {
  //prevent from being fired if no API exists
  if (scorm_API != null) {
    scorm_API.LMSSetValue("cmi.core.lesson_status",lessonStatus);
    //log('updateLMS() lessonStatus: '+lessonStatus);
    scorm_API.LMSSetValue("cmi.suspend_data",suspendData);
    //log('updateLMS() suspendData: '+suspendData);
    scorm_API.LMSSetValue("cmi.core.lesson_location",lessonLocation);
    //log('updateLMS() lessonLocation: '+lessonLocation);
    scorm_API.LMSSetValue("cmi.core.session_time",lessonTime);
    //log('updateLMS() lessonTime: '+lessonTime);

    scorm_API.LMSCommit("");
  }
}


function updateObjectives() {
  //create the objective placeholders
  if (scorm_API != null && objectivesString != "") {
    objectivesData = objectivesString.split(",");  
    dataLength = objectivesData.length / 6;
    for (i = 0; i < dataLength; i++) {
      var objectiveNum = objectivesData.shift();

      scorm_API.LMSSetValue("cmi.objectives."+objectiveNum+".id",objectivesData.shift());  
      scorm_API.LMSSetValue("cmi.objectives."+objectiveNum+".score.raw",objectivesData.shift());  
      scorm_API.LMSSetValue("cmi.objectives."+objectiveNum+".score.max",objectivesData.shift());  
      scorm_API.LMSSetValue("cmi.objectives."+objectiveNum+".score.min",objectivesData.shift());  
      scorm_API.LMSSetValue("cmi.objectives."+objectiveNum+".status",objectivesData.shift());  
    }
  }
}


function closeDown() {
  //when a course is closed, this is called by onunload event  
  if (scorm_API != null) {
    updateLMS();

    scorm_API.LMSFinish("");
  }
}


//Handle FSCommand messages from Flash
function loader_DoFSCommand(command, args) {
  useFlashProxy = false;

  doCommand(command, args);
}


// Handle JavaScriptProxy messages from Flash
function doJSProxyCommand(command, args) {
  useFlashProxy = true;

  if (flashProxy == null)
    initProxy();

  doCommand(command, args);
}


function doCommand(command, args) {
  // Direct LMS specific calls to callAPI()
  if (scorm_API != null && command.substring(0,3) == "LMS")
    callAPI(command,new String(args));

  if (command == "AcknowledgeCall") {
    proxyCallReceived(args);
  }
  else if (command == "StoreLocation") {
    lessonLocation = args;
  }
  else if (command == "StoreStatus") {
    lessonStatus = args;
  }
  else if (command == "StoreTime") {
    lessonTime = args;
  }
  else if (command == "StoreSuspendData") {
    suspendData = args;
  }
  else if (command == "StoreObjectives") {
    objectivesString = args;
  }
  else if (command == "UpdateObjectives") {
    updateObjectives();
  }
  else if (command == "UpdateValues") {
    updateLMS();
  }
  // not calls to the lms, these are functions that are related to the print and email quiz results
  if (command == "storeIDInfo"){
	IDinfo = args;
  }
  if (command == "storeString"){
	stringArray = args;
	getWindow(false);
  }
  if (command == "mailAddress"){
	mailAddress = args;
  }
  if (command == "mailResults"){
	stringArray = args;
	getWindow(true);
  }
  if (command == "storeNumbers"){
	originalNumbers = args;
	originalNumbersArray = originalNumbers.split("&")
  }
  
}


function log(message) {
  var elem = document.getElementById('javascriptmessage');
  if (elem)
    elem.innerHTML = elem.innerHTML+'<br>'+message;
}

