//utility functions
function getObjByName(name,doc) {
var o = 0;

if(!doc) doc = document;
if(doc[name]) o=doc[name];
if(!document.all)
{

return doc.getElementById(name);
}
if(document.all && doc.all[name]) 
{o=doc.all[name];}
  if(o){
  if(!o.getElementsByTagName) o.getElementsByTagName = getElementsArray;
  return o;
  }
if(document.layers) {
  for(var i=0;i < doc.layers.length;i++){
  var lyrdoc = doc.layers[i].document;

  if(lyrdoc[name]) return lyrdoc[name];
    if(lyrdoc.layers.length > 0) {
    var o = getObjByName(name,lyrdoc);
    if(o) return o;
    }
  }
}
return 0;
}
if(!document.getElementById) document.getElementById = getObjByName;

function MM_openBrWindow(theURL,winName,features) {viewer = window.open(theURL,winName,features);viewer.focus();}


function PageQuery(q) {
    if(q.length > 1) this.q = q.substring(1, q.length);
    else this.q = null;
    this.keyValuePairs = new Array();
    if(q) {
        for(var i=0; i < this.q.split("&").length; i++) {
            this.keyValuePairs[i] = this.q.split("&")[i];
        }
    }
    this.getKeyValuePairs = function() { return this.keyValuePairs; }
    this.getValue = function(s) {
        for(var j=0; j < this.keyValuePairs.length; j++) {
            if(this.keyValuePairs[j].split("=")[0] == s)
                return this.keyValuePairs[j].split("=")[1];
        }
        return false;
    }
    this.getParameters = function() {
        var a = new Array(this.getLength());
        for(var j=0; j < this.keyValuePairs.length; j++) {
            a[j] = this.keyValuePairs[j].split("=")[0];
        }
        return a;
    }
    this.getLength = function() { return this.keyValuePairs.length; }   
}
function queryString(key){
var page = new PageQuery(window.location.search); 
return unescape(page.getValue(key)); 
}

//global variables
var gblCourse;
var gblModules = new Array();
var gblScreens = new Array();
var gblGlossary = new Array();
//var gblNumScreens = 0;
//var gblCurrentScreenIndex = 0;
var gblCurrentScreen;
var gblNextScreen;
var gblPreviousScreen;
var gblBackScreens = new Array();
var gblPreviousButtonNavigatesHistory = false;
var gblEvaluation = false;

var gblScreenFrameWidth = 0;
var gblScreenFrameHeight = 0;

var gblScreenPathRelative = '../../';

var gblCourseMapStyle = 'tree';


var gblThemeDir = '';

var gblDefaultDir = '';

var gblReturnToQuizButton;
var gblNextButton;
var gblPreviousButton;
var gblExitButton;
var gblCourseMapButton;
var gblGlossaryButton;
var gblSearchButton;
var gblReplayButton;
var gblMainMenuButton;
var gblMuteButton;
var gblFAQButton;

var gblMainMenuBackButton;

var gblBreadCrumbLabel;
var gblCourseLabel;
var gblModuleLabel;
var gblTopicLabel;
var gblScreenLabel;
var gblCurrentPageLabel;
var gblNumPagesLabel;
var UDUTU_API = window;

var gblScreenFrame;
var gblNavFrame;
var gblNavDocument;

var gblCourseMapURL;
var gblCourseGlossaryURL;
var gblCourseNavigationURL;
var gblCourseSearchURL;
var gblMainMenuURL;
var gblCourseFAQURL;

var gblStartOnMainMenu = false;

var gblSoundOn = true;
var gblFailedQuiz = null;

var gblDefaultLearningStyle = 'tellme';

//caching functions
var gblCurrentlyCachingScreen;
var gblCurrMediaIdx = 0;
var gblMediaArray =new Array();

var gblMaxPreCache = 100;

var cacheloops = 0;

function cacheNext(){
  
  //loop to the start of the array if we have read to the end
 if (gblCurrMediaIdx == gblMediaArray.length) {gblCurrMediaIdx = 0;cacheloops++}
  //call cacheflash with the next file to cache
  if (gblMediaArray.length > 0 && cacheloops <= 1) {
      try{
	
        var m = getObjByName("cacheflash",document);
        m.SetVariable("strMediaURL", '../media/content/' + gblMediaArray[gblCurrMediaIdx]);
	var currCacheIndex = getCurrScreen().cacheIndex;
	if (gblCurrMediaIdx < (currCacheIndex + gblMaxPreCache))
		gblCurrMediaIdx ++;
      }
      catch(ex){}
  }
}

function startCache(){
try{
var m = getObjByName("cacheflash",document);
m.SetVariable("strMediaURL", '../media/content/' + gblMediaArray[gblCurrMediaIdx]);
      }
      catch(ex){}
}

function cacheflash_DoFSCommand(command, args) {
  window.setTimeout('cacheNext();',1000);
}

var isInternetExplorer = navigator.appName.indexOf("Microsoft") != -1;
if (navigator.appName && navigator.appName.indexOf("Microsoft") != -1 && navigator.userAgent.indexOf("Windows") != -1 && navigator.userAgent.indexOf("Windows 3.1") == -1) {
	document.write('<script language=\"VBScript\"\>\n');
	document.write('On Error Resume Next\n');
	document.write('Sub cacheflash_FSCommand(ByVal command, ByVal args)\n');
	document.write('	Call cacheflash_DoFSCommand(command, args)\n');
	document.write('End Sub\n');
	document.write('</script\>\n');
}

window.setTimeout('startCache()', 45000);

//course functions - builds out the course to mirror the authoring structure
function initCourse(id,name,completed, baseModule)
{
    this.type = 'course';
    this.id = id;
    this.name = name;
    this.completed = completed;
    this.baseModule = baseModule;
}   

function initModule(id,name,parentModule,completed,moduleType,isRandom,randomNumToShow)
{
    this.type = 'module';
    this.moduleType = moduleType;
    this.isRandom = isRandom;
    this.randomNumToShow = randomNumToShow;
    this.id = id;
    this.name = name;
    
    //used only to determine what the last visited screen in a scenario is
    this.lastVisitedScenarioScreen = null;
    
    if (parentModule != null)
    {
     parentModule.moduleObjects[parentModule.moduleObjects.length] = this;
     parentModule.modules[parentModule.modules.length] = this;
    }
    this.parentModule = parentModule;
    this.completed = completed;
    this.moduleObjects = new Array();
    this.modules = new Array();
    this.screens = new Array();
    gblModules[gblModules.length] = this;

}
function initScreen(id,name,parentModule,htmlFile,visited,autoLaunchCourseMap,maxscore,lockNavigation,streamNarration,passingScore,isScored, completesParent)
{
    this.type = 'screen';
    this.id = id;
    this.name = name;
    
    
    parentModule.moduleObjects[parentModule.moduleObjects.length] = this;
    parentModule.screens[parentModule.screens.length] = this;
    this.parentModule = parentModule;
    
    this.htmlFile = htmlFile;
    this.visited = visited;
    this.completesParent = completesParent;

    this.score = -1;
    this.maxscore = maxscore;
    this.completed = false;
    
    this.isCompleted = isScreenCompleted;
    this.lockNavigation = lockNavigation;
    this.cacheIndex = gblMediaArray.length;
    this.streamNarration = streamNarration;
    this.passingScore = passingScore;
    this.isScored = isScored;
    this.jumpTos = new Array();
    this.cacheContent = new Array();
    this.nextScreen = null;
    this.previousScreen = null;
    
    gblScreens[gblScreens.length] = this;
    //the page number will be determined by whether or not it
    //is in a scenario - all screens in a scenario have the 
    //same page #
    //therefore, this will have to be built out once the whole tree is built
    this.pageNumber = 0;
}

function initGlossaryItem(id,abbreviation,definition,phrase)
{
    var gi = new glossaryItem(id,abbreviation,definition,phrase);
}

function glossaryItem(id,abbreviation,definition,phrase)
{
    this.id = id;
    this.abbreviation = abbreviation;
    this.definition = definition;
    this.phrase = phrase;
    gblGlossary[gblGlossary.length] = this;
}

function initJumpTo(fromScreen, toScreen, condition)
{
    this.fromScreen = fromScreen;
    this.fromScreen.jumpTos[this.fromScreen.jumpTos.length] = this;
    this.toScreen = toScreen;
    this.condition = condition;
}

function testfire()
{
    alert('blah');
}

function attachContent(fileURL,toScreen)
{
    toScreen.cacheContent = fileURL;
}

//course functions - builds out the course as it will be navigated
//first clean out screens in modules that won't appear because the module
//isRandom and the module is only going to show a set number of screens


//figure out how many pages there will be, based on those modules that are scenarios
//note that when paginating, if a module is a scenario, all screens in that scenario
//will have the same page 'number's
//also, when displaying the course map, scenarios will only appear as a single page -
//the start page. Additionally - submodules in a scenario will not appear in the course map.


function isScreenCompleted()
{
 // this.completed = ((this.visited && !this.isScored) || (this.visited && this.score > -1 && this.isScored));
 // if (this.completed)
   // this.parentModule.completed = true;
  return (((this.visited && !this.isScored) || (this.visited && this.score > -1 && this.isScored)) || this.completed);
}
function getCurrScreen()
{
    //return gblScreens[gblCurrentScreenIndex];
    return gblCurrentScreen;
}
function setCurrScreen(value)
{
  gblCurrentScreen = value;
}
function getScreenByScreenID(intScreenID)
{
//    for (var i=0;i<gblNumScreens;i++)
//    {

//      if (gblScreens[i].id == intScreenID)
//      { 
//        return gblScreens[i];
//        break;
//      }
//    }
    return null;
}
function getModuleByScreenID(intScreenID)
{
    //return getScreenByScreenID(intScreenID).topic.module;
    return null;
}

function getModuleByModuleID(intModuleID)
{
    for (var i=0;i<gblModules.length;i++)
    {
      if (gblModules[i].id == intModuleID)
      { 
        return gblModules[i];
        break;
      }
    }
    return null;
}

//button functions
function initButton(imgUp, imgOver, imgDisabled, imgID, funcOnClick, strAlt, strDisabledAlt)
{

    this.btnEnabled = btnEnabled;
    this.imgID = imgID;
    this.image = getObjByName(imgID,gblNavDocument);
    this.funcOnClick = funcOnClick;
    
    //the following block will fail if the image button isn't actually on the nav template
    try{
    this.image.imgUp = imgUp;
    this.image.imgOver = imgOver;
    this.image.imgDisabled = imgDisabled;
    this.image.onmouseover = btnMouseOver;
    this.image.onmouseout = btnMouseOut;
    this.image.onclick = funcOnClick;
    this.image.alt = strAlt;
    this.image.strDisabledAlt = strDisabledAlt;
    this.image.strAlt = strAlt;
    this.image.style.cursor = "pointer";
    this.btnEnabled(true);
    }
    catch(ex)
    {}
}
function printScreen()
{
  if (document.frames[0].frames[0].frames[0]) {
    document.frames[0].frames[0].frames[0].focus();
  }
  else {
    document.frames[0].frames[0].focus();
  }
  window.print();
}
function btnEnabled(val)
{
    try{
        this.image.enabled = val;
        
        if (val)
        {this.image.onclick=this.funcOnClick;this.image.alt=this.image.strAlt;this.image.src = this.image.imgUp;this.image.style.cursor="pointer";}
        else
        {this.image.onclick=null;this.image.alt=this.image.strDisabledAlt;this.image.src = this.image.imgDisabled;this.image.style.cursor="text";}
    }
    catch(e)
    {}
}

function btnMouseOver()
{
    if (this.enabled)
        this.src = this.imgOver;
    else
        this.src = this.imgDisabled;
}

function btnMouseOut()
{
    if (this.enabled)
        this.src = this.imgUp;
    else
        this.src = this.imgDisabled;
}
//label functions

function initLabel(lblID)
{
    this.lblID = lblID;
    this.label = getObjByName(lblID,gblNavDocument);
    this.setText = setText;
}

function setText(strText)
{
    try{
        this.label.innerHTML = strText;
    }
    catch(e){}
}

//page functions

function initStartPage()
{
//  var qryScreenID = queryString('ScreenID');
//    if (qryScreenID)
//    {
//        var blnMatchFound = false;
//        for (var i=0;i<gblNumScreens;i++)
//        {
//          if (gblScreens[i].id == qryScreenID)
//          { 
//            blnMatchFound = true;
//            gblCurrentScreenIndex = i;
//            return i;
//          }
//        }
//        if (!blnMatchFound)
//            return 0;
//    }
//    else
//        gblCurrentScreenIndex = 0;
}


//todo
function initLabels()
{
    
    var currScreen;

    currScreen = getCurrScreen();
    gblCurrentPageLabel.setText(currScreen.pageNumber);
    gblNumPagesLabel.setText(gblScreens[gblScreens.length - 1].pageNumber);

    gblCourseLabel.setText(gblCourse.name);
    //gblModuleLabel.setText(currScreen.topic.module.name);
    //gblTopicLabel.setText(currScreen.topic.name);
    gblScreenLabel.setText(currScreen.name);

    if (gblBreadCrumbLabel != null)
    {
	var parent = currScreen.parentModule;
	var strBreadCrumb = parent.name;
	parent = parent.parentModule;
	while (parent != null)
	{
	  strBreadCrumb = parent.name + ' - ' + strBreadCrumb;
	  parent = parent.parentModule;
	}
	gblBreadCrumbLabel.setText(strBreadCrumb);
    }
}

//todo
function initButtons()
{
        if (gblNextScreen != null)
            gblNextButton.btnEnabled(true);
        else
            gblNextButton.btnEnabled(false);

        if (gblPreviousScreen != null || (gblPreviousButtonNavigatesHistory && gblBackScreens.length > 0))
            gblPreviousButton.btnEnabled(true);
        else
            gblPreviousButton.btnEnabled(false);
            
        // when return to quiz is visible disable CM, Search and Main Menu  
        //var bReturnToQuizHidden = !isQuizButtonVisible();
        
//        gblExitButton.btnEnabled(true);
//        gblCourseMapButton.btnEnabled(bReturnToQuizHidden);
//        gblGlossaryButton.btnEnabled(true);
//        gblSearchButton.btnEnabled(bReturnToQuizHidden);
//        gblReplayButton.btnEnabled(true);
//        gblMainMenuButton.btnEnabled(bReturnToQuizHidden);
        
        gblExitButton.btnEnabled(true);
        gblCourseMapButton.btnEnabled(true);
        gblGlossaryButton.btnEnabled(true);
        gblSearchButton.btnEnabled(true);
        gblReplayButton.btnEnabled(true);
        gblMainMenuButton.btnEnabled(true);
        
        if (getCurrScreen().parentModule.moduleType == "Scenario")
          disableNav();
}

//function initVisitedPages()
//{

//}

function initScreenFrame()
{
    setCurrScreenVisited(); 
    if (getCurrScreen().lockNavigation)
    { 
        disableNav();
        gblNextButton.image.alt = "You must finish the interaction to continue";
        gblPreviousButton.image.alt = "You must finish the interaction to continue";
    }

    //reset the width and height of the screen frame, since it may have been changed
    setScreenFrameParams(gblScreenFrameWidth,gblScreenFrameHeight);
    //gblScreenFrame = getObjByName('frameScreen',document);
    gblScreenFrame.src = gblScreenPathRelative + getCurrScreen().htmlFile;
    
    
    //var cacheIndex = gblScreens[gblCurrentScreenIndex].cacheIndex;
    //cacheIndex++;
    //gblCurrMediaIdx = (cacheIndex<=gblMediaArray.length) ? cacheIndex: cacheIndex-1; 
}

//this function may be called to make the screen frame larger to accomodate large videos/swfs
function setScreenFrameParams(width, height)
{
    //only resize the screen frame to larger than its original parameters
    if (width > gblScreenFrameWidth)
        gblScreenFrame.width = width;
    if (height > gblScreenFrameHeight)
        gblScreenFrame.height = height;
}

//used in next function only
gblVarsInitialized = false;

function initializeStudentView()
{

    try{
    if (gblMuteButton && gblMuteButton.image){
        if (gblSoundOn)
        {
            gblMuteButton.image.alt = 'Turn Sound Off';
        }
        else
        {
            gblMuteButton.image.alt = 'Turn Sound On';
        }
    }
    }
    catch(ex){alert(ex.message);}
    
    //only set the start page and initialize variables if
    //it hasn't been done yet
    if (gblVarsInitialized == false)
    {
      gblVarsInitialized = true;
      //gblNumScreens = gblScreens.length;
     //if (false)//(getIsSCORM())
     //   initSCORM();
      //else
        initStartPage();
    }
    
    //if we're on a preassessment and we aren't supposed
    //to show preassessments, move forward until we aren't on a preassessment
    currScreen = getCurrScreen();
    //while (gblCurrentScreenIndex < gblScreens.length)
    //{
     //   gblCurrentScreenIndex++;
    //    currScreen = getCurrScreen();
    //}
    
    initLabels();
    initButtons();
    //initVisitedPages();
    
    initScreenFrame();
    //you never want to start on the main menu if
    //the gblcurrentscreenindex > 0 (as a request will have been
    //made in the query string to start on a specific screen,
    //otherwise gblcurrentscreenindex would be 0)
    

      //if (top.gblCurrentScreenIndex > 0)
      //{
      //  gblStartOnMainMenu = false;
      //}
      if (gblStartOnMainMenu == true)
      {
        var qryLockModuleID = queryString('LockModuleID');
        if (qryLockModuleID != null)//never show the mainmenu if we aren't showing all modules
        {
          gblStartOnMainMenu = false;
          goMainMenu();
          //the first screen will be flagged as visited, but it won't really be,
          //so un-flag it
          gblCurrentScreen.visited = false;
        }
      }
}

function getFirstScreenInModule(mod)
{
  if (mod.moduleType == 'Scenario' && mod.lastVisitedScenarioScreenInModule != null)
    return mod.lastVisitedScenarioScreenInModule;
  var firstScreen = null;
  for (var i = 0;i<mod.moduleObjects.length; i++)
  {
    if (mod.moduleObjects[i].type == "module")
    {
      firstScreen = getFirstScreenInModule(mod.moduleObjects[i]);
      if (firstScreen != null)
      { return firstScreen; }
    }
    else if (mod.moduleObjects[i].type == "screen")
    { return mod.moduleObjects[i];}
  }
  return null;
}

