/*************************************************************************
 ** Copyright Knowledge Window Inc. 2002
 ** 
 ** Launch vLearn course to communicate with LRN, AICC.
 **
 ** Revision History:
 ** 1.0.2	5/10/2002  support JSAPI and HACP
 ** 1.0.1	11/15/2001 support AICC 3.0 and LRN 2.0
 **
 ***************************************************************************/
 

//HTTP delay time, content waits for this time after issuing getParam.
var HTTP_WAITING_TIME   = 500;

var g_oLMSAPI		= null;

var m_gstrAiccSid	="";
var m_gstrAiccUrl	="";
var web_launch		="";

var getParamURL		="";
var putParamURL		="";
var doneURL		="";

var t_score=0, t_status="complete";


var coreArray= new Array();
var lauParArray= new Array();	

//Error Message
var m_sLMSAPIError 	= "Failed to load LMS API";
var m_sParamParseError 	= "Failed to parse input parameters";
var m_sLRNStopError	= "Failed to stop LRN";



/***************************************************************************
 ** 
 ** Utility function for debug
 ** Revision 7/23/2002 ali - added debug window to hold the information
 **
 **
 ** debugModel:  1: normal alert message
 **              2: debug trace window
 **              0 or others: no debug output
 ***************************************************************************/
var traceLog = traceLog;  //notraceLog
var g_debugWin = null;    //debug window
var g_debugModel = 0;  
function traceLog
(strMessage)
{
	if (g_debugModel == 2) {
		if ( g_debugWin == null) {
			g_debugWin = window.open( "../LRN Viewer/HTML/debug.htm", "_debugWin");
		}
		
		if ( !g_debugWin.documentReady) {
			loadDebugPage(0, strMessage);
		}else
			writeDebugPage(strMessage);
	}
	
	if (g_debugModel == 1) {
		alert (strMessage);
	}

	return;
}

/***************************************************************************
 ** 
 ** Function to show all error message
 **
 ** $ TODO: This function shall be the standard way to display error message
 **         remove the alert message. 
 **
 ***************************************************************************/
function showErrorMsg
(strMessage, oError)
{
	var errordescription = "no error description";
	if (oError != null)
	{
		errordescription = oError.description;
	}
	alert ( "Error: " + strMessage + "\n" + "Error description: " +errordescription );
	return;
}

/***************************************************************************
 **
 ** Function to parse the input URL
 **
 ** Input URL format: http://..../page.htm?aicc_sid=xxxx&aicc_url=xxxx&web_launch=xxx
 **
 ** Refer to AICC CMI for the details on input parameters.
 **
 ***************************************************************************/
function GetURL(){
	traceLog ("Entering GetURL()");
	var root = "" + window.location;
	paramStr =root.substring(root.lastIndexOf("?")+1, root.length);
	UCparamStr=paramStr.toUpperCase();
	if(UCparamStr!=null && UCparamStr!=""){
		if(UCparamStr.indexOf("AICC_SID=") >=0){
			m_gstrAiccSid=paramStr.substring(UCparamStr.indexOf("AICC_SID=")+9, paramStr.length);
			if(m_gstrAiccSid.indexOf("&") >=0){
				m_gstrAiccSid=m_gstrAiccSid.substring(0, m_gstrAiccSid.indexOf("&"));	
			}
			m_gstrAiccSid=unescape(m_gstrAiccSid);	
		}
		if(UCparamStr.indexOf("AICC_URL=") >=0){
			m_gstrAiccUrl=paramStr.substring(UCparamStr.indexOf("AICC_URL=")+9, paramStr.length);
			if(m_gstrAiccUrl.indexOf("&") >=0){
				//m_gstrAiccUrl=paramStr.substring(UCparamStr.indexOf("AICC_URL=")+9, UCparamStr.indexOf("&"));
				// fix the parse bug 5/28/2002
				m_gstrAiccUrl=m_gstrAiccUrl.substring(0, m_gstrAiccUrl.indexOf("&"));
			}
			m_gstrAiccUrl=unescape(m_gstrAiccUrl);		
		}
		if(UCparamStr.indexOf("WEB_LAUNCH=") >=0){
			web_launch=paramStr.substring(UCparamStr.indexOf("WEB_LAUNCH=")+9, paramStr.length);
			if(web_launch.indexOf("&") >=0){
				web_launch=web_launch.substring(0, web_launch.indexOf("&"));
			}
			web_launch=unescape(web_launch);
		}
	}
	
	traceLog ("m_gstrAiccSid -- " + m_gstrAiccSid);
	traceLog ("m_gstrAiccUrl --" + m_gstrAiccUrl);
	traceLog ("web_launch -- " + web_launch);
}



/********************************************************************
 **
 ** JS function to exit course
 **
 ********************************************************************/
function exit(){
	if(confirm("Are you sure you want to exit the course?")){
		stopLRN();               //terminate LRN 
		saveInfoOnExit();	 //save the user cookie
		if (m_bProtocol == AICC_PROTOCOL_HACP)
		{
			ExitAU();
		}		
		window.syllabusMainFrame.onbeforeunload="";
		window.syllabusMainFrame.onunload="";
		window.location.replace(doneURL);  //relink to done page
	}
}

/********************************************************************
 **
 ** JS function to close the browser window
 **
 ********************************************************************/
function stopLRN(){
	traceLog ("Entering stopLRN()");
	try
	{
		traceLog ("Calling LMSAPI LRNTerminate()");
		top.g_oClassLMSAPI.LRNTerminate();
	}catch(e)
	{
		showErrorMsg(m_sLRNStopError, e);
	}
	
	try
	{
		traceLog ("Calling LMSAPI LMSFinish()");
		top.g_oClassLMSAPI.LMSFinish();
	}catch(e)
	{
		showErrorMsg(m_sLRNStopError, e);
	}
	traceLog ("Finished stopLRN()");
}

/***************************************************************************
 **
 ** function for before unload frameset
 **
 ***************************************************************************/
function beforeUnload() {
	event.returnValue="Please press the Cancel button and use the EXIT button to close the course! If you press the OK button, this window will be closed!";
}

/***************************************************************************
 **
 ** function to unload the frameset
 **
 ** warned user to use exit button first
 **
 **************************************************************************/
function unload () {
		stopLRN();               //terminate LRN 
		if (m_bProtocol == AICC_PROTOCOL_HACP)
		{
			ExitAU();
		}
		saveInfoOnExit();	 //save the user cookie
}

/***************************************************************************
 ** 
 ** function to start LRN 2.0
 **
 ***************************************************************************/
function startLRN()
{
   traceLog ("Entering startLRN()");
   try
      {
	var strSaveName = "lrntask";
	top.g_oClassLMSAPI = new LMSAPI_Instance("lrn", strSaveName);
	//LMS initial in its own block, even LMSInitial fails, LRN will continue
	try
	{	   
	   	top.g_oClassLMSAPI.LMSSetProtocol (getProtocol(), g_oLMSAPI );
	   	top.g_oClassLMSAPI.LMSInitialize();
	} catch (e)
	{
		showErrorMsg (m_sLMSAPIError, e);	
	}
	   
	top.g_oClassLMSAPI.LRNInitialize();
	traceLog ("replacing syllabus frame");
	//start to load syllabus frame
	top.frames('task').location.replace ("../LRN Viewer/HTML/SyllabusFrame.htm");
	traceLog ("replacing banner frame");
	top.frames('banner').location.replace ("../LRN Viewer/HTML/CourseNav.htm");
	PollFramesReadyState(0);
      }catch(e)
      {
	showErrorMsg (m_sLMSAPIError, e);
      }
      
      traceLog ("Finished launch.startLRN()");
}

/********************************************************************
 ** 
 ** check the LMS protocol
 ** The protocol priority: 1. JSAPI
 **                        2. HCAP
 ** it is used to define the protocol variable of LMSAPI object
 ********************************************************************/
var PROTOCOL_UNDEFINED  = 0;
var AICC_PROTOCOL_JSAPI = 1;
var AICC_PROTOCOL_HACP  = 2;
var m_bProtocol		= PROTOCOL_UNDEFINED;

function getProtocol () {
	traceLog ("Entering getProtocol");
	if (g_oLMSAPI != null) {
		traceLog ("Using AICC_PROTOCOL_JSAPI");
		return AICC_PROTOCOL_JSAPI;
	}
	if( m_gstrAiccUrl!="" && m_gstrAiccSid != ""){
		traceLog ("Using AICC_PROTOCOL_HACP");
		return AICC_PROTOCOL_HACP;
	}
	
	traceLog ("Protocol undefined");
	return PROTOCOL_UNDEFINED;
}


/*******************************************************************************
**
** findAPI() recursively search current window's hierchy for the object named API.
**
** Return:  If an API object is found, it's returned, otherwise null is returned
**
*******************************************************************************/
function findAPI(win)
{
	traceLog ("launch.findAPI(win) -- Entering findAPI()...");
	var oWinContainer = win;	
	try
	{
		while(typeof(oWinContainer) != "undefined" )
		{				
			if ( oWinContainer != null) {
				traceLog ("Searching oWinContainer." + oWinContainer.location.href);
				if(oWinContainer.API != null)
				{
					traceLog ("Found LMS API object");
					return oWinContainer.API;
				}
				
				//search all the next level frames of this top window
				if (oWinContainer.length > 0)
   				{
      					//traceLog("looking for api in " + oWinContainer.length + " windows frames");

      					for (var i=0;i< oWinContainer.length;i++)
      					{
            					//traceLog ("Recursively looking for api in frames["+i+"] of " + oWinContainer.length);
         					if (oWinContainer.frames[i].API != null)
         					{
         						traceLog ("Found LMS API object");
            						return oWinContainer.frames[i].API;
         					}
         				}
      				}	
			
				if(typeof(oWinContainer.opener) != "undefined")
				{
					if (oWinContainer.opener != null ) {
						traceLog ("Go up one level.");
						oWinContainer = oWinContainer.opener.top;
					}
				}else
				{
					//no parent
					traceLog ("This window doesn't have parent");
					break;
				}
			}
		}
		
		traceLog ("LMS API object not found");
		return null;
	}
	catch(e)
	{
		traceLog ("Error on finding LMS API: " + e.description);
		return null;
	}
}

/********************************************************************
 ** 
 ** main page start process
 **
 ********************************************************************/
function start(){
	traceLog ("launch.start()--Entering main page init");
	//initialize global variables
	var root = "" + document.location;
	root = root.substring(0,root.lastIndexOf("/")+1);
	getParamURL = root+ escape ("../LRN Viewer/HTML/GetParam.htm");
	putParamURL = root+ escape ("../LRN Viewer/HTML/PutParam.htm");
	doneURL =root+ escape ("../LRN Viewer/HTML/done.htm");

	//parse input URL
	GetURL();
		
	//find the LMS API
	g_oLMSAPI = findAPI(this.top);

	m_bProtocol = getProtocol();
	
	if ( m_bProtocol == AICC_PROTOCOL_HACP)
	{
		m_gbGetParamDone = false;
		GetParam();
	}
	
	if ( m_bProtocol != PROTOCOL_UNDEFINED)
	{
		//need to wait for server response
		top.frames('task').document.write ("<DIV ID='WaitingNotice' style='position: absolute; width:550px; height:100px; top:200px; left:100px; visibility:visible;z-index:0'><Center><H4>Connecting to  LMS server. Waiting...</H4></Center></DIV>");
		setTimeout("startLRN()", HTTP_WAITING_TIME + 2000);
	}else
	{
		//local launch
		startLRN();
	}
	traceLog ("launch.start()--Finished main page init");
}

/*********************************************
 ** Utility Function for time waiting
 **
 ** @create 7/23/2002
 **
 *********************************************/
function loadDebugPage(elapsed, strMessage) {
	// ====== START OF CONFIGURABLE SETTINGS ======
	var MAX_TIME_TO_WAIT = 15; // Time in SECONDS before user is asked if they wish to cancel loading.
	var POLLING_DELAY = 100; // Time in MILLISECONDS between load checks.
	// ====== END OF CONFIGURABLE SETTINGS ======
	var elapsed = (elapsed ? parseInt(elapsed, 10) : 0);
	
	if (!g_debugWin.documentReady) {
		if (elapsed >= MAX_TIME_TO_WAIT*1000) {
			if (confirm("Still trying to load page after waiting " + MAX_TIME_TO_WAIT + " seconds.\n\nChoose \"OK\" to continue waiting, \"CANCEL\" to stop.")) elapsed = 0;
				else 
				{
					alert ("Failed to load debug window!");
					return;
				}
			}
			setTimeout("loadDebugPage(" + (elapsed+=POLLING_DELAY) + "," + strMessage + ")", POLLING_DELAY);
	}
	else 
		writeDebugPage(strMessage); // MODIFY THIS FUNCTION NAME TO YOUR OWN FUNCTION TO CALL WHEN ALL FRAMES ARE LOADED

}

/***********************************************
 ** Method to write trace message to debug window
 ** 
 ** only called after the debug window are loaded
 **
 ************************************************/
function writeDebugPage(strMessage){	
	
		strOldMsg = g_debugWin.document.all("debugMsg").value;
		//alert (strOldMsg);
		timestamp = new Date();
		g_debugWin.document.all("debugMsg").innerText = strOldMsg + "\n" +  timestamp + "-----" + strMessage;
}



/***************************************************************
 ** To check if all frames has been loaded and are ready
 **
 ** @revision 7/24/2002 ali - added for KPMG Bug Report 001
 ***************************************************************/
function PollFramesReadyState(elapsed) {
	traceLog ("Entering PollFramesReadyState( " + elapsed + ")" );
	// ====== START OF CONFIGURABLE SETTINGS ======
	var MAX_TIME_TO_WAIT = 15; // Time in SECONDS before user is asked if they wish to cancel loading.
	var POLLING_DELAY = 200; // Time in MILLISECONDS between frame checks.
	// ====== END OF CONFIGURABLE SETTINGS ======

	var elapsed = (elapsed ? parseInt(elapsed, 10) : 0);
	var w = window.frames; var readyFramesCnt = 0; l = w.length;
	if (typeof(w) != "undefined") {
		for (var f=0; f<l; ++f) {if (w[f] && w[f].documentReady) readyFramesCnt++;}
		if (readyFramesCnt != l || l == 0) {
			if (elapsed >= MAX_TIME_TO_WAIT*1000) {
				if (confirm("Still trying to load " + (l - readyFramesCnt) + " [" + f + "] of the " + l + " frames after waiting " + MAX_TIME_TO_WAIT + " seconds.\n\nChoose \"OK\" to continue waiting, \"CANCEL\" to stop.")) elapsed = 0;
				else 
				{
					alert ("Failed to load syllabus frame and banner frames");
					return;
				}
			}
			setTimeout("PollFramesReadyState(" + (elapsed+=POLLING_DELAY) + ")", POLLING_DELAY);
		}
		else onFramesReady(); // MODIFY THIS FUNCTION NAME TO YOUR OWN FUNCTION TO CALL WHEN ALL FRAMES ARE LOADED
	}
	else alert("Your browser doesn't appear to support frames.");
}

/****************************************************************
 ** Function to be called when all frames are ready
 ****************************************************************/
function onFramesReady()
{
	traceLog ("Entering onFramesReady");
	top.frames('task').frames("syllabus").Syllabus_Start();

}
 	
//var to determine the end of launching this script page
var g_sLaunchDone = "done";

