
// Define exception/error codes
var _NoError = "0";
var _DataSaveError = "302";
var _NotImplementedError = "401";
var _ElementIsReadOnly = "403";
var _ElementIsWriteOnly = "404";
var _Debug = true;
var _WriteOnly = "2";
var _ReadOnly = "1";
var _ReadWrite = "0";
var _getData = "getParam";
var _setData = "setParam";

var _TimeoutID = 0;
var _launchPath = "";
var _childWin = "";
var _lmsOrigTime = 0;
var _lmsStartTime = 0;
var _lmsTimeID = 0;

var _int_current_count = 0; // current interactions stored in memory
var _int_max_count = 3;  // max possible interactions stored in memory
var _index = 0;

var _totTime = "";
var _lastSessTime = "00:00:00.0";


//***********************************************************************
// Error Manager code
//***********************************************************************
var LMSerrors =
[
   ["0", "No Error", "The previous LMS API Function call completed successfully."],
   ["101", "General Exception", "An unspecified, unexpected exception has occured"],
   ["201", "Invalid argument error", ""],
   ["202", "Element can not have children", ""],
   ["203", "Element not an array - cannot have count", ""],
   ["301", "Not initialized", "The LMS is not initialized."],
   ["302", "LMS error", "Last call to LMSSetValue()was unsuccessful.  Data will not be saved"],
   ["401", "Not implemented error", "The data model element in question was not implemented"],
   ["402", "Invalid set value, element is a key word",
      "Trying to set a reserved key word in the data model" +
      "Trying to set a key word (_count, _children, or _version) " +
      "This is prohibited"],
   ["403", "Element is read only",
      "Data Element is Read Only (Not Writeable)"+
      "Cannot call LMSSetValue() for the element in question"],
   ["404", "Element is write only",
      "Data Element is Write Only (Not Readable)"+
      "Cannot call LMSGetValue() for the element in question"],
   ["405", "Incorrect Data Type",
      "Invalid Type being used for setting element"+
      "The type being used as the set value argument does not match" +
      " that of the element being set"],
   ["499", "Interaction type unknown",
      "Interaction type must be defined first" +
      "Interaction type unknown..."]
];
	
   
 function clLMSErrorManager() 
 {
 	this.currentErrorCode='0';
	this.currentNotDefinedErrorDescription = "";  //for errors not predefined in the LMS
	this.GetCurrentErrorCode=GetCurrentErrorCode;
 	this.SetCurrentErrorCode=SetCurrentErrorCode;
 	this.ClearCurrentErrorCode=ClearCurrentErrorCode;
 	this.GetErrorDescription=GetErrorDescription;
 	this.GetErrorDiagnostic=GetErrorDiagnostic;
 	this.GetErrorElement=GetErrorElement;
}

function GetCurrentErrorCode() 
{ 
	return this.currentErrorCode; 
}

function SetCurrentErrorCode(code)
{ 
	if ((code != null) && (code != '')) 
		this.currentErrorCode = code; 
	else 
		this.currentErrorCode = '0'; 
}

function ClearCurrentErrorCode() 
{ 
	this.currentErrorCode = LMSerrors[0][0]; 
}

function GetErrorDescription(code) 
{ 
	if((code != null) && (code != "") && (code > 100)) 
		return this.GetErrorElement(code)[1]; 
	else 
		return this.currentNotDefinedErrorDescription; 
}

function GetErrorDiagnostic(code) 
{ 
	if((code != null) && (code != "") && (code > 100)) 
		return this.GetErrorElement(code)[2]; 
	else 
		return ""; 
}
   
function GetErrorElement(code)
{
  for(i=0; i < LMSerrors.length; i++)
    if(LMSerrors[i][0] == code) 
		return LMSerrors[i];
 
  return [code,this.currentNotDefinedErrorDescription,this.currentNotDefinedErrorDescription];
}

//***********************************************************************
//*** BEGIN definition individual data pieces **/
//readWrite: 0 = R & W
//			 1 = R only
//			 2 = W only
//***********************************************************************

function getFieldValueString(sFieldName)
{
	var sDataField = "parent.frames['lmsData'].document.getElementById('" + sFieldName + "').value";
	
	return sDataField;
}

function cl_suspend_data(){
	this.data = getFieldValueString("suspend");
	this.readWrite = _ReadWrite;
}

function cl_lesson_status(){
	this.data = getFieldValueString("scoStatus");
	this.readWrite = _ReadWrite;
}

function cl_student_name(){
	this.data = getFieldValueString("userName");
	this.readWrite = _ReadOnly;
}

function cl_student_id(){
	this.data = getFieldValueString("stuID");
	this.readWrite = _ReadOnly;
}

function cl_session_time(){
	this.data = getFieldValueString("sessTime");
	this.readWrite = _WriteOnly;
}

function cl_lmsTime(){
	this.data = getFieldValueString("lmsTime");
	this.readWrite = _ReadWrite;
}

function cl_total_time(){
	this.data = getFieldValueString("totalTime");
	this.readWrite = _ReadOnly;
}

function cl_raw(){
	this.data = getFieldValueString("rawScore");
	this.readWrite = _ReadWrite;
}

function cl_end_of_sco(){
	this.data = getFieldValueString("endofsco");
	this.readWrite = _ReadWrite;
}

//**************************************************************************************************

//*** startwood elements
function cl_exit(){
	this.data = getFieldValueString("exit");
	this.readWrite = _ReadWrite;
}

function cl_max(){
	this.data = getFieldValueString("maxScore");
	this.readWrite = _ReadWrite;
}

function cl_min(){
	this.data = getFieldValueString("minScore");
	this.readWrite = _ReadWrite;
}

function cl_int_count(){
	this.data = getFieldValueString("int_count");
	this.readWrite = _ReadOnly;
}

function cl_lesson_mode(){
	this.data = getFieldValueString("lesson_mode");
	this.readWrite = _ReadOnly;
}

//----------------------------------------------------------------------------------
function cl_int0_id(){
	this.data = getFieldValueString("int0_id");
	this.readWrite = _WriteOnly;
}

function cl_int0_type(){
	this.data = getFieldValueString("int0_type");
	this.readWrite = _WriteOnly;
}

function cl_int0_student_response(){
	this.data = getFieldValueString("int0_student_response");
	this.readWrite = _WriteOnly;
}

function cl_int0_result(){
	this.data = getFieldValueString("int0_result");
	this.readWrite = _WriteOnly;
}

function cl_int0_weighting(){
	this.data = getFieldValueString("int0_weighting");
	this.readWrite = _WriteOnly;
}

function cl_int0_latency(){
	this.data = getFieldValueString("int0_latency");
	this.readWrite = _WriteOnly;
}

function cl_int0_time(){
	this.data = getFieldValueString("int0_time");
	this.readWrite = _WriteOnly;
}

//** correct responses - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int0_correct_responses(){
	this.int0 = new cl_int0_correct_responses0();	
}

function cl_int0_correct_responses0(){
	this.id = new cl_int0_correct_responses0_id();	
	//this.<other elements>
}

function cl_int0_correct_responses0_id(){
	this.data = getFieldValueString("int0_correct_responses0_id");
	this.readWrite = _WriteOnly;
}

//** objectives - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int0_objectives(){
	this.int0 = new cl_int0_objectives0();
}

function cl_int0_objectives0(){
	this.id = new cl_int0_objectives0_id();
}

function cl_int0_objectives0_id(){
	this.data = getFieldValueString("int0_objectives0_id");
	this.readWrite = _WriteOnly;
}

//----------------------------------------------------------------------------------
function cl_int1_id(){
	this.data = getFieldValueString("int1_id");
	this.readWrite = _WriteOnly;
}

function cl_int1_type(){
	this.data = getFieldValueString("int1_type");
	this.readWrite = _WriteOnly;
}

function cl_int1_student_response(){
	this.data = getFieldValueString("int1_student_response");
	this.readWrite = _WriteOnly;
}

function cl_int1_result(){
	this.data = getFieldValueString("int1_result");
	this.readWrite = _WriteOnly;
}

function cl_int1_weighting(){
	this.data = getFieldValueString("int1_weighting");
	this.readWrite = _WriteOnly;
}

function cl_int1_latency(){
	this.data = getFieldValueString("int1_latency");
	this.readWrite = _WriteOnly;
}

function cl_int1_time(){
	this.data = getFieldValueString("int1_time");
	this.readWrite = _WriteOnly;
}


//** correct responses - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int1_correct_responses(){
	this.int0 = new cl_int1_correct_responses0();
}

function cl_int1_correct_responses0(){
	this.pattern = new cl_int1_correct_responses0_pattern();
}

function cl_int1_correct_responses0_pattern(){
	this.data = getFieldValueString("int1_correct_responses0_pattern");
	this.readWrite = _WriteOnly;
}


//** objectives - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int1_objectives(){
	this.int0 = new cl_int1_objectives0();
}

function cl_int1_objectives0(){
	this.id = new cl_int1_objectives0_id();
}

function cl_int1_objectives0_id(){
	this.data = getFieldValueString("int1_objectives0_id");
	this.readWrite = _WriteOnly;
}

//---------------------------------------------------------------------------------------

function cl_int2_id(){
	this.data = getFieldValueString("int2_id");
	this.readWrite = _WriteOnly;
}

function cl_int2_type(){
	this.data = getFieldValueString("int2_type");
	this.readWrite = _WriteOnly;
}

function cl_int2_student_response(){
	this.data = getFieldValueString("int2_student_response");
	this.readWrite = _WriteOnly;
}

function cl_int2_result(){
	this.data = getFieldValueString("int2_result");
	this.readWrite = _WriteOnly;
}

function cl_int2_weighting(){
	this.data = getFieldValueString("int2_weighting");
	this.readWrite = _WriteOnly;
}

function cl_int2_latency(){
	this.data = getFieldValueString("int2_latency");
	this.readWrite = _WriteOnly;
}

function cl_int2_time(){
	this.data = getFieldValueString("int2_time");
	this.readWrite = _WriteOnly;
}

//** correct responses - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int2_correct_responses(){
	this.int0 = new cl_int2_correct_responses0();
}

function cl_int2_correct_responses0(){
	this.pattern = new cl_int2_correct_responses0_pattern();
}

function cl_int2_correct_responses0_pattern(){
	this.data = getFieldValueString("int2_correct_responses0_pattern");
	this.readWrite = _WriteOnly;
}


//** objectives - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int2_objectives(){
	this.int0 = new cl_int2_objectives0();
}

function cl_int2_objectives0(){
	this.id = new cl_int2_objectives0_id();
}

function cl_int2_objectives0_id(){
	this.data = getFieldValueString("int2_objectives0_id");
	this.readWrite = _WriteOnly;
}

//---------------------------------------------------------------------------------------

function cl_int3_id(){
	this.data = getFieldValueString("int3_id");
	this.readWrite = _WriteOnly;
}

function cl_int3_type(){
	this.data = getFieldValueString("int3_type");
	this.readWrite = _WriteOnly;
}

function cl_int3_student_response(){
	this.data = getFieldValueString("int3_student_response");
	this.readWrite = _WriteOnly;
}

function cl_int3_result(){
	this.data = getFieldValueString("int3_result");
	this.readWrite = _WriteOnly;
}

function cl_int3_weighting(){
	this.data = getFieldValueString("int3_weighting");
	this.readWrite = _WriteOnly;
}

function cl_int3_latency(){
	this.data = getFieldValueString("int3_latency");
	this.readWrite = _WriteOnly;
}

function cl_int3_time(){
	this.data = getFieldValueString("int3_time");
	this.readWrite = _WriteOnly;
}

//** correct responses - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int3_correct_responses(){
	this.int0 = new cl_int3_correct_responses0();
}

function cl_int3_correct_responses0(){
	this.pattern = new cl_int3_correct_responses0_pattern();
}

function cl_int3_correct_responses0_pattern(){
	this.data = getFieldValueString("int3_correct_responses0_pattern");
	this.readWrite = _WriteOnly;
}


//** objectives - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int3_objectives(){
	this.int0 = new cl_int3_objectives0();
}

function cl_int3_objectives0(){
	this.id = new cl_int3_objectives0_id();
}

function cl_int3_objectives0_id(){
	this.data = getFieldValueString("int3_objectives0_id");
	this.readWrite = _WriteOnly;
}


//---------------------------------------------------------------------------------------


function cl_int4_id(){
	this.data = getFieldValueString("int4_id");
	this.readWrite = _WriteOnly;
}

function cl_int4_type(){
	this.data = getFieldValueString("int4_type");
	this.readWrite = _WriteOnly;
}

function cl_int4_student_response(){
	this.data = getFieldValueString("int4_student_response");
	this.readWrite = _WriteOnly;
}

function cl_int4_result(){
	this.data = getFieldValueString("int4_result");
	this.readWrite = _WriteOnly;
}

function cl_int4_weighting(){
	this.data = getFieldValueString("int4_weighting");
	this.readWrite = _WriteOnly;
}

function cl_int4_latency(){
	this.data = getFieldValueString("int4_latency");
	this.readWrite = _WriteOnly;
}

function cl_int4_time(){
	this.data = getFieldValueString("int4_time");
	this.readWrite = _WriteOnly;
}

//** correct responses - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int4_correct_responses(){
	this.int0 = new cl_int4_correct_responses0();
}

function cl_int4_correct_responses0(){
	this.pattern = new cl_int4_correct_responses0_pattern();
}

function cl_int4_correct_responses0_pattern(){
	this.data = getFieldValueString("int4_correct_responses0_pattern");
	this.readWrite = _WriteOnly;
}


//** objectives - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int4_objectives(){
	this.int0 = new cl_int4_objectives0();
}

function cl_int4_objectives0(){
	this.id = new cl_int4_objectives0_id();
}

function cl_int4_objectives0_id(){
	this.data = getFieldValueString("int4_objectives0_id");
	this.readWrite = _WriteOnly;
}


//---------------------------------------------------------------------------------------


function cl_int5_id(){
	this.data = getFieldValueString("int5_id");
	this.readWrite = _WriteOnly;
}

function cl_int5_type(){
	this.data = getFieldValueString("int5_type");
	this.readWrite = _WriteOnly;
}

function cl_int5_student_response(){
	this.data = getFieldValueString("int5_student_response");
	this.readWrite = _WriteOnly;
}

function cl_int5_result(){
	this.data = getFieldValueString("int5_result");
	this.readWrite = _WriteOnly;
}

function cl_int5_weighting(){
	this.data = getFieldValueString("int5_weighting");
	this.readWrite = _WriteOnly;
}

function cl_int5_latency(){
	this.data = getFieldValueString("int5_latency");
	this.readWrite = _WriteOnly;
}

function cl_int5_time(){
	this.data = getFieldValueString("int5_time");
	this.readWrite = _WriteOnly;
}

//** correct responses - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int5_correct_responses(){
	this.int0 = new cl_int5_correct_responses0();
}

function cl_int5_correct_responses0(){
	this.pattern = new cl_int5_correct_responses0_pattern();
}

function cl_int5_correct_responses0_pattern(){
	this.data = getFieldValueString("int5_correct_responses0_pattern");
	this.readWrite = _WriteOnly;
}


//** objectives - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int5_objectives(){
	this.int0 = new cl_int5_objectives0();
}

function cl_int5_objectives0(){
	this.id = new cl_int5_objectives0_id();
}

function cl_int5_objectives0_id(){
	this.data = getFieldValueString("int5_objectives0_id");
	this.readWrite = _WriteOnly;
}

//---------------------------------------------------------------------------------------


function cl_int6_id(){
	this.data = getFieldValueString("int6_id");
	this.readWrite = _WriteOnly;
}

function cl_int6_type(){
	this.data = getFieldValueString("int6_type");
	this.readWrite = _WriteOnly;
}

function cl_int6_student_response(){
	this.data = getFieldValueString("int6_student_response");
	this.readWrite = _WriteOnly;
}

function cl_int6_result(){
	this.data = getFieldValueString("int6_result");
	this.readWrite = _WriteOnly;
}

function cl_int6_weighting(){
	this.data = getFieldValueString("int6_weighting");
	this.readWrite = _WriteOnly;
}

function cl_int6_latency(){
	this.data = getFieldValueString("int6_latency");
	this.readWrite = _WriteOnly;
}

function cl_int6_time(){
	this.data = getFieldValueString("int6_time");
	this.readWrite = _WriteOnly;
}

//** correct responses - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int6_correct_responses(){
	this.int0 = new cl_int6_correct_responses0();
}

function cl_int6_correct_responses0(){
	this.pattern = new cl_int6_correct_responses0_pattern();
}

function cl_int6_correct_responses0_pattern(){
	this.data = getFieldValueString("int6_correct_responses0_pattern");
	this.readWrite = _WriteOnly;
}

//** objectives - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int6_objectives(){
	this.int0 = new cl_int6_objectives0();
}

function cl_int6_objectives0(){
	this.id = new cl_int6_objectives0_id();
}

function cl_int6_objectives0_id(){
	this.data = getFieldValueString("int6_objectives0_id"); + "..value";
	this.readWrite = _WriteOnly;
}


//---------------------------------------------------------------------------------------


function cl_int7_id(){
	this.data = getFieldValueString("int7_id");
	this.readWrite = _WriteOnly;
}

function cl_int7_type(){
	this.data = getFieldValueString("int7_type");
	this.readWrite = _WriteOnly;
}

function cl_int7_student_response(){
	this.data = getFieldValueString("int7_student_response");
	this.readWrite = _WriteOnly;
}

function cl_int7_result(){
	this.data = getFieldValueString("int7_result");
	this.readWrite = _WriteOnly;
}

function cl_int7_weighting(){
	this.data = getFieldValueString("int7_weighting");
	this.readWrite = _WriteOnly;
}

function cl_int7_latency(){
	this.data = getFieldValueString("int7_latency");
	this.readWrite = _WriteOnly;
}

function cl_int7_time(){
	this.data = getFieldValueString("int7_time");
	this.readWrite = _WriteOnly;
}

//** correct responses - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int7_correct_responses(){
	this.int0 = new cl_int7_correct_responses0();
}

function cl_int7_correct_responses0(){
	this.pattern = new cl_int7_correct_responses0_pattern();
}

function cl_int7_correct_responses0_pattern(){
	this.data = getFieldValueString("int7_correct_responses0_pattern");
	this.readWrite = _WriteOnly;
}


//** objectives - right now only one in lesson, but will need to add
//** if lesson calls more than 1 correct response
function cl_int7_objectives(){
	this.int0 = new cl_int7_objectives0();
}

function cl_int7_objectives0(){
	this.id = new cl_int7_objectives0_id();
}

function cl_int7_objectives0_id(){
	this.data = getFieldValueString("int7_objectives0_id");
	this.readWrite = _WriteOnly;
}



//***********************************************************************
// LMS data model
//***********************************************************************

function cl_core()
{
	this.lesson_status = new cl_lesson_status();
	this.score = new cl_score();
	//this.session_time = 30;
	this.student_name = new cl_student_name();
	this.student_id = new cl_student_id();
	this.session_time = new cl_session_time();
	
	//*** not scorm standard.  Our lms specific.
	this.lmsTime = new cl_lmsTime();
	
	//*** starwood 
	this.lesson_mode = new cl_lesson_mode();
	this.exit = new cl_exit();
}

function cl_int0()
{
   this.id = new cl_int0_id();
	this.type = new cl_int0_type();
	this.student_response = new cl_int0_student_response();
	this.result = new cl_int0_result();
	this.weighting = new cl_int0_weighting();
	this.latency = new cl_int0_latency();
	this.time = new cl_int0_time();
	this.correct_responses = new cl_int0_correct_responses();
	this.objectives = new cl_int0_objectives();
}

function cl_int1()
{
    this.id = new cl_int1_id();
	this.type = new cl_int1_type();
	this.student_response = new cl_int1_student_response();
	this.result = new cl_int1_result();
	this.weighting = new cl_int1_weighting();
	this.latency = new cl_int1_latency();
	this.time = new cl_int1_time();
	this.correct_responses = new cl_int1_correct_responses();
	this.objectives = new cl_int1_objectives();
}


function cl_int2()
{
   this.id = new cl_int2_id();
	this.type = new cl_int2_type();
	this.student_response = new cl_int2_student_response();
	this.result = new cl_int2_result();
	this.weighting = new cl_int2_weighting();
	this.latency = new cl_int2_latency();
	this.time = new cl_int2_time();
	this.correct_responses = new cl_int2_correct_responses();
	this.objectives = new cl_int2_objectives();
}

function cl_int3()
{
   this.id = new cl_int3_id();
	this.type = new cl_int3_type();
	this.student_response = new cl_int3_student_response();
	this.result = new cl_int3_result();
	this.weighting = new cl_int3_weighting();
	this.latency = new cl_int3_latency();
	this.time = new cl_int3_time();
	this.correct_responses = new cl_int3_correct_responses();
	this.objectives = new cl_int3_objectives();
}

function cl_int4()
{
   this.id = new cl_int4_id();
	this.type = new cl_int4_type();
	this.student_response = new cl_int4_student_response();
	this.result = new cl_int4_result();
	this.weighting = new cl_int4_weighting();
	this.latency = new cl_int4_latency();
	this.time = new cl_int4_time();
	this.correct_responses = new cl_int4_correct_responses();
	this.objectives = new cl_int4_objectives();
}

function cl_int5()
{
   this.id = new cl_int5_id();
	this.type = new cl_int5_type();
	this.student_response = new cl_int5_student_response();
	this.result = new cl_int5_result();
	this.weighting = new cl_int5_weighting();
	this.latency = new cl_int5_latency();
	this.time = new cl_int5_time();
	this.correct_responses = new cl_int5_correct_responses();
	this.objectives = new cl_int5_objectives();
}

function cl_int6()
{
   this.id = new cl_int6_id();
	this.type = new cl_int6_type();
	this.student_response = new cl_int6_student_response();
	this.result = new cl_int6_result();
	this.weighting = new cl_int6_weighting();
	this.latency = new cl_int6_latency();
	this.time = new cl_int6_time();
	this.correct_responses = new cl_int6_correct_responses();
	this.objectives = new cl_int6_objectives();
}

function cl_int7()
{
   this.id = new cl_int7_id();
	this.type = new cl_int7_type();
	this.student_response = new cl_int7_student_response();
	this.result = new cl_int7_result();
	this.weighting = new cl_int7_weighting();
	this.latency = new cl_int7_latency();
	this.time = new cl_int7_time();
	this.correct_responses = new cl_int7_correct_responses();
	this.objectives = new cl_int7_objectives();
}


function cl_interactions()
{
   this.int1 = new cl_int1();
	this.int2 = new cl_int2();
	this.int3 = new cl_int3();
	this.int4 = new cl_int4();
	this.int5 = new cl_int5();
	this.int6 = new cl_int6();
	this.int7 = new cl_int7();
	this._count = new cl_int_count();
}

function cl_cmi()
{
	this.suspend_data = new cl_suspend_data();
	this.core = new cl_core();
	
	//*** not scorm standard.  Our lms specific.
	this.end_of_sco = new cl_end_of_sco();
	
	//*** starwood
	this.interactions = new cl_interactions();  
}

function cl_score()
{
	this.raw = new cl_raw();
	
	//*** starwood
	this.max = new cl_max();
	this.max = new cl_min();
}

function cl_lms()
{
	this.LMSInitialize = LMSInitialize;
	this.LMSGetValue = LMSGetValue;
	this.LMSSetValue = LMSSetValue;
	this.LMSFinish = LMSFinish;
	this.LMSGetLastError = LMSGetLastError;
 	this.LMSGetErrorString = LMSGetErrorString;
 	this.LMSGetDiagnostic = LMSGetDiagnostic;
	this.LMSCommit = LMSCommit;
	
	try{
		this.dataSaveError = getFieldValueString("errCode");
	}
	catch(e){}
	
	this.command = getFieldValueString("commandText");
	this.submitForm = "parent.frames['lmsData'].document.forms['getForm']";
	this.cmi = new cl_cmi();
	this.lmsErrorManager = new clLMSErrorManager();
}

	
/*************************************************************************/
/****** LMS standard calls */
/*************************************************************************/

function LMSInitialize()
{
	_lmsTimeID = 0;
	
	if (this.lmsErrorManager != null)
		this.lmsErrorManager.SetCurrentErrorCode(_NoError);
	
	try {							
		var fraData = parent.frames["lmsData"];
		
		//alert ("in INITIALIZE: " + fraData.document.getElementById("int_count").value);
		var i = fraData.document.getElementById("int_max_count").value;		
		
		_int_max_count = i * 1;
	}
	catch(e){
		_int_max_count = _int_max_count;
	}
	
	return "true";
}


function LMSFinish()
{	
	if (this.lmsErrorManager != null)
		this.lmsErrorManager.SetCurrentErrorCode(_NoError);
		
	LMSCommit();
	clearForm();
	
	parent.frames['main'].location = "/menureturn.aspx";
	return "true";
}


function clearForm()
{
	var fraData = parent.frames["lmsData"];
	
	fraData.document.getElementById("rawScore").value = 0;
	fraData.document.getElementById("suspend").value = "";
	fraData.document.getElementById("scoStatus").value = "";
	fraData.document.getElementById("sessTime").value = "";
	fraData.document.getElementById("lmsTime").value = "";
	fraData.document.getElementById("totTime").value = "";
	//fraData.document.getElementById("commandText").value = "";
}


function LMSCommitInternal()
{
	
	if (this.lmsErrorManager != null)
		this.lmsErrorManager.SetCurrentErrorCode(_NoError);

		//alert ("in COMMIT INTERNAL");
		
		var fraData = parent.frames["lmsData"];
	
		//*** set the current number of interactions to be saved on form
		fraData.document.getElementById("int_current_count").value = _int_current_count;
		
		//***submit form to database. NOTE get back results in a hidden frame
		fraData.document.forms["getForm"].target = "recv";
		fraData.document.forms["getForm"].submit();
		
		// *** init number of current values on form to be saved to db
		_int_current_count = 0;
	
	return "true";
}


function LMSCommit()
{	
	if (this.lmsErrorManager != null)
		this.lmsErrorManager.SetCurrentErrorCode(_NoError);

		//alert ("in COMMIT");

		var fraData = parent.frames["lmsData"];
	
		//*** set the current number of interactions to be saved on form
		fraData.document.getElementById("int_current_count").value = _int_current_count;
		
		//***submit form to database
	   //alert ("COMMIT " + "curr count "  + _int_current_count + " db count " + fraData.document.getElementById("int_count").value);

		parent.frames["lmsData"].document.forms["getForm"].submit();
		
		// *** init number of current values on form to be saved to db
		_int_current_count = 0;
	
	return "true";
}


function LMSGetLastError() 
{  
		return this.lmsErrorManager.GetCurrentErrorCode(); 
}
	
function LMSGetErrorString(errorCode) 
{  
		return this.lmsErrorManager.GetErrorDescription(errorCode); 
}
	
function LMSGetDiagnostic(errorCode) 
{  
		return this.lmsErrorManager.GetErrorDiagnostic(errorCode); 
}


function LMSGetValue(param)
{
	//alert ("**** In Lms Get Data: *" + param);
	var s;
	
	if (this.lmsErrorManager != null){
		this.lmsErrorManager.SetCurrentErrorCode(_NoError);
		this.lmsErrorManager.currentNotDefinedErrorDescription = "";
	}

	//*** check if element is implemented
	try{
		s = eval("this." + param.toString() + ".readWrite");
	}
	catch(e){
		//*** not implemented error;
		if (this.lmsErrorManager != null)
			this.lmsErrorManager.SetCurrentErrorCode(_NotImplementedError);
		return false;
	}
	
	//*** check read/write
	if (s.toString() == _WriteOnly){
		//*** element is write only
		if (this.lmsErrorManager != null)
			this.lmsErrorManager.SetCurrentErrorCode(_ElementIsWriteOnly);
		return false;
	}
	
	s = eval("this." + param.toString() + ".data");
	
	//if (param.indexOf("_count",0) > 0)
		//alert ("**** In Lms Get Data: *" + param + "= " + eval(s.toString()) );

	return eval(s.toString());
}


function saveTotTime(value)
{
	//time in MS
	var totTimeMS = 0;
	var sessTimeMS = 0;
	var lastSessTimeMS = 0;
	var sumTimeMS = 0;
	
	//***scorm formatted time
	var scormTotTime = "";
	
	try {    
		var fraData = parent.frames["lmsData"];
		
    	_totTime = fraData.document.getElementById("totTime").value;
			
		//alert ("START session time : " + value + " tot time : " + _totTime);
    
		totTimeMS = ConvertCMITimeSpanToMS(_totTime);
		sessTimeMS = ConvertCMITimeSpanToMS(value);
		lastSessTimeMS = ConvertCMITimeSpanToMS(_lastSessTime);
		
		sumTimeMS = (totTimeMS + sessTimeMS) - lastSessTimeMS;
		//alert (totTimeMS + " " + sessTimeMS + " " + lastSessTimeMS + " ---- " + sumTimeMS);
		_lastSessTime = value;
				
		var scormTotTime = ConvertMilliSecondsToSCORMTime(sumTimeMS,true);
		fraData.document.getElementById("totTime").value = scormTotTime;
		
		//alert ("session Time: " + value + ", Tot Time: " + scormTotTime + ", sumTimeMS: " + sumTimeMS);
	}
	catch(e){
		//alert ("Time error : " + e.message);
	}	
}


function LMSSetValue(param, value)
{
	//alert ("**** In Lms Set Data: *" + param + "*\n" + value);
		
	//*** processTime
	if (param.indexOf("session_time", 0) > 0){
		saveTotTime(value);
	} 
	
	if (value.indexOf("'", 0) > 0){
		value = value.replace(/'/g,"\\'");
	}

	var fraData = parent.frames["lmsData"];
	
	//*** set the command type of the form
	var s = API.command;
	eval(s + "=" +  "'" + _setData + "'" );  
	
	//*** handle interractions
	if (param.indexOf("interactions",0) > 0){
	   
	  if (param.indexOf("objectives",0) > 0){
			//** save the lms parameter value for later trace
			s = "int" + _int_current_count.toString() + "_Obj0_param";
			s = getFieldValueString(s);
			eval(s + "=" + "'" +  param + "'" );
		}
		else if (param.indexOf("correct_responses",0) > 0) {
			//** save the lms parameter value for later trace
			s = "int" + _int_current_count.toString() + "_CA0_param";
			s = getFieldValueString(s);
			eval(s + "=" + "'" +  param + "'" );
		}
		else if (param.indexOf("id",0) > 0){
			
	   		//*** current interactions
	   		try{
			_int_current_count = _int_current_count + 1;
			//alert ("------LMS current int count: " + _int_current_count);
			
			//*** lesson interaction count
			fraData.document.getElementById("int_count").value = (parseInt(fraData.document.getElementById("int_count").value) * 1)  + (1 * 1);
			//alert ("------- database int count: " + fraData.document.getElementById("int_count").value);
		
			//*** check if interractions exceed values on form
			if (_int_current_count > _int_max_count){
				
		     	LMSCommitInternal();
			 	//alert ("curr: " + _int_current_count + " max : " + _int_max_count);
			 	_int_current_count = 1;	
			}
				//** save the lms parameter value for later trace
				s = "int" + _int_current_count.toString() + "_param";
				s = getFieldValueString(s);
				eval(s + "=" + "'" +  param + "'" );	
				//alert(s + "=" + "'" +  param + "'");
			}
			catch(e){
				//alert ("NEW ERROR: " + e.message);
			}		
		} 
		
			//alert("***************** " + _int_current_count + " : " + param);
			var paramList =  (param.split("."));
			paramList [2] = "int" + _int_current_count.toString();
			if (paramList.length > 4){
			    paramList[4] = "int0";
			}
			param = paramList.join(".");

			//alert ("**************NEW PARAM CHANGED* " + param);
	}
	
	
	//*** set the command type of the form
	s = API.command;
	eval(s + "=" +  "'" + _setData + "'" );  
	
	s = eval("this.dataSaveError");
	
	if (eval(s) == "1"){
		if (this.lmsErrorManager != null)
			this.lmsErrorManager.SetCurrentErrorCode(_DataSaveError);
		return false;
	}
	
	if (this.lmsErrorManager != null){
		this.lmsErrorManager.SetCurrentErrorCode(_NoError);
		this.lmsErrorManager.currentNotDefinedErrorDescription = "";
	}
	
	//*** check if element is implemented
	try{
		s = eval("this." + param.toString() + ".readWrite");
	}
	catch(e){
		//*** not implemented error;
		if (this.lmsErrorManager != null)
			this.lmsErrorManager.SetCurrentErrorCode(_NotImplementedError);
		return false;
	}
	
	//*** check read/write
	if (s.toString() == _ReadOnly){
		//*** element is read only
		if (this.lmsErrorManager != null)
			this.lmsErrorManager.SetCurrentErrorCode(_ElementIsReadOnly);
		return false;
	}

	try{
	
		s = eval("this." + param.toString() + ".data");
		
		//alert ("value on form: " + s);
		
		if (eval(s) != value.toString()){
			//alert("values different" + "\n*" + s + "*\n*" + "\n*" + eval(s) + "*\n*" + value.toString() + "*");
			
			//*** set the cached data 
			s = eval("this." + param + ".data");
			//alert(s + "=" +  "'" + value + "'" );
			eval(s + "=" +  "'" + value + "'" ); 
			
			//alert ("DEBUG: Data set on form: " + param);			
		}
	}
	catch(e){
		//alert ("ERROR: " + e.message + ': ' + value);
	}
	
	return "true";
}
	

//NOTE - using the time functions from Articulate	
function ConvertCMITimeSpanToMS(strTime)
{	
	var aryParts;
	var intHours;
	var intMinutes;
	var intSeconds;
	
	var intTotalMilliSeconds;
	
	//split the string into its parts
	aryParts = strTime.split(":");
	
	//make sure it's valid 
	//if (! IsValidCMITimeSpan(strTime)){
		//SetErrorInfo(SCORM_ERROR_GENERAL, "LMS ERROR - Invalid time span passed to ConvertSCORMTimeToMS, please contact technical support");
		//return 0;
	//}
	
	//separate the parts and multiply by the appropriate constant (3600000 = num milliseconds in an hour, etc)
	intHours   = aryParts[0];
	intMinutes = aryParts[1];
	intSeconds = aryParts[2];	//don't need to worry about milliseconds b/c they are expressed as fractions of a second
		
	intTotalMilliSeconds = (intHours * 3600000) + (intMinutes * 60000) + (intSeconds * 1000);
	
	//necessary because in JavaScript, some values for intSeconds (such as 2.01) will have a lot of decimal
	//places when multiplied by 1000. For instance, 2.01 turns into 2009.999999999999997.
	intTotalMilliSeconds = Math.round(intTotalMilliSeconds);
		
	return intTotalMilliSeconds;
}



//NOTE - using the time functions from Articulate	
function ConvertMilliSecondsToSCORMTime(intTotalMilliseconds, blnIncludeFraction)
{	
	// safeguard checked before conversion
	if (NaN(intTotalMilliseconds) | intTotalMilliseconds < 0) intTotalMilliseconds = 0;
		
	var intHours;
	var intintMinutes;
	var intSeconds;
	var intMilliseconds;
	var intHundredths;
	var strCMITimeSpan;
	
	try{
		if (blnIncludeFraction == null || blnIncludeFraction == undefined){
			blnIncludeFraction = true;
		}
		
		//extract time parts
		intMilliseconds = intTotalMilliseconds % 1000;
		intSeconds = ((intTotalMilliseconds - intMilliseconds) / 1000) % 60;
		intMinutes = ((intTotalMilliseconds - intMilliseconds - (intSeconds * 1000)) / 60000) % 60;
		intHours = (intTotalMilliseconds - intMilliseconds - (intSeconds * 1000) - (intMinutes * 60000)) / 3600000;
		
		/*
		deal with exceptional case when content used a huge amount of time and interpreted CMITimstamp 
		to allow a number of intMinutes and seconds greater than 60 i.e. 9999:99:99.99 instead of 9999:60:60:99
		note - this case is permissable under SCORM, but will be exceptionally rare
		*/
	
		if (intHours == 10000) 
		{
			intHours = 9999;
	
			intMinutes = (intTotalMilliseconds - (intHours * 3600000)) / 60000;
			if (intMinutes == 100) 
			{
				intMinutes = 99;
			}
			intMinutes = Math.floor(intMinutes);
			
			intSeconds = (intTotalMilliseconds - (intHours * 3600000) - (intMinutes * 60000)) / 1000;
			if (intSeconds == 100) 
			{
				intSeconds = 99;
			}
			intSeconds = Math.floor(intSeconds);
			intMilliseconds = (intTotalMilliseconds - (intHours * 3600000) - (intMinutes * 60000) - (intSeconds * 1000));
		}
		
	
		//drop the extra precision from the milliseconds
		intHundredths = Math.floor(intMilliseconds / 10);
	
		//put in padding 0's and concatinate to get the proper format
		strCMITimeSpan = ZeroPad(intHours, 4) + ":" + ZeroPad(intMinutes, 2) + ":" + ZeroPad(intSeconds, 2);
		
		if (blnIncludeFraction){
			strCMITimeSpan += "." + intHundredths;
		}
			
		//check for case where total milliseconds is greater than max supported by strCMITimeSpan
		if (intHours > 9999) 
		{
			strCMITimeSpan = "9999:99:99";
			
			if (blnIncludeFraction){
				strCMITimeSpan += ".99";
			}
		}
	}
	catch(e){
		//alert ("ERR: " + e.message);
	}
		
	return strCMITimeSpan;
}


function ZeroPad(intNum, intNumDigits)
{	
	var strTemp;
	var intLen;
	var i;
	
	strTemp = new String(intNum);
	intLen = strTemp.length;
	
	if (intLen > intNumDigits){
		strTemp = strTemp.substr(0,intNumDigits);
	}
	else{
		for (i=intLen; i<intNumDigits; i++){
			strTemp = "0" + strTemp;
		}
	}
	return strTemp;
}

	
//*** This function does not handle millisec
function formatDate(sec) 
{	
	var h = 0;
	var m = 0;
   var s = 0;
   var rem = 0;       
   var str = "";

   if (sec < 60) {
      s = sec;
	}
   else if (sec < 3600) {
		m = parseInt(sec/60);
		s = sec%60;
   }
   else {
		h = parseInt(sec / 3600);
		rem = sec%3600;
		m = parseInt(rem/60);
		s = rem%60;
   }
           
    h = h.toString();
    m = m.toString();
    s = s.toString();

	if (h == "0" && m == "0" && s == "0") {
		//do nothing
	}
	else {
		str = ((h.length==1 ? "0" : "") + h
			+ ":" + (m.length==1 ? "0" : "") + m 
		 	+ ":" + (s.length==1 ? "0" : "") + s);
   }   
	        
	return str;
}
	

//************************************************************************
//**** API 
/*************************************************************************/
var API = new cl_lms();	


	
/*************************************************************************/
/****** LMS non-standard calls */
/*************************************************************************/

function lmsGetData(launchPath,scoID,userID)
{	
	//alert ("IN GETDATA");
	
	//_childWin = childWin;
	
	//alert ("testing");
	//var s2 = ConvertCMITimeSpanToMS("10:20:30.5");
	//alert ("millisec : " + s2);
	//var s = ConvertMilliSecondsToSCORMTime(s2,true);
	//alert ("scorm time : " + s);
	

	_launchPath = launchPath.toString();
	
	var fraData = parent.frames["lmsData"];
	
	fraData.document.getElementById("userID").value = userID;
	fraData.document.getElementById("scoID").value = scoID;
	fraData.document.getElementById("commandText").value = _getData;
	fraData.document.forms["getForm"].submit();
	
	//*** wait for data from lms
	waitForData();
}

function waitForData()
{	
	if (eval(API.dataSaveError) == "2"){
		
		//**** NOTE: lmsTime Keeping not implemented. Session Time is accumulated
		
		var fraData = parent.frames["lmsData"];
		
		_totTime = fraData.document.getElementById("totTime").value;	
				
		parent.frames['main'].location.href = _launchPath.toString();
	}
	else{
		_TimeoutID = window.setTimeout("waitForData()", 1000);
	}
}

function savelmsTime()
{
	try {
		if (_lmsTimeID == 99 ) return; //*** lesson ended cancel timer
	
		// time in seconds since lesson launched
		var fraData = parent.frames["lmsData"];
		var d = new Date();
		var additionalTime = parseInt( (d.getTime() - _lmsStartTime ) / 1000); 
	
		var lmsTime = parseInt(_lmsOrigTime) + additionalTime; // cumulative time
		//*** debug alert ("origTime " + _lmsOrigTime + "\n\nadditional time " + additionalTime + "\n\ntotal time " + lmsTime);
	
		fraData.document.getElementById("saveLmsTime").value = 1;
		
		var s = API.LMSSetValue("cmi.core.lmsTime", lmsTime);
	
		fraData.document.getElementById("saveLmsTime").value = 0;
	
		_lmsTimeID = window.setTimeout("savelmsTime()", 1000);
	}
	catch (e){
		alert("savelmsTime : " + e.message);
	}
}



//************************************************************************
//************************************************************************
//**** following calls made from lesson only.  Just for testing below
/*************************************************************************/

function lesson_LMSGetValue()
{
	var s = "";  
	
	s = API.LMSGetValue("cmi.core.lesson_status");
	//alert ("Data from database: " + s);
	
	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(errCode);
      }

      //alert(errDescription);
   }
	
}

function lesson_LMSSetValue()
{
	var s;	
	
	//*** set the command type of the form
	s = API.command;
	eval(s + "=" +  "'" + _setData + "'" );   
	
	s = API.LMSSetValue("cmi.core.lesson_status", "passed");
	
	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(errCode);
         
      }
	  //alert(errDescription);
      return "false";
	}
	
	return "true";
}