function getFirstScreenAfterModule(afterMod)
{
  if (afterMod.parentModule == null)
  {return null;}
  var firstScreen = null;
  var currModulePos = 10000;
  for (var i = 0; i<afterMod.parentModule.moduleObjects.length; i++)
  {
    if (afterMod == afterMod.parentModule.moduleObjects[i])
    {
      currModulePos = i;
    }
    if (currModulePos < i)
    {
      if (afterMod.parentModule.moduleObjects[i].type == "module")
      {
        firstScreen = getFirstScreenInModule(afterMod.parentModule.moduleObjects[i]);
        if (firstScreen != null)
            return firstScreen;
      }
      else if (afterMod.parentModule.moduleObjects[i].type == "screen")
      {firstScreen = afterMod.parentModule.moduleObjects[i];return firstScreen;}
    }
  }
  firstScreen = getFirstScreenAfterModule(afterMod.parentModule);
  
  return firstScreen;
  
}

function getNextScreen()
{
    var currModule = getCurrScreen().parentModule;
    var currScreen = getCurrScreen();
    var currScreenPos = 10000;
    var nextScreen = null;
    //first, walk the current module and see if there are any screens after this one
    for (var i = 0;i<currModule.moduleObjects.length; i++)
    {
      if (currModule.moduleObjects[i] == currScreen)
      {
        currScreenPos = i;
      }
      if (currScreenPos < i)
      {
        if (currModule.moduleObjects[i].type == "module")
        {
          nextScreen = getFirstScreenInModule(currModule.moduleObjects[i]);
        }
        else if (currModule.moduleObjects[i].type == "screen")
        { nextScreen = currModule.moduleObjects[i];}
      }
      if (nextScreen != null) return nextScreen;
    }
    
    //if the current module is the root, there isn't a next screen
    //but if not, and there are no more screens in this module, go up 
    if (currModule.parentModule != null && nextScreen == null)
    {
      nextScreen = getFirstScreenAfterModule(currModule);
    }
    return nextScreen;
}

var gblBreak;
//note that navigation will not follow an index
//we want to navigate along the course structure, as we now have 
//scenarios and jump tos to worry about
function goNextPage()
{
    
    gblPreviousScreen = getCurrScreen();
    gblBackScreens[gblBackScreens.length] = getCurrScreen();
    setCurrScreen(gblNextScreen);
    gblNextScreen = getNextScreen();
    
    initLabels();
    initButtons();
    initScreenFrame();
    
}

function getLastScreenBeforeModule(beforeMod)
{
  if (beforeMod.parentModule == null)
  {return null;}
  var lastScreen = null;
  var currModulePos = 0;
  //for (var i = 0; i<afterMod.parentModule.moduleObjects.length; i++)
  for (var i = beforeMod.parentModule.moduleObjects.length; i>=0; i--)
  {
    if (beforeMod == beforeMod.parentModule.moduleObjects[i])
    {
      currModulePos = i;
    }
    if (currModulePos > i)
    {
      if (beforeMod.parentModule.moduleObjects[i].type == "module")
      {
        lastScreen = getLastScreenInModule(beforeMod.parentModule.moduleObjects[i]);
        if (lastScreen != null)
            return lastScreen;
      }
      else if (beforeMod.parentModule.moduleObjects[i].type == "screen")
      {lastScreen = beforeMod.parentModule.moduleObjects[i];return lastScreen;}
    }
  }
  lastScreen = getLastScreenBeforeModule(beforeMod.parentModule);
  
  return lastScreen;
  
}

function getLastVisitedScenarioScreenInModule(mod)
{
    return getFirstScreenInModule(mod);
}

function getLastScreenInModule(mod)
{
  if (mod.moduleType == 'Scenario' && mod.lastVisitedScenarioScreenInModule != null)
    return mod.lastVisitedScenarioScreenInModule;
  var lastScreen = null;
  //for (var i = 0;i<mod.moduleObjects.length; i++)
  for (var i = mod.moduleObjects.length-1;i >= 0; i--)
  {
    if (mod.moduleObjects[i].type == "module")
    {
      lastScreen = getLastScreenInModule(mod.moduleObjects[i]);
      if (lastScreen != null)
      { return lastScreen; }
    }
    else if (mod.moduleObjects[i].type == "screen")
    { return mod.moduleObjects[i];}
  }
  return null;
}

function getPreviousScreen()
{
    var previousScreen = null;

    var currModule = getCurrScreen().parentModule;
    var currScreen = getCurrScreen();
    var currScreenPos = 0;
    
    //first, walk the current module and see if there are any screens before this one
    //for (var i = 0;i<currModule.moduleObjects.length; i++)
    for (var i = currModule.moduleObjects.length - 1;i>=0; i--)
    {
    //alert(currModule.moduleObjects[i].type + ' sdfs');
    
      if (currModule.moduleObjects[i] == currScreen)
      {
        currScreenPos = i;
      }
      if (currScreenPos > i)
      {
        if (currModule.moduleObjects[i].type == "module")
        {
          previousScreen = getLastScreenInModule(currModule.moduleObjects[i]);
        }
        else if (currModule.moduleObjects[i].type == "screen")
        { previousScreen = currModule.moduleObjects[i];}
      }
      if (previousScreen != null) return previousScreen;
    }
    
    //if the current module is the root, there isn't a previous screen
    //but if not, and there are no more screens in this module, go up 
    if (currModule.parentModule != null && previousScreen == null)
    {
      
      previousScreen = getLastScreenBeforeModule(currModule);
    }
    
    return previousScreen;
}

function goBackPage()
{

    if (gblBackScreens.length > 0)
    {
      setCurrScreen(gblBackScreens[gblBackScreens.length - 1]);
      gblBackScreens.length--;
      if (gblBackScreens.length > 0)
      {
	    gblPreviousScreen = gblBackScreens[gblBackScreens.length - 1];
      }
      else
      {
	    gblPreviousScreen = getPreviousScreen();
      }
    }

}

function goPreviousPage() 
{
    //set the current screen to the previous screen
    gblNextScreen = getCurrScreen();

    if (gblBackScreens.length > 0 && gblPreviousButtonNavigatesHistory)
    {
       goBackPage();
    }
    else
    {
      setCurrScreen(gblPreviousScreen);
      gblPreviousScreen = getPreviousScreen();
    }
    initLabels();
    initButtons();
    initScreenFrame();
}

function setCurrScreenPassed()
{
  var currScreen = getCurrScreen();
  if (currScreen.lockNavigation)
    enableNav();
  currScreen.score = currScreen.maxscore;
  setCurrScreenVisited();
  setInteractionStatus(currScreen.id,'correct',currScreen.name);

  //goNextIncompleteScreen();
}
function setCurrScreenFailed()
{
 
  var currScreen = getCurrScreen();
  if (currScreen.lockNavigation)
    enableNav();
  currScreen.score = 0;
  
  setCurrScreenVisited();
  setInteractionStatus(currScreen.id,'incorrect',currScreen.name);

  //goNextIncompleteScreen();
  
  //showQuizButton();
}

function setCurrScreenInteractionStatus(result,correct_response,learner_response,type)
{
  var currScreen = getCurrScreen();
  if (currScreen.lockNavigation)
    enableNav();
  if (result == 'correct')
    currScreen.score = currScreen.maxscore;
  else
    currScreen.score = 0;
  
  setCurrScreenVisited();
  setInteractionStatus(currScreen.id,result,currScreen.name,correct_response,learner_response,type)

  //goNextIncompleteScreen();
}

//Not used (we have no interactions with scores other than pass/fail)
/*function setCurrScreenScore(score)
{
  var currScreen = getCurrScreen();
  if (currScreen.lockNavigation)
    enableNav();
  currScreen.score = score;
  
  setCurrScreenVisited();
  if (score == currScreen.maxscore)
    goNextIncompleteScreen();
  else
    goNextPage();    
}*/

function evaluateModuleCompletion(forModule)
{
    if (forModule.completed == true)
      return true;
    var blnModuleCompleted = true;
    //walk the module if it's completed flag == false
    for (var i = 0;i<forModule.moduleObjects.length; i++)
    {
        //alert(forModule.moduleObjects[i].type);
        if (forModule.moduleObjects[i].type == "module")
        {
           blnModuleCompleted = (blnModuleCompleted && evaluateModuleCompletion(forModule.moduleObjects[i]));
        }
        else if (forModule.moduleObjects[i].type == "screen")
        { 
           var currScreen = forModule.moduleObjects[i];
           blnModuleCompleted = (blnModuleCompleted && currScreen.isCompleted());
        }
        if (!blnModuleCompleted)
        {
           forModule.completed = false;
           return false;
        }  
    }
    forModule.completed = blnModuleCompleted;
    return blnModuleCompleted;
}
function evaluateCourseCompletion()
{
    var rootModCompleted = evaluateModuleCompletion(gblCourse.baseModule);
    gblCourse.completed = rootModCompleted;
    return rootModCompleted;
}

function setCurrScreenVisited()
{
  var currScreen = getCurrScreen();
  currScreen.visited = true;
  //TODO: not sure about the way this whole 'completed' thing is implemented...
  currScreen.completed = currScreen.isCompleted();
  currModule = currScreen.parentModule;
  if (currScreen.completed && currScreen.completesParent)
  {
    //currModule.completed = true;
    setModuleCompleted(currModule)
  }
  while (currModule.moduleType == 'Scenario')
  {
    currModule.lastVisitedScenarioScreenInModule = currScreen;
    currModule = currModule.parentModule;
  }
}

//function goNextIncompleteScreen()
//{

//}


function setModuleCompleted(module)
{
    for (var i = 0;i<module.moduleObjects.length; i++)
    {
        module.moduleObjects[i].completed = true;
        if (module.moduleObjects[i].type == "module")
        {
           setModuleCompleted(module.moduleObjects[i]);
        }
        /*else if (module.moduleObjects[i].type == "screen")
        { 
           
        }*/
    }
}

function doReplay()
{
  initScreenFrame();
}

function openCourseMap()
{
    var themedir = gblThemeDir;  
  if(navigator.appName == "Microsoft Internet Explorer")
  {
    MM_openBrWindow(gblRelativePathToFiles + themedir + gblCourseMapURL,'CourseMap','scrollbars=yes,resizable=yes,width=720,height=500,left=60,top=100');
  }
  else
  {
    MM_openBrWindow(gblCourseMapURL,'CourseMap','scrollbars=yes,resizable=yes,width=720,height=500,left=60,top=100');
  }
}

function openGlossary()
{
    var themedir = gblThemeDir;
  if(navigator.appName == "Microsoft Internet Explorer")
  {
    MM_openBrWindow(gblRelativePathToFiles + themedir + gblCourseGlossaryURL,'Glossary','scrollbars=yes,resizable=no,width=720,height=500,left=60,top=100')
  }
  else
  {
    MM_openBrWindow(gblCourseGlossaryURL,'Glossary','scrollbars=yes,resizable=no,width=720,height=500,left=60,top=100')
  }
}

function openSearch()
{
MM_openBrWindow(gblCourseSearchURL,'CourseMap','scrollbars=yes,resizable=no,width=720,height=500,left=60,top=100')
}
function openFAQ()
{
MM_openBrWindow(gblCourseFAQURL,'FAQ','scrollbars=yes,resizable=no,width=500,height=500,left=60,top=100')
}

function goMainMenu()
{
  if (gblMainMenuURL == '' || gblMainMenuURL == null)
  {
    alert('A main menu has not been defined for this course.');
  }
  else
  
  {
    gblNavFrame.src = gblMainMenuURL;
  }
}
function goPreassessmentChoice() 
{
  gblNavFrame.src = gblPreassessmentChoiceURL;
}
function goPreassessment()
{
  gblOnPreassessment = true;
  gblNavFrame.src = gblCourseNavigationURL;
}
function goCourseNavigation()
{
  gblOnPreassessment = false;

  gblNavFrame.src = gblRelativePathToFiles + gblThemeDir + gblCourseNavigationURL;
}

function goScreenFromMainMenu(intScreenID)
{
    goCourseNavigation();

    var blnMatchFound = false;
    //must do this rather than goscreen because the screenframe won't be there
    for (var i=0;i<gblScreens.length;i++)
    {
        if (gblScreens[i].id == intScreenID)
        {
            blnMatchFound = true;
            gblBackScreens[gblBackScreens.length] = getCurrScreen();
            setCurrScreen(gblScreens[i]);
            gblPreviousScreen = getPreviousScreen();
            gblNextScreen = getNextScreen();
            break;
        }
    }
}

function goModuleFromMainMenu(intModuleID)
{
  goCourseNavigation();
  var mod = getModuleByModuleID(intModuleID);
  var scrn = getFirstScreenInModule(mod);
  if (scrn != null)
  {
    gblBackScreens[gblBackScreens.length] = getCurrScreen();
    setCurrScreen(scrn);
    gblPreviousScreen = getPreviousScreen();
  }
  else
  {
    gblBackScreens[gblBackScreens.length] = getCurrScreen();
    setCurrScreen(gblScreens[0]); 
  }
  gblNextScreen = getNextScreen();
}

function doExit()
{
    doExitSCORM();
    
    window.opener = null;
    window.close();
}
function doKrystalExit()
{
  window.location = "http://www.krystalkollege.com/MainPage.asp";
}

function goScreen(intScreenID)
{
    if (intScreenID)
    {
        var blnMatchFound = false;
        for (var i=0;i<gblScreens.length;i++)
        {

            if (gblScreens[i].id == intScreenID)
            {
                blnMatchFound = true;
                gblBackScreens[gblBackScreens.length] = getCurrScreen();
                setCurrScreen(gblScreens[i]);
                gblPreviousScreen = getPreviousScreen();
                gblNextScreen = getNextScreen();
                
                initLabels();
                initButtons();
                initScreenFrame();
                
                break;
            }
        }
    }
}


function enableNext(blnValue)
{

}

function enablePrevious(blnValue)
{

}

function enableNav()
{
    gblNextButton.btnEnabled(true);
    gblPreviousButton.btnEnabled(true);
    gblCourseMapButton.btnEnabled(true);
    gblSearchButton.btnEnabled(true);
    //gblReplayButton.btnEnabled(true);
    gblMainMenuButton.btnEnabled(true);
}

function disableNav()
{
    gblNextButton.btnEnabled(false);
    gblPreviousButton.btnEnabled(false);
    gblCourseMapButton.btnEnabled(false);
    gblSearchButton.btnEnabled(false);
    //gblReplayButton.btnEnabled(false);
    gblMainMenuButton.btnEnabled(false);
}
function toggleSound()
{
    gblSoundOn = !gblSoundOn;
    if (gblSoundOn)
    {
      gblMuteButton.image.alt = 'Turn Sound Off';
    }
    else
    {
      gblMuteButton.image.alt = 'Turn Sound On';
    }
}

// this function re-initializes our global course arrays 
// if we are passed a moudule id in the querystring
function onCourseLoaded()
{

    var qryLockModuleID = queryString('LockModuleID');

    if (qryLockModuleID > 0) {
        var oModule = getModuleByModuleID(qryLockModuleID);

        
        if (oModule){
          gblStartOnMainMenu=false;
	      gblScreens[gblScreens.length - 1].pageNumber = enumeratePages(oModule,1) - 1;
	      oModule.parentModule = null;
          gblCourse.baseModule = oModule;

	      var scrn = getFirstScreenInModule(oModule);

          setCurrScreen(scrn);
          gblPreviousScreen = getPreviousScreen();

          gblNextScreen = getNextScreen();
        }
   }
   else        
   {
    
     
    var qryScreenID = queryString("ScreenID");
    
    var currModule = gblCourse.baseModule;
    if (gblScreens.length > 0)
    {
        enumeratePages(currModule,1);
        
        
        
        if (qryScreenID > 0)
        {
            //goScreen(qryScreenID); //can't use goscreen (it tries to initialize labels, etc.) 
            for (var i=0;i<gblScreens.length;i++)
            {
                if (gblScreens[i].id == qryScreenID)
                {
                    setCurrScreen(gblScreens[i]);
                    gblPreviousScreen = getPreviousScreen();
                    gblNextScreen = getNextScreen();
                    break;
                }
            }
        }
        else
        {
            var qryModID = queryString("ModuleID");
            if (qryModID > 0)
            {
              var mod = getModuleByModuleID(qryModID);
              var scrn = getFirstScreenInModule(mod);
              if (scrn != null)
              {
                setCurrScreen(scrn);
                gblPreviousScreen = getPreviousScreen();
              }
              else
              {
                setCurrScreen(gblScreens[0]); 
              }
              gblNextScreen = getNextScreen();
            }
            else
            {
              //set up the starting screen
              gblCurrentScreen = gblScreens[0]; 
              gblNextScreen = getNextScreen();
            }
        } 
        gblSCORMAPI = getAPI();
        initSCORM();
    }
    else
    {
      alert('There are currently no screens in this course');
    }
   }
}

//note: we want all pages in a scenario to have the same page number
function enumeratePages(forModule,currPgNum)
{
    var currScreen;
    for (var i = 0;i<forModule.moduleObjects.length; i++)
    {
        //alert(forModule.moduleObjects[i].type);
        if (forModule.moduleObjects[i].type == "module")
        {
           currPgNum = enumeratePages(forModule.moduleObjects[i],currPgNum);
           //if this module is not a scenario, but we just enumerated the pages in the
           //child scenario, increment the page counter (as it won't have been incremented from within)
           if (forModule.moduleObjects[i].moduleType == "Scenario" && forModule.moduleType != "Scenario")
           {
             currPgNum++;
           }
        }
        else if (forModule.moduleObjects[i].type == "screen")
        { 
        //alert(currPgNum);
           currScreen = forModule.moduleObjects[i];
           currScreen.pageNumber = currPgNum;
           //only increment if not in a scenario
           if (forModule.moduleType != "Scenario")
             currPgNum++;
        }
        
    }
    return currPgNum;
}

function returnToQuiz()
{
  if (gblReturnToQuizButton) {
    hideQuizButton();
    goScreen(gblFailedQuiz.id);
  }
}

function hideQuizButton()
{
  if (gblReturnToQuizButton) {
    gblReturnToQuizButton.btnEnabled(false);
    gblReturnToQuizButton.image.style.visibility = 'hidden';
    gblCourseMapButton.btnEnabled(true);
    gblMainMenuButton.btnEnabled(true);
    gblSearchButton.btnEnabled(true);
  }
}

//function showQuizButton()
//{
//  if (gblReturnToQuizButton) {
//    gblReturnToQuizButton.btnEnabled(true);
//    gblReturnToQuizButton.image.style.visibility = 'visible';
//    gblCourseMapButton.btnEnabled(false);
//    gblMainMenuButton.btnEnabled(false);
//    gblSearchButton.btnEnabled(false);
//  }
//}
//function isQuizButtonVisible()
//{
//  if (gblReturnToQuizButton){
//    return (gblReturnToQuizButton.image.enabled);
//  }
//  else {
//    return (false);
//  }
//}





function playSound(strURL)
{
      try{
        var m = getObjByName("cacheflash",document);
        m.SetVariable("strPlaySoundURL", strURL);
        //alert('playing ' + strURL);
      }
      catch(ex){}
  
}
function stopSound()
{
      try{
        var m = getObjByName("cacheflash",document);
        m.SetVariable("strPlaySoundURL", "STOP");
      }
      catch(ex){}
}





//scorm/aicc api interface layer
var findAPITries = 0;
var gblSCORMVersion = null;
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.API_1484_11 == 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;
   }
   if (win.API_1484_11 != null)
   {
    gblSCORMVersion = "SCORM 2004";
    return win.API_1484_11;
   }
   if (win.API != null)
   {
    gblSCORMVersion = "SCORM 1.2";
    return win.API;
   }
   return null;
}

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 find an API adapter");
   }*/

   return theAPI;
}

var gblSCORMAPI;// = getAPI();

function getIsSCORM()
{
  return (gblSCORMAPI != null);
}

function LMSInitialize()
{
  //the parameter is unused - reserved by SCORM for future use
  if (gblSCORMAPI.LMSInitialize != null)
    return gblSCORMAPI.LMSInitialize("");
  else
    return gblSCORMAPI.Initialize("");
}

function LMSFinish()
{
  //the parameter is unused - reserved by SCORM for future use
  if (gblSCORMAPI.LMSFinish != null)
    return gblSCORMAPI.LMSFinish("");
  else
    return gblSCORMAPI.Terminate("");
}

function LMSGetValue(parameter)
{
  if (gblSCORMAPI.LMSGetValue != null)
    return gblSCORMAPI.LMSGetValue(parameter);
  else
    return gblSCORMAPI.GetValue(parameter);
}

function LMSSetValue(parameter, value)
{
  if (gblSCORMAPI.LMSSetValue != null)
    return gblSCORMAPI.LMSSetValue (parameter, value);
  else
    return gblSCORMAPI.SetValue(parameter, value);   
}

function LMSCommit()
{
  //the parameter is unused - reserved by SCORM for future use
  if (gblSCORMAPI.LMSCommit != null)
    return gblSCORMAPI.LMSCommit("");    
  else
    return gblSCORMAPI.Commit("");
}


//scorm/aicc api - udutu interface
function getBookmark()
{
  //var intScreenID = LMSGetValue("cmi.core.lesson_location");
  //if (intScreenID == "" || intScreenID == null) 
  //{
    var intScreenID = LMSGetValue("cmi.location"); //scorm 2004 (must do it both ways since a couple of clients have hybrid scorm2004/scorm 1.2 implementations)
    if (intScreenID == "" || intScreenID == null) 
        intScreenID = -1;
  //}
  return intScreenID;
}

function setBookmark(intScreenID)
{
  //LMSSetValue("cmi.core.lesson_location",intScreenID);
  LMSSetValue("cmi.location",intScreenID); //scorm 2004
}

function setCompleted()
{
  //LMSSetValue("cmi.core.lesson_status","completed");
  LMSSetValue("cmi.completion_status","completed"); //scorm 2004
}

function setIncomplete()
{
  //LMSSetValue("cmi.core.lesson_status","incomplete");
  LMSSetValue("cmi.completion_status","incomplete"); //scorm 2004
}

function setLogout()
{
  //LMSSetValue("cmi.core.exit","logout");
  LMSSetValue("cmi.exit","logout"); //scorm 2004
}

var arrInteractions = new Array();
var arrPreviousSessionInteractions = new Array();
//var prevSessionInteractionCount = 0;
function getInteractionIndex(id)
{
  for (var i = 0; i < arrInteractions.length; i++)
  {
    if (id == arrInteractions[i].id)
      return i;
  }
  return -1;
}
function initInteraction(toArr,id,result,description,correct_response,learner_response,type)
{
  this.id = id;
  this.result = result;
  this.description = description;
  this.type = type;
  this.correct_response = correct_response;
  this.learner_response = learner_response;
  toArr[toArr.length] = this;
}
//our application uses a journaling scheme to keep track of interactions so that
//results from previous sessions are not overwritten.  the length of the array
//is set so that the first n entries are null, where n is the number of interaction
//results stored from previous sessions.  the SCORM specification allows for this
function loadInteractions()
{
  var intArrLen = LMSGetValue('cmi.interactions._count');
  if (intArrLen != null && intArrLen > 0)
  {
    //arrPreviousSessionInteractions.length = intArrLen;
    for (i=0;i<intArrLen;i++)
    {
      var id = LMSGetValue('cmi.interactions.' + i + '.id');
      var result = LMSGetValue('cmi.interactions.' + i + '.result');
      var description = LMSGetValue('cmi.interactions.' + i + '.description');
      var type = LMSGetValue('cmi.interactions.' + i + '.type');
      var correct_response = LMSGetValue('cmi.interactions.' + i + '.correct_responses.0.pattern');
      var learner_response = LMSGetValue('cmi.interactions.' + i + '.learner_response');
      initInteraction(arrPreviousSessionInteractions,id,result,description,correct_response,learner_response,type);
    }
  }
}
function searchLastInteractionResult(interactionID)
{
  for (var i = arrInteractions.length -1; i>=0; i++)
  {
    if (arrInteractions[i].id == interactionID)
      return arrInteractions[i];
  }
  for (var i = arrPreviousSessionInteractions.length -1; i>=0; i++)
  {
    if (arrPreviousSessionInteractions[i].id == interactionID)
      return arrPreviousSessionInteractions[i];
  }
  return null; 
}
function setInteractionStatus(id, result, description,correct_response,learner_response,type)
{
  
      var intArrIndex = getInteractionIndex(id);
      var interaction;
      if (intArrIndex >= 0)
      {
        interaction = arrInteractions[intArrIndex];
        interaction.learner_response = learner_response;
      }
      else
      {
        interaction = new initInteraction(arrInteractions,id,result,description,correct_response,learner_response,type);
        intArrIndex = arrInteractions.length -1;
      }
  if (gblSCORMAPI != null)
  {
      var intSCORMindex = intArrIndex + arrPreviousSessionInteractions.length;
      LMSSetValue('cmi.interactions.' + intSCORMindex + '.id',id);
      LMSSetValue('cmi.interactions.' + intSCORMindex + '.result',result);
      LMSSetValue('cmi.interactions.' + intSCORMindex + '.description',description);
      //assume interaction is a mult-choice for now (this will change)
      if (type == null) type = 'choice';
      LMSSetValue('cmi.interactions.' + intSCORMindex + '.type',type);
      if (correct_response != null)
        LMSSetValue('cmi.interactions.' + intSCORMindex + '.correct_responses.0.pattern',correct_response);
      if (learner_response != null)
        LMSSetValue('cmi.interactions.' + intSCORMindex + '.learner_response',learner_response);
      saveProgress();
  }
}

function setProgressMeasure()
{
  if (gblCourse.completed == 'true')
  {
    LMSSetValue('cmi.progress_measure',1);
  }
  else
  {
      var modCount = gblModules.length;
      var completedCount = 0;
      if (modCount > 1)
      {
          for (var i = 0; i< modCount; i++)
          {
            if (gblModules[i].completed)
              completedCount++;
          }
          LMSSetValue('cmi.progress_measure',completedCount/modCount);
      }
      else
      {
        var scrCount = gblScreens.length;
        for (var i = 0; i<scrCount; i++)
        {
          if (gblScreens[i].isCompleted()== true)
            completedCount++;
        }
        if (scrCount == 0)
          LMSSetValue('cmi.progress_measure',completedCount/scrCount);
        else
          LMSSetValue('cmi.progress_measure',completedCount/scrCount);
      }
  }
}

function getSuspendData()
{
  var tmp = LMSGetValue("cmi.suspend_data");
  if (tmp == null) tmp = '';
  return tmp;
} 

function setSuspendData(parameter)
{
  LMSSetValue("cmi.suspend_data",parameter);
}

function initSCORM()
{ 
  if (gblSCORMAPI != null)
  {
      LMSInitialize();
      //go to the last page the student was on
      var intScreenID = getBookmark();
      if (intScreenID > 0)
      {
	    //gblStartOnMainMenu = false;	
        for (var i=0;i<gblScreens.length;i++)
        {
            if (gblScreens[i].id == intScreenID)
            {
                setCurrScreen(gblScreens[i]);
                gblPreviousScreen = getPreviousScreen();
                gblNextScreen = getNextScreen();
                break;
            }
        }
      }
      else
        initStartPage();
      //load the visited screens
      var suspendData = getSuspendData();
      var arrSUSPEND_DATA = suspendData.split(',');
      if (arrSUSPEND_DATA.length > 0)
      {
        //assume the screens in the list will be in order, so flagging
        //a screen as being completed will be quick
        var currSuspendIndex = 0;
        for (var i = 0; i < gblScreens.length; i++)
        {
          var tmpScreen = gblScreens[i];
          //if the ids match, flag the screen as completed, and increment the suspendindex
          //to try and match against the next screen in the list
          if (currSuspendIndex < arrSUSPEND_DATA.length)
          {
	        if (arrSUSPEND_DATA[currSuspendIndex] == tmpScreen.id)
	        {
            	tmpScreen.completed = true;
		        if (tmpScreen.completesParent)
		        { 
			        var mod = tmpScreen.parentModule;
			        mod.completed = true;
			        setModuleCompleted(mod);
		        }
		        currSuspendIndex++;
	        }
	        else
	        {
	         var arrSUSPEND_EL = arrSUSPEND_DATA[currSuspendIndex].split(':');

                if (arrSUSPEND_EL[0] == tmpScreen.id)
	            {
            	    tmpScreen.completed = true;
		            if (tmpScreen.completesParent)
		            { 
			            var mod = tmpScreen.parentModule;
			            mod.completed = true;
			            setModuleCompleted(mod);
		            }
		            currSuspendIndex++;
		            if (arrSUSPEND_EL.length > 1)
		            {
		                tmpScreen.score = arrSUSPEND_EL[1];
		            }
            	
	            }
	        }
          }
        }
      }
      loadInteractions();
  }
} 

function saveScore()
{
	var rawScore = 0;
	var maxScore = 0;
	for (var i = 0; i<gblScreens.length; i++)
      	{
          if(gblScreens[i].score > 0)
	  {
		rawScore += gblScreens[i].score;
	  }
	  maxScore += gblScreens[i].maxscore;
	}
	LMSSetValue('cmi.score.raw',rawScore);
	LMSSetValue('cmi.score.max',maxScore);
}

function saveProgress()
{
      gblCourse.completed = evaluateCourseCompletion(); 
      if (gblCourse.completed)
        setCompleted();
      else
        setIncomplete();
      var currScreen = getCurrScreen();
      setBookmark(currScreen.id);
      
      var strSuspendData = "";
      for (var i = 0; i<gblScreens.length; i++)
      {
        if(gblScreens[i].isCompleted())
        {
            if (strSuspendData != "")
              strSuspendData += ",";
            strSuspendData += gblScreens[i].id;
	    if (gblScreens[i].score > -1)
	    	strSuspendData += ":" + gblScreens[i].score;
            
        }
      }
      setSuspendData(strSuspendData);
      setProgressMeasure();
      saveScore();
      LMSCommit();
}

function doExitSCORM()
{
  if (gblSCORMAPI != null)
  {
      
      saveProgress();
      setLogout();
      LMSFinish();
  }
}