// Delphi Training shared JavaScript code
// Prepared 2/16/2004-kbrote
// Edited 8/31/05 - tschatz
// Last Edit 05/17/2007 - mtemple
//
//05/17/2007 MT - Changed numerous functions to allow the new 9.5 UI to work correctly including:
//Added functions closeWindow(), closeTraining(), checkBrowser(), NI_setGlossary(), setPage()
//
//06/07/06 TS - Added fullscreen functionality to MM_openBRWindow()
//Added left=0, top=0 to MM_openBRWindow

//5/2/06 TS - Added NI_removeMenu function to handle right clicks

//4/21/06 TS - Changed doLMSFinish, doLMSInitialize, LMSFindAPI, LMSGetAPI
//commented out the alerts for use with non LMS systems
//
//Added the NI_FindPage function to find the first page from the lessonXML 
//
function checkBrowser(){
var agt = navigator.appName.toLowerCase();
if (agt=="netscape"){
	document.write('<link rel="stylesheet" type="text/css" href="../scripts/fftraining.css" />');
}else{
	document.write('<link rel="stylesheet" type="text/css" href="../scripts/ietraining.css" />');
}
}
//
function closeWindow(){	window.close(); }
//
function closeTraining(){
	NI_killChildren();
	opener.document.location.href='../default.htm';
}
//
function NI_changewindow(){
	var LMS = doLMSInitialize();
	var page = "holder";
	MM_openBrWindow(page + ".htm?LMS="+LMS,page,'scrollbars=yes, resizable=no, width=1000, height=651, left=0,top=0');
}
//
function NI_setGlossary(term){
	MM_openBrWindow("../glossary/glossary.htm?term="+term, 'Glossary','scrollbars=yes, resizable=no, width=961, height=650, left=0,top=0');
}
//
function NI_getURL() {
    return window.location.toString();
}
//
function setPage(page){
	window.frames["content"].location.href = page + ".htm";
}
//
function NI_removeMenu(page){
	if (event.button == 2){
		FInteraction.TGotoFrame("/", page);
		window.frames["content"].location.replace('javascript: parent');
	}
}

/*
function removeMenu(){
	if (event.button == 2){
		FInteraction.TGotoFrame("/", 1);
		location.replace('javascript: parent.dummy1');
	}
}
*/
//Opens the specific lessons init page which was chosen from the main menu.
function NI_openInit(page){
	NI_killChildren();
	MM_openBrWindow(page + "/holder.htm", page,'scrollbars=yes, resizable=no, width=1000, height=651, left=0,top=0');
}
//
function NI_findPage(){
	var thisXML = new ActiveXObject("Microsoft.XMLDOM");
	thisXML.async = false;
	thisXML.load("lessonXML.xml");
	var pages = thisXML.getElementsByTagName("PAGE");
	return(pages[0].getAttribute("name").slice(0,3));
}
function NI_killChildren(args){
	//window.alert("Kill");
	//window.alert(window.children);
	if(window.children){
		for(var i = 0; i < window.children.length; i++){
			var closeWin = window.children[i];
			closeWin.close();
		}
	}
}
//
function NI_buildObject(obj, initText){
	document.write(obj)
	if(initText){
		NI_feedback(initText);
	}
}
//
function NI_standards(id){
	/*var thisPage = document.URL;
	thisPage = thisPage.slice(thisPage.lastIndexOf("/") + 1, thisPage.lastIndexOf("/") + 4);
	var thisPage = findURL();
	thisPage = thisPage.slice(0, 3);
	*/
	thisPage = id + "_Standards.htm";
	thisPage = "../standards/"+thisPage;
	MM_openBrWindow(thisPage,"standards","scrollbars=yes,resizable=yes,width=1000,height=650,left=0,top=0")
}


function findURL(){
	
	var sPath = window.location.pathname;
	var slash = "\\";
	if(sPath.lastIndexOf(slash) == -1){
		slash = "/";
	}
	var sPage = sPath.substring(sPath.lastIndexOf(slash) + 1);
	sPage = sPage.substring(0, sPage.lastIndexOf('.'));
	return sPage;
}
//
function NI_checkForInitText(){
	if(initText != ""){
		var myArray = NI_makeArray(initText);
		
		NI_feedback(myArray[0], myArray[1], myArray[2], myArray[3]);
	}
}
//
function NI_feedback(val, title, ind, cor){
	
	if(!title){
		myArray = NI_makeArray(val);
		val = myArray[0];
		title = myArray[1];
		ind = myArray[2];
		cor = myArray[3];
		//alert("HI"+myArray[3]);
	}
	window.document.myFeedback.SetVariable("myFeedback", val);
	window.document.myFeedback.SetVariable("myTitle", title);
	window.document.myFeedback.SetVariable("ind", ind);
	window.document.myFeedback.SetVariable("cor", cor);
}
//
function NI_showHideLayers(lay, vis){
	if(!vis){
		myArray = NI_makeArray(lay);
		lay = myArray[0];
		vis = myArray[1];
	}
	vis=(vis == "show")?"visible":"hidden";
	document.getElementById(lay).style.visibility = vis;
}


function NI_makeArray(args){
	var myArray = args.split("~");
	return(myArray);
}

/*************************************************************/


function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

function MM_swapImage() { //v3.0
  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}

function MM_swapImgRestore() { //v3.0
  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}

function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_jumpMenu(targ,selObj,restore){ //v3.0
  eval(targ+".location='"+selObj.options[selObj.selectedIndex].value+"'");
  if (restore) selObj.selectedIndex=0;
}

function MM_showHideLayers() { //v6.0
  var i,p,v,obj,args=MM_showHideLayers.arguments;
  for (i=0; i<(args.length-2); i+=3) if ((obj=MM_findObj(args[i]))!=null) { v=args[i+2];
    if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v=='hide')?'hidden':v; }
    obj.visibility=v; }
}

// Most likely never called - but just in case they are on Netscape

function MM_reloadPage(init) {  //reloads the window if Nav4 resized - Just in case for try it and try it now pages built using show / hide layers
  if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
    document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; onresize=MM_reloadPage; }}
  else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) location.reload();
}
MM_reloadPage(true);

// Used to pop new windows like glossary or teach me more
//Altered by TS to put the names of each window that opens into an array

function MM_openBrWindow(theURL,winName,features) { //v2.0
  var endIndex = features.length;
  if(features.indexOf(",", features.indexOf("width")) != -1){
	  endIndex = features.indexOf(",", features.indexOf("width"));
  }
  var myWidth = features.substring(features.indexOf("width"), endIndex);
  for(var i = 0; i < myWidth.length; i++){
	  var temp = myWidth.charAt(i);
	  if(!isNaN(temp)){
		  myWidth = myWidth.substring(i, endIndex);
		  break;
	  }
  }
  
  endIndex = features.length;
  if(features.indexOf(",", features.indexOf("height")) != -1){
	  endIndex = features.indexOf(",", features.indexOf("height"));
  }
  var myHeight = features.substring(features.indexOf("height"), endIndex);
  for(var i = 0; i < myHeight.length; i++){
	  var temp = myHeight.charAt(i);
	  if(!isNaN(temp)){
		  myHeight = myHeight.substring(i, endIndex);
		  break;
	  }
  }
  
  /*if(myWidth >= 1000 && myHeight >= 710){
	  
	  var endIndex = features.length;
  	  if(features.indexOf(",", features.indexOf("width")) != -1){
	  	endIndex = features.indexOf(",", features.indexOf("width"));
  	  }
	  preFeatures = features.substring(0, features.indexOf("width"));
	  postFeatures = features.substring(endIndex);
	  
	  features = preFeatures + "width="+screen.width + postFeatures;
	 
	  var endIndex = features.length;
  	  if(features.indexOf(",", features.indexOf("height")) != -1){
	  	endIndex = features.indexOf(",", features.indexOf("height"));
  	  }
	  preFeatures = features.substring(0, features.indexOf("height"));
	  postFeatures = features.substring(endIndex);
	  
	  features = preFeatures + "height="+screen.height + postFeatures;
	  //features = features + ",fullscreen=yes";
	  //alert(features);
  }*/
  
  if(features.indexOf("left") == -1){
	  features = features + ",left=0,top=0";
  }
  
  var thisWin = window.open(theURL,winName,features);
  if(window.children){
	  for(var i = 0; i < window.children.length; i++){
		  if(window.children[i] == thisWin){
			  //window.alert("BREAK");
			  return;
		  }
	  }
	  window.children = window.children.concat(thisWin);
	 // window.alert("Already");
  }else{
	  window.children = [thisWin];
  }
  //window.alert(children.length);
}

// Do not allow the user to re-size the window

function checkKey()
{
  if (window.event.keyCode == 122)
  {
    window.event.keyCode = 0;
    return false;
  }
  return true;
}

// LMS Script
/*******************************************************************************
**
** Concurrent Technologies Corporation (CTC) grants you ("Licensee") a non-
** exclusive, royalty free, license to use, modify and redistribute this
** software in source and binary code form, provided that i) this copyright
** notice and license appear on all copies of the software; and ii) Licensee does
** not utilize the software in a manner which is disparaging to CTC.
**
** This software is provided "AS IS," without a warranty of any kind.  ALL
** EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
** IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-
** INFRINGEMENT, ARE HEREBY EXCLUDED.  CTC AND ITS LICENSORS SHALL NOT BE LIABLE
** FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
** DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL CTC  OR ITS
** LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
** INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
** CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
** OR INABILITY TO USE SOFTWARE, EVEN IF CTC  HAS BEEN ADVISED OF THE POSSIBILITY
** OF SUCH DAMAGES.
**
*******************************************************************************/

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;


/*******************************************************************************
**
** Function: doLMSInitialize()
** Inputs:  None
** Return:  CMIBoolean true if the initialization was successful, or
**          CMIBoolean false if the initialization failed.
**
** Description:
** Initialize communication with LMS by calling the LMSInitialize
** function implemented by the LMS.
**
*******************************************************************************/
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();
   }

   return result.toString();
}

/*******************************************************************************
**
** Function doLMSFinish()
** Inputs:  None
** Return:  CMIBoolean true if successful
**          CMIBoolean false if failed.
**
** Description:
** Close communication with LMS by calling the LMSFinish
** function implemented by the LMS
**
*******************************************************************************/

function doLMSFinish()
{
   var api = getAPIHandle();
   if (api == null)
   {
      //alert("Unable to locate the LMS's API Implementation.\nLMSFinish was not successful.");
	  window.close();
      return "false";
   }
   else
   {
      // call the LMSFinish function that should be implemented by the API

      var result = api.LMSFinish("");
      if (result.toString() != "true")
      {
         var err = ErrorHandler();
      }

   }
	window.close();
   return result.toString();
}

/********************************************************************************
*           This code is activated for standalone non-LMS deployment            *
*********************************************************************************/
/*
function doLMSFinish()
{
	window.navigate("../default.htm");
}

/*******************************************************************************
**
** Function doLMSGetValue(name)
** Inputs:  name - string representing the cmi data model defined category or
**             element (e.g. cmi.core.student_id)
** Return:  The value presently assigned by the LMS to the cmi data model
**       element defined by the element or category identified by the name
**       input value.
**
** Description:
** Wraps the call to the LMS LMSGetValue method
**
*******************************************************************************/
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)
** Inputs:  name -string representing the data model defined category or element
**          value -the value that the named element or category will be assigned
** Return:  CMIBoolean true if successful
**          CMIBoolean false if failed.
**
** Description:
** Wraps the call to the LMS LMSSetValue function
**
*******************************************************************************/
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()
** Inputs:  None
** Return:  None
**
** Description:
** Call the LMSCommit function 
**
*******************************************************************************/
function doLMSCommit()
{
   var api = getAPIHandle();
   if (api == null)
   {
      alert("Unable to locate the LMS's API Implementation.\nLMSCommit was not successful.");
      return "false";
   }
   else
   {
      var result = api.LMSCommit("");
      if (result != "true")
      {
         var err = ErrorHandler();
      }
   }

   return result.toString();
}

/*******************************************************************************
**
** Function doLMSGetLastError()
** Inputs:  None
** Return:  The error code that was set by the last LMS function call
**
** Description:
** Call the LMSGetLastError function 
**
*******************************************************************************/
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)
** Inputs:  errorCode - Error Code
** Return:  The textual description that corresponds to the input error code
**
** Description:
** Call the LMSGetErrorString function 
**
********************************************************************************/
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)
** Inputs:  errorCode - Error Code(integer format), or null
** Return:  The vendor specific textual description that corresponds to the 
**          input error code
**
** Description:
** Call the LMSGetDiagnostic function
**
*******************************************************************************/
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()
** Inputs:  none
** Return:  true if the LMS API is currently initialized, otherwise false
**
** Description:
** Determines if the LMS API is currently initialized or not.
**
*******************************************************************************/
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()
** Inputs:  None
** Return:  The current value of the LMS Error Code
**
** Description:
** Determines if an error was encountered by the previous API call
** and if so, displays a message to the user.  If the error code
** has associated text it is also displayed.
**
*******************************************************************************/
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()
** 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 findAPI(win)
** Inputs:  win - a Window Object
** Return:  If an API object is found, it's returned, otherwise null is returned
**
** Description:
** This function looks for an object named API in parent and opener windows
**
*******************************************************************************/
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()
** Inputs:  none
** Return:  If an API object is found, it's returned, otherwise null is returned
**
** Description:
** This function looks for an object named API, first in the current window's 
** frame hierarchy and then, if necessary, in the current window's opener window
** hierarchy (if there is an opener window).
**
*******************************************************************************/
function getAPI()
{
   var theAPI = findAPI(window);
   if ((theAPI == null) && (window.opener != null) && (typeof(window.opener) != "undefined"))
   {
      theAPI = findAPI(window.opener);
   }
   if (theAPI == null)
   {
      //alert("Unable to find an API adapter");
   }
   return theAPI
}