
// 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 cl_suspend_data(){
	this.data = "parent.frames['lmsData'].document.all.getForm.suspend.value";
	this.readWrite = _ReadWrite;
}

function cl_lesson_status(){
	this.data = "parent.frames['lmsData'].document.all.getForm.scoStatus.value";
	this.readWrite = _ReadWrite;
}

function cl_student_name(){
	this.data = "parent.frames['lmsData'].document.all.getForm.userName.value";
	this.readWrite = _ReadOnly;
}

function cl_student_id(){
	this.data = "parent.frames['lmsData'].document.all.getForm.stuID.value";
	this.readWrite = _ReadOnly;
}

function cl_session_time(){
	this.data = "parent.frames['lmsData'].document.all.getForm.sessTime.value";
	this.readWrite = _WriteOnly;
}

function cl_lmsTime(){
	this.data = "parent.frames['lmsData'].document.all.getForm.lmsTime.value";
	this.readWrite = _ReadWrite;
}

function cl_total_time(){
	this.data = "parent.frames['lmsData'].document.all.getForm.totalTime.value";
	this.readWrite = _ReadOnly;
}

function cl_raw(){
	this.data = "parent.frames['lmsData'].document.all.getForm.rawScore.value";
	this.readWrite = _ReadWrite;
}

function cl_end_of_sco(){
	this.data = "parent.frames['lmsData'].document.all.getForm.endofsco.value";
	this.readWrite = _ReadWrite;
}

//**************************************************************************************************

//*** startwood elements



function cl_exit(){
	this.data = "parent.frames['lmsData'].document.all.getForm.exit.value";
	this.readWrite = _ReadWrite;
}

function cl_max(){
	this.data = "parent.frames['lmsData'].document.all.getForm.maxScore.value";
	this.readWrite = _ReadWrite;
}

function cl_min(){
	this.data = "parent.frames['lmsData'].document.all.getForm.minScore.value";
	this.readWrite = _ReadWrite;
}

function cl_int_count(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int_count.value";
	this.readWrite = _ReadOnly;
}

function cl_lesson_mode(){
	this.data = "parent.frames['lmsData'].document.all.getForm.lesson_mode.value";
	this.readWrite = _ReadOnly;
}


//----------------------------------------------------------------------------------
function cl_int0_id(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int0_id.value";
	this.readWrite = _WriteOnly;
}

function cl_int0_type(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int0_type.value";
	this.readWrite = _WriteOnly;
}

function cl_int0_student_response(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int0_student_response.value";
	this.readWrite = _WriteOnly;
}

function cl_int0_result(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int0_result.value";
	this.readWrite = _WriteOnly;
}

function cl_int0_weighting(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int0_weighting.value";
	this.readWrite = _WriteOnly;
}

function cl_int0_latency(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int0_latency.value";
	this.readWrite = _WriteOnly;
}

function cl_int0_time(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int0_time.value";
	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();
	
	//this.int1 = new cl_int0_correct_responses2();
	//this.int2 = new cl_int0_correct_responses3();
	
}
function cl_int0_correct_responses0(){
	this.id = new cl_int0_correct_responses0_id();
	
	//** 
	//this.<other elements>
}
function cl_int0_correct_responses0_id(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int0_correct_responses0_id.value";
	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 = "parent.frames['lmsData'].document.all.getForm.int0_objectives0_id.value";
	this.readWrite = _WriteOnly;
}

//----------------------------------------------------------------------------------
function cl_int1_id(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int1_id.value";
	this.readWrite = _WriteOnly;
}

function cl_int1_type(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int1_type.value";
	this.readWrite = _WriteOnly;
}

function cl_int1_student_response(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int1_student_response.value";
	this.readWrite = _WriteOnly;
}

function cl_int1_result(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int1_result.value";
	this.readWrite = _WriteOnly;
}

function cl_int1_weighting(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int1_weighting.value";
	this.readWrite = _WriteOnly;
}

function cl_int1_latency(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int1_latency.value";
	this.readWrite = _WriteOnly;
}

function cl_int1_time(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int1_time.value";
	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();
	//this.int1 = new cl_int1_correct_responses2();
	//this.int2 = new cl_int1_correct_responses3();
}

function cl_int1_correct_responses0(){
	this.pattern = new cl_int1_correct_responses0_pattern();
	
	//** 
	//this.<other elements>
}

function cl_int1_correct_responses0_pattern(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int1_correct_responses0_pattern.value";
	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 = "parent.frames['lmsData'].document.all.getForm.int1_objectives0_id.value";
	this.readWrite = _WriteOnly;
}



//---------------------------------------------------------------------------------------

function cl_int2_id(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int2_id.value";
	this.readWrite = _WriteOnly;
}

function cl_int2_type(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int2_type.value";
	this.readWrite = _WriteOnly;
}

function cl_int2_student_response(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int2_student_response.value";
	this.readWrite = _WriteOnly;
}

function cl_int2_result(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int2_result.value";
	this.readWrite = _WriteOnly;
}

function cl_int2_weighting(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int2_weighting.value";
	this.readWrite = _WriteOnly;
}

function cl_int2_latency(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int2_latency.value";
	this.readWrite = _WriteOnly;
}

function cl_int2_time(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int2_time.value";
	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();
	//this.int1 = new cl_int2_correct_responses2();
	//this.int2 = new cl_int2_correct_responses3();
}

function cl_int2_correct_responses0(){
	this.pattern = new cl_int2_correct_responses0_pattern();
	
	//** 
	//this.<other elements>
}

function cl_int2_correct_responses0_pattern(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int2_correct_responses0_pattern.value";
	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 = "parent.frames['lmsData'].document.all.getForm.int2_objectives0_id.value";
	this.readWrite = _WriteOnly;
}


//---------------------------------------------------------------------------------------


function cl_int3_id(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int3_id.value";
	this.readWrite = _WriteOnly;
}

function cl_int3_type(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int3_type.value";
	this.readWrite = _WriteOnly;
}

function cl_int3_student_response(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int3_student_response.value";
	this.readWrite = _WriteOnly;
}

function cl_int3_result(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int3_result.value";
	this.readWrite = _WriteOnly;
}

function cl_int3_weighting(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int3_weighting.value";
	this.readWrite = _WriteOnly;
}

function cl_int3_latency(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int3_latency.value";
	this.readWrite = _WriteOnly;
}

function cl_int3_time(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int3_time.value";
	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();
	//this.int1 = new cl_int3_correct_responses2();
	//this.int2 = new cl_int3_correct_responses3();
}

function cl_int3_correct_responses0(){
	this.pattern = new cl_int3_correct_responses0_pattern();
	
	//** 
	//this.<other elements>
}

function cl_int3_correct_responses0_pattern(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int3_correct_responses0_pattern.value";
	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 = "parent.frames['lmsData'].document.all.getForm.int3_objectives0_id.value";
	this.readWrite = _WriteOnly;
}


//---------------------------------------------------------------------------------------


function cl_int4_id(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int4_id.value";
	this.readWrite = _WriteOnly;
}

function cl_int4_type(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int4_type.value";
	this.readWrite = _WriteOnly;
}

function cl_int4_student_response(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int4_student_response.value";
	this.readWrite = _WriteOnly;
}

function cl_int4_result(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int4_result.value";
	this.readWrite = _WriteOnly;
}

function cl_int4_weighting(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int4_weighting.value";
	this.readWrite = _WriteOnly;
}

function cl_int4_latency(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int4_latency.value";
	this.readWrite = _WriteOnly;
}

function cl_int4_time(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int4_time.value";
	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();
	//this.int1 = new cl_int4_correct_responses2();
	//this.int2 = new cl_int4_correct_responses3();
}

function cl_int4_correct_responses0(){
	this.pattern = new cl_int4_correct_responses0_pattern();
	
	//** 
	//this.<other elements>
}

function cl_int4_correct_responses0_pattern(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int4_correct_responses0_pattern.value";
	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 = "parent.frames['lmsData'].document.all.getForm.int4_objectives0_id.value";
	this.readWrite = _WriteOnly;
}


//---------------------------------------------------------------------------------------


function cl_int5_id(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int5_id.value";
	this.readWrite = _WriteOnly;
}

function cl_int5_type(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int5_type.value";
	this.readWrite = _WriteOnly;
}

function cl_int5_student_response(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int5_student_response.value";
	this.readWrite = _WriteOnly;
}

function cl_int5_result(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int5_result.value";
	this.readWrite = _WriteOnly;
}

function cl_int5_weighting(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int5_weighting.value";
	this.readWrite = _WriteOnly;
}

function cl_int5_latency(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int5_latency.value";
	this.readWrite = _WriteOnly;
}

function cl_int5_time(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int5_time.value";
	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();
	//this.int1 = new cl_int5_correct_responses2();
	//this.int2 = new cl_int5_correct_responses3();
}

function cl_int5_correct_responses0(){
	this.pattern = new cl_int5_correct_responses0_pattern();
	
	//** 
	//this.<other elements>
}

function cl_int5_correct_responses0_pattern(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int5_correct_responses0_pattern.value";
	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 = "parent.frames['lmsData'].document.all.getForm.int5_objectives0_id.value";
	this.readWrite = _WriteOnly;
}

//---------------------------------------------------------------------------------------


function cl_int6_id(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int6_id.value";
	this.readWrite = _WriteOnly;
}

function cl_int6_type(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int6_type.value";
	this.readWrite = _WriteOnly;
}

function cl_int6_student_response(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int6_student_response.value";
	this.readWrite = _WriteOnly;
}

function cl_int6_result(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int6_result.value";
	this.readWrite = _WriteOnly;
}

function cl_int6_weighting(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int6_weighting.value";
	this.readWrite = _WriteOnly;
}

function cl_int6_latency(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int6_latency.value";
	this.readWrite = _WriteOnly;
}

function cl_int6_time(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int6_time.value";
	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();
	//this.int1 = new cl_int6_correct_responses2();
	//this.int2 = new cl_int6_correct_responses3();
}

function cl_int6_correct_responses0(){
	this.pattern = new cl_int6_correct_responses0_pattern();
	
	//** 
	//this.<other elements>
}

function cl_int6_correct_responses0_pattern(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int6_correct_responses0_pattern.value";
	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 = "parent.frames['lmsData'].document.all.getForm.int6_objectives0_id.value";
	this.readWrite = _WriteOnly;
}


//---------------------------------------------------------------------------------------


function cl_int7_id(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int7_id.value";
	this.readWrite = _WriteOnly;
}

function cl_int7_type(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int7_type.value";
	this.readWrite = _WriteOnly;
}

function cl_int7_student_response(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int7_student_response.value";
	this.readWrite = _WriteOnly;
}

function cl_int7_result(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int7_result.value";
	this.readWrite = _WriteOnly;
}

function cl_int7_weighting(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int7_weighting.value";
	this.readWrite = _WriteOnly;
}

function cl_int7_latency(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int7_latency.value";
	this.readWrite = _WriteOnly;
}

function cl_int7_time(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int7_time.value";
	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();
	//this.int1 = new cl_int7_correct_responses2();
	//this.int2 = new cl_int7_correct_responses3();
}

function cl_int7_correct_responses0(){
	this.pattern = new cl_int7_correct_responses0_pattern();
	
	//** 
	//this.<other elements>
}

function cl_int7_correct_responses0_pattern(){
	this.data = "parent.frames['lmsData'].document.all.getForm.int7_correct_responses0_pattern.value";
	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 = "parent.frames['lmsData'].document.all.getForm.int7_objectives0_id.value";
	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 = "parent.frames['lmsData'].document.all.getForm.errCode.value";
	}
	catch(e){
	}
	this.command = "parent.frames['lmsData'].document.all.getForm.commandText.value";
	this.submitForm = "parent.frames['lmsData'].document.all.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 i = parent.frames['lmsData'].document.all.getForm.int_max_count.value;
		//alert ("in INITIALIZE: " + parent.frames['lmsData'].document.all.getForm.int_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()
{
	parent.frames['lmsData'].document.all.getForm.rawScore.value = 0;
	parent.frames['lmsData'].document.all.getForm.suspend.value = "";
	parent.frames['lmsData'].document.all.getForm.scoStatus.value = "";
	parent.frames['lmsData'].document.all.getForm.sessTime.value = "";
	parent.frames['lmsData'].document.all.getForm.lmsTime.value = "";
	parent.frames['lmsData'].document.all.getForm.totTime.value = "";
	//parent.frames['lmsData'].document.all.getForm.commandText.value = "";
}


function LMSCommitInternal()
{
	
	if (this.lmsErrorManager != null)
		this.lmsErrorManager.SetCurrentErrorCode(_NoError);

		//alert ("in COMMIT INTERNAL");
	
		//*** set the current number of interactions to be saved on form
		parent.frames['lmsData'].document.all.getForm.int_current_count.value = _int_current_count;
		
		//***submit form to database. NOTE get back results in a hidden frame
		parent.frames['lmsData'].document.all.getForm.target = "recv";
		parent.frames['lmsData'].document.all.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");
	
		//*** set the current number of interactions to be saved on form
		parent.frames['lmsData'].document.all.getForm.int_current_count.value = _int_current_count;
		
		//***submit form to database
	    //alert ("COMMIT " + "curr count "  + _int_current_count + " db count " + parent.frames['lmsData'].document.all.getForm.int_count.value);

		parent.frames['lmsData'].document.all.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){
	var s;

	//alert ("**** In Lms Get Data: *" + param);
	
	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{
    
    _totTime = parent.frames['lmsData'].document.all.getForm.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);
	parent.frames['lmsData'].document.all.getForm.totTime.value = scormTotTime;
	
//alert ("session Time: " + value + " Tot Time: " + scormTotTime);
	}
	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,"\\'");
	}

	//*** 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 = "parent.frames['lmsData'].document.all.getForm.int" + _int_current_count.toString() + "_Obj0_param.value";
			eval(s + "=" + "'" +  param + "'" );
		}
		else if (param.indexOf("correct_responses",0) > 0) {
			//** save the lms parameter value for later trace
			s = "parent.frames['lmsData'].document.all.getForm.int" + _int_current_count.toString() + "_CA0_param.value";
			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
			parent.frames['lmsData'].document.all.getForm.int_count.value = (parseInt(parent.frames['lmsData'].document.all.getForm.int_count.value) * 1)  + (1 * 1);
			//alert ("------- database int count: " ,parent.frames['lmsData'].document.all.getForm.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 = "parent.frames['lmsData'].document.all.getForm.int" + _int_current_count.toString() + "_param.value";
				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){
	
	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){
	var s;
	//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();
	
	parent.frames['lmsData'].document.all.getForm.userID.value = userID;
	parent.frames['lmsData'].document.all.getForm.scoID.value = scoID;
	parent.frames['lmsData'].document.all.getForm.commandText.value = _getData;
	parent.frames['lmsData'].document.all.getForm.submit();
	
	//*** wait for data from lms
	waitForData();
}

function waitForData(){
	
	if (eval(API.dataSaveError) == "2"){
	
		//**** NOTE: lms Time Keeping not implemented. Session Time is accumulated
			var d = new Date();
			//parent.frames['lmsData'].document.all.getForm.totTime.value = "00:10:00.0";
			_totTime = parent.frames['lmsData'].document.all.getForm.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 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);
	
		parent.frames['lmsData'].document.all.getForm.saveLmsTime.value = 1;
		
		var s = API.LMSSetValue("cmi.core.lmsTime", lmsTime);
	
		parent.frames['lmsData'].document.all.getForm.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";
}

	
