/*
   IMPORTANT: MAC & FIREFOX REQUIRES THIS FILE TO BE IN UTF-8 FORMAT
*/

/***************************                               ***********************************/
/***************************  INTERNAL FUNCTIONS AND DATA  ***********************************/
/***************************                               ***********************************/


/*
	Logs an interaction
*/
function addInteraction(id, type, description, correct, response, result, latency)
{
	var cnt = LMS.interactionCnt;
	var interaction = "cmi.interactions." + cnt;
	var weight = 1; // We normally don't weight our exercises
	
	if( API )
	{	   
		var rc = "";
		
		if( LMS.SCORMversion == "1.2" )
		{ 
			var now = SCORMtime( new Date() );

			rc = API.LMSSetValue( interaction + ".id",                          id       );
			checkResult( rc );

			rc = API.LMSSetValue( interaction + ".time",                        now      );
			checkResult( rc );

			rc = API.LMSSetValue( interaction + ".type",                        type     );
			checkResult( rc );

			// fill-in response field is limited to 255 characters
			if(type == "fill-in") correct = correct.slice(0,254);

			rc = API.LMSSetValue( interaction + ".correct_responses.0.pattern", correct  );
			checkResult( rc );

			rc = API.LMSSetValue( interaction + ".weighting",                   weight   );
			checkResult( rc );

			// fill-in response field is limited to 255 characters
			if(type == "fill-in") response = response.slice(0,254);

			rc = API.LMSSetValue( interaction + ".student_response",            response );
			checkResult( rc );

			rc = API.LMSSetValue( interaction + ".result",                      result   );
			checkResult( rc );

			rc = API.LMSSetValue( interaction + ".latency",                     latency  );
			checkResult( rc );

			document.Main.SetVariable ( "LMSReturnValue" , rc );

			API.LMSCommit("");
		}
		else if( LMS.SCORMversion == "2004" )
		{

			// -----------------------------
			// Convert latency
			// -----------------------------
			var timeArray = new Array(4);
			timeArray = latency.split(":");

			var hours = timeArray[0];
			var minutes = timeArray[1];
			var seconds = timeArray[2];
      
			latency = "PT" + hours + "H" + minutes + "M" + seconds + "S"; 


			// -----------------------------
			// Convert time
			// -----------------------------
			var now 	= new Date();
			var year 	= now.getYear();
			var month 	= now.getMonth();

			year = year % 100;
			year += (year < 38) ? 2000 : 1900;
     
			if ( month <= 9 )
			{
				month = "0" + month;
			}

			var day = now.getDay();

			if ( day <= 9 )
			{
				day = "0" + day;
			}

			now = year + "-" + month + "-" + day + "T" + SCORMtime( new Date() );


			// -----------------------------
			// Convert result
			// -----------------------------
			if ( result == "wrong" )
			{
				result = "incorrect";
			}


			rc = API.SetValue( interaction + ".id",                          id       );
			checkResult( rc );

			rc = API.SetValue( interaction + ".timestamp",                   now      );
			checkResult( rc );

			// Utilize the scorm 2004 support for long answers
			if(type == "fill-in") type = "long-fill-in";

			rc = API.SetValue( interaction + ".type",                        type     );
			checkResult( rc );

			//SCORM 2004 requires different delimiters: "," is replaced with "[,]", "." is replaced with "[.]"
			rc = API.SetValue( interaction + ".correct_responses.0.pattern", correct.split(',').join('[,]').split('.').join('[.]')  );
			checkResult( rc );

			rc = API.SetValue( interaction + ".weighting",                   weight   );
			checkResult( rc );

			description = description.slice(0,249);
			rc = API.SetValue( interaction + ".description",                 description );
			checkResult( rc );

			//SCORM 2004 requires different delimiters: "," is replaced with "[,]", "." is replaced with "[.]"
			rc = API.SetValue( interaction + ".learner_response",            response.split(',').join('[,]').split('.').join('[.]') );
			checkResult( rc );

			rc = API.SetValue( interaction + ".result",                      result   );
			checkResult( rc );

			rc = API.SetValue( interaction + ".latency",                     latency  );
			checkResult( rc );

			document.Main.SetVariable ( "LMSReturnValue" , rc );

			API.Commit("");
		}
	}
	else if(AICCApi)
	{
		AICCApi.addInteraction(id, type, correct, response, result, latency);
	}
	else
	{
		if( APIflag == "force" )
		{
			window.location.href = "../noAPI.html";
		}

	}

   LMS.interactionCnt++;
}
/*
	Checks the results from the API for validity
*/
function checkResult( rc )
{
    if( rc != "true" )
    {
        var errorCode = API.LMSGetLastError();
        /* 401 means not implemented */
        if(errorCode != "401")
        {
            if( APIflag == "force" )
            {
                window.location.href = "../noAPI.html";
            }
        }
        else
        {
            rc = "true";
        }
    }
}

/**************************                             **********************/
/**************************  PUBLIC FUNCTIONS AND DATA  **********************/
/**************************                             **********************/

function initialize()
{

	timeOfInit = new Date();

	if( API != null)
	{
		if( LMS.SCORMversion == "1.2" )
		{
			try
			{
				var result = API.LMSInitialize("");

				if( result != "true" )
				{
					// If not LMSInitalize was successful, exit with an error
					return( false );
				}

				lessonStatus = API.LMSGetValue( "cmi.core.lesson_status" );

				if( lessonStatus.length == 0 || (lessonStatus.length > 0 && lessonStatus.charAt(0) != "p" && lessonStatus.charAt(0) != "c" && lessonStatus.charAt(0) != "f" ))
				{
					API.LMSSetValue( "cmi.core.lesson_status", "incomplete" );
					API.LMSCommit("");
				}
			}
			catch( e )
			{
				return( false );
			}
		}
		else if( LMS.SCORMversion == "2004" )
		{			
			try
			{				
				var result = API.Initialize("");				
								
				if( result != "true" )
				{
					// If not LMSInitalize was successful, exit with an error
					return( false );
				}

				var completionStatus = String( API.GetValue( "cmi.completion_status" ) );	

				if( completionStatus.length == 0 || ( completionStatus.length > 0 && completionStatus.charAt(0) != "c" ) )
				{
					API.SetValue( "cmi.completion_status", "incomplete" );
					API.Commit("");
				}

			}
			catch( e )
			{
				return( false );
			}
		}
	}
	else if(AICCApi)
	{
		AICCApi.initialize(timeOfInit);
	}
	else
	{
		return( false );
	}
 
   return( true );
}

/*
	Logs the course as completed.
*/	
function courseCompleted()
{
	if( API )
	{
		if( LMS.SCORMversion == "1.2" )
		{		
			lessonStatus = API.LMSGetValue( "cmi.core.lesson_status" );

			if( lessonStatus.charAt(0) != "p" && lessonStatus.charAt(0) != "c" )
			{
				API.LMSSetValue( "cmi.core.lesson_status", "completed" );
				API.LMSCommit("");
			}
		}
		else if( LMS.SCORMversion == "2004" )
		{		
			completionStatus = String( API.GetValue( "cmi.completion_status" ) );

			if( completionStatus.length == 0 || ( completionStatus.length > 0 && completionStatus.charAt(0) != "c" ) )
			{				
				API.SetValue( "cmi.completion_status", "completed" );
				API.Commit("");
			}
		}
	}
	else if(AICCApi)
	{
		AICCApi.courseCompleted();
	}
}


/*
	Sets the completion status for the course
*/
function setCompletion( value )
{
	if( API )
	{
		if( LMS.SCORMversion == "1.2" )
		{
			lessonStatus = API.LMSGetValue( "cmi.core.lesson_status" );

			// Do not alter if user has completed or passed allready
			if( lessonStatus.charAt(0) != "p" && lessonStatus.charAt(0) != "c" )
			{
				API.LMSSetValue( "cmi.core.lesson_status", value );
				API.LMSCommit( "" );
			}
		}
		else if( LMS.SCORMversion == "2004" )
		{
			completionStatus 	= String( API.GetValue( "cmi.completion_status" ) );
			successStatus 		= String( API.GetValue( "cmi.success_status" ) );


			if( value == "passed" || value == "failed" )
			{
				// Do not alter if user has passed allready
				if( successStatus.length == 0 || ( successStatus.length > 0 && successStatus.charAt(0) != "p" ) )
				{
					API.SetValue( "cmi.completion_status", "completed" );
					API.SetValue( "cmi.success_status", value );
					API.Commit( "" );
				}
			}
			else if( value == "completed" || value == "incomplete" )
			{
				// Do not alter if user has completed allready
				if( completionStatus.length == 0 || ( completionStatus.length > 0 && completionStatus.charAt(0) != "c" ) )
				{

					API.SetValue( "cmi.completion_status", value );
					API.Commit( "" );
				}
			}
		}
	}
	else if(AICCApi)
	{
		AICCApi.setCompletion(value);
	}
}

/*
	Sets the score for the course
*/
function setScore( value )
{

	if( API )
	{
		if( LMS.SCORMversion == "1.2" )
		{
			lessonStatus = API.LMSGetValue( "cmi.core.lesson_status" );

			// Do not alter if user has completed or passed session
			if( lessonStatus.charAt(0) != "p" && lessonStatus.charAt(0) != "c" )
			{
				API.LMSSetValue( "cmi.core.score.raw", value );
				API.LMSSetValue( "cmi.core.score.min", 0 );
				API.LMSSetValue( "cmi.core.score.max", 100 );
				API.LMSCommit( "" );
			}
		}
		else if( LMS.SCORMversion == "2004" )
		{
			successStatus = String( API.GetValue( "cmi.success_status" ) );

			// Do not alter if user has completed or passed session
			if( successStatus.length == 0 || ( successStatus.length > 0 && successStatus.charAt(0) != "p" ) )
			{
				API.SetValue( "cmi.score.raw", value );
				API.SetValue( "cmi.score.min", 0 );
				API.SetValue( "cmi.score.max", 100 );
				API.SetValue( "cmi.score.scaled", value/100 );
				API.Commit( "" );
			}
		}
	}
	else if(AICCApi)
	{
		AICCApi.setScore(value);
	}

}

/*
	Sets the score and completion for the course
*/	
function setScoreAndCompletion( value, completion )
{
	if( API )
	{
		if( LMS.SCORMversion == "1.2" )
		{
			lessonStatus = API.LMSGetValue( "cmi.core.lesson_status" );

			// Do not alter if user has completed or passed session
			if( lessonStatus.charAt(0) != "p" && lessonStatus.charAt(0) != "c" )
			{
				API.LMSSetValue( "cmi.core.score.raw", value );
				API.LMSSetValue( "cmi.core.score.min", 0 );
				API.LMSSetValue( "cmi.core.score.max", 100 );
				API.LMSSetValue( "cmi.core.lesson_status", completion );
				API.LMSCommit( "" );
			}
		}
		else if( LMS.SCORMversion == "2004" )
		{
			successStatus 		= String( API.GetValue( "cmi.success_status" ) );

			// Do not alter if user has passed the session
			if( successStatus.length == 0 || ( successStatus.length > 0 && successStatus.charAt(0) != "p" ) )
			{
				if( completion == "passed" || completion == "failed" )
				{
					API.SetValue( "cmi.score.raw", value );
					API.SetValue( "cmi.score.min", 0 );
					API.SetValue( "cmi.score.max", 100 );
					API.SetValue( "cmi.score.scaled", value/100 );
					API.SetValue( "cmi.success_status", completion );
					API.SetValue( "cmi.completion_status", "completed" );
					API.Commit( "" );
				}
			}
		}		
	}
	else if(AICCApi)
	{
		AICCApi.setScoreAndCompletion(value, completion);
	}

}

/*
	Marks the current session as finished 
*/
function finish()
{
	if( API )
	{
        trackTime();
		
		if( LMS.SCORMversion == "1.2" )
		{		
        	API.LMSFinish("");
		}
		else if( LMS.SCORMversion == "2004" )
		{					
			API.Terminate("");
		}
	}	
	else if(AICCApi)
	{
		AICCApi.finish();
	}
}

/*
    Tracks time since start of course.
*/
function trackTime()
{
	if( API )
	{
		timeOfCompletion = new Date();
		var secondsElapsed = Math.floor( ( timeOfCompletion.getTime() - timeOfInit.getTime() ) / 1000 );

		
		if( LMS.SCORMversion == "1.2" )
		{		
			timeUsed = secsToTime( secondsElapsed );				

			API.LMSSetValue( "cmi.core.session_time", timeUsed );
			API.LMSCommit(""); 
		}
		else if( LMS.SCORMversion == "2004" )
		{					
			timeUsed = secsToTime2004( secondsElapsed );				

			API.SetValue( "cmi.session_time", timeUsed );
			API.Commit(""); 
		}
	}	
}

// Example:
// addMultipleChoice( "ex1", "my exercise", "a,b", "a,c","wrong","0:0:12" );
function addMultipleChoice(id,description,correct,response,result,latency)
{
    addInteraction(id,"choice",description,correct,response,result,latency);
}


// Example:
// addSlider( "ex1", "my exercise", "", "3","","0:0:12" );
// addSlider( "ex2", "choice 3", "choice 2","wrong","0:0:12" );
function addSlider(id,description,correct,response,result,latency)
{   addInteraction(id,"likert",description,correct,response,result,latency);}


// Example:
// addFreetext( "ex3", "my exercise", "Platon", "Platon","correct","0:0:12" );
function addFreetext(id,description,correct,response,result,latency)
{
   // Workaround implemented to support long parameters (>2kB)
   correct = document.Main.GetVariable("__FillInCorrect");
   response = document.Main.GetVariable("__FillInResponse");

   addInteraction(id,"fill-in",description,correct,response,result,latency);
}


// Example:
// addDragDrop( "ex4", "my exercise", "{a.b,e.f,c.b}", "a.b,e.f,c.f","wrong","0:0:12" );
function addDragDrop(id,description,correct,response,result,latency)
{   addInteraction(id,"matching",description,correct,response,result,latency);}

/*
	Saves suspend data for the course
*/
function suspendCourse( location, data )
{
	if( API )
	{
		if( LMS.SCORMversion == "1.2" )
		{
			var rc = API.LMSSetValue( "cmi.core.exit", "suspend" );
			checkResult( rc );

			var rc = API.LMSSetValue( "cmi.core.lesson_location", location );
			checkResult( rc );

			var rc = API.LMSSetValue( "cmi.suspend_data", data );
			checkResult( rc );
		}
		else if( LMS.SCORMversion == "2004" )
		{
			var rc = API.SetValue( "cmi.exit", "suspend" );
			checkResult( rc );

			var rc = API.SetValue( "cmi.location", location );
			checkResult( rc );

			var rc = API.SetValue( "cmi.suspend_data", data );
			checkResult( rc );
		}
	}
	else if(AICCApi)
	{
		AICCApi.suspendCourse(location, data);
	}
	else
	{
		//alert( "API not found. suspendCourse: " + location + ", " + data );
	}

}

