/*******************************************************************************
** initialisations
*******************************************************************************/


/*******************************************************************************
**
** Function doLMSInitializeSCORM12()
** Inputs:  none
** Return:  "true" si initialisation OK. Sinon "false"
**
** Description:
** Initialise l'API de tracking et signale au LMS le début de la session, le tout en SCORM 1.2
**
*******************************************************************************/
function doLMSInitializeSCORM12() {
	var buffer = "false";

	API = getAPI12(); // recherche de l'API
	if (API != null) {
		buffer = API.LMSInitialize(""); //Peut renvoyer une chaine ou un booleen ou rien du tout
		if (buffer == null) buffer = false;
		buffer = buffer.toString();
		buffer = buffer.toLowerCase();
		_sTrackingMode = "SCORM 1.2";
	}

	//trace("APIBased_LMSInitialize bAPIBased = " + bAPIBased);
	return buffer;
}

/*******************************************************************************
**
** Function doLMSFinishSCORM12()
** Inputs:  none
** Return:  le dernier code d'erreur
**
** Description:
** Envoi une dernière fois les données de tracking au LMS
** et met fin à la session de tracking en SCORM 1.2
**
*******************************************************************************/
function doLMSFinishSCORM12() {
	//trace("APIBased_LMSFinish");
	var buffer = false;
	clearInterval(nCommitIntervalID);

	// envoie de toutes les données stockées
	API.LMSSetValue("cmi.core.score.raw", tracking["cmi.core.score.raw"]);
	API.LMSSetValue("cmi.core.session_time", tracking["cmi.core.session_time"]);
	API.LMSSetValue("cmi.core.lesson_status", tracking["cmi.core.lesson_status"]);
	API.LMSSetValue("cmi.core.lesson_location", tracking["cmi.core.lesson_location"]);
	API.LMSSetValue("cmi.suspend_data", tracking["cmi.suspend_data"]);
	API.LMSSetValue("cmi.core.author_data", tracking["cmi.core.author_data"]);
	API.LMSCommit("");
	API.LMSFinish(""); // termine la session

	buffer = doLMSGetLastErrorSCORM12();
	
	return buffer;
}


/*******************************************************************************
**
** Function getLMSParametersSCORM12()
** Inputs:  none
** Return:  une chaine URL
**
** Description:
** Retourne des paramètres url_encoded avec des infos sur le tracking
**
*******************************************************************************/
function getLMSParametersSCORM12() {
	var buffer = "";	

	//Récupère les données de l'objet core (seulement les données accesiibles en lecture)
	var sCoreChildren = doLMSGetValueSCORM12("cmi.core._children", "");
	if (sCoreChildren.indexOf("student_id") > -1) tracking["cmi.core.student_id"] = doLMSGetValueSCORM12("cmi.core.student_id", "");
	if (sCoreChildren.indexOf("student_name") > -1) tracking["cmi.core.student_name"] = doLMSGetValueSCORM12("cmi.core.student_name", "");
	if (sCoreChildren.indexOf("lesson_location") > -1) tracking["cmi.core.lesson_location"] = doLMSGetValueSCORM12("cmi.core.lesson_location", "");
	if (sCoreChildren.indexOf("credit") > -1) tracking["cmi.core.credit"] = doLMSGetValueSCORM12("cmi.core.credit", "credit");
	if (sCoreChildren.indexOf("lesson_status") > -1) tracking["cmi.core.lesson_status"] = doLMSGetValueSCORM12("cmi.core.lesson_status", "not attempted");
	if (sCoreChildren.indexOf("entry") > -1) tracking["cmi.core.entry"] = doLMSGetValueSCORM12("cmi.core.entry", "");
	if (sCoreChildren.indexOf("lesson_mode") > -1) tracking["cmi.core.lesson_mode"] = doLMSGetValueSCORM12("cmi.core.lesson_mode", "normal");

	//Récupère le cmi.suspend_data
	tracking["cmi.suspend_data"] = doLMSGetValueSCORM12("cmi.suspend_data", "");

	//Récupère le cmi.launch_data
	tracking["cmi.launch_data"] = doLMSGetValueSCORM12("cmi.launch_data");

	//Récupère le cmi.student_preference
	var sStudentPreferenceChildren = doLMSGetValueSCORM12("cmi.student_preference._children", "");
	if (sStudentPreferenceChildren.indexOf("audio") > -1) tracking["cmi.student_preference.audio"] = doLMSGetValueSCORM12("cmi.student_preference.audio", 0);
	if (sStudentPreferenceChildren.indexOf("language") > -1) tracking["cmi.student_preference.language"] = doLMSGetValueSCORM12("cmi.student_preference.language", "");
	if (sStudentPreferenceChildren.indexOf("speed") > -1) tracking["cmi.student_preference.speed"] = doLMSGetValueSCORM12("cmi.student_preference.speed", 0);
	if (sStudentPreferenceChildren.indexOf("text") > -1) tracking["cmi.student_preference.text"] = doLMSGetValueSCORM12("cmi.student_preference.text", 0);
	
	//Initialise données en écriture seule
	tracking["cmi.core.session_time"] = "0000:00:00";
	tracking["cmi.core.exit"] = "";
	
	//Spécifique aux échanges avec ELW
	if (sCoreChildren.indexOf("edit_mode") > -1) tracking["cmi.core.edit_mode"] = doLMSGetValueSCORM12("cmi.core.edit_mode", "");

	//Prépare la chaine URL contenant les paramètres à destination du Flash
	buffer  = buffer + "&bAPIBased=1";
	buffer  = buffer + "&scormversion=1.2";
	if (tracking["cmi.core.student_id"]) buffer = buffer + "&sStudentId=" + tracking["cmi.core.student_id"];
	if (tracking["cmi.core.student_name"]) buffer = buffer + "&sStudentName=" + tracking["cmi.core.student_name"];
	if (tracking["cmi.core.lesson_location"]) buffer = buffer + "&sLessonLocation=" + tracking["cmi.core.lesson_location"];
	if (tracking["cmi.core.credit"]) buffer = buffer + "&sCredit=" + tracking["cmi.core.credit"];
	if (tracking["cmi.core.lesson_status"]) buffer = buffer + "&sLessonStatus=" + tracking["cmi.core.lesson_status"];
	if (tracking["cmi.core.entry"]) buffer = buffer + "&sEntry=" + tracking["cmi.core.entry"];
	if (tracking["cmi.core.lesson_mode"]) buffer = buffer + "&sLessonMode=" + tracking["cmi.core.lesson_mode"];
	if (tracking["cmi.core.edit_mode"]) buffer = buffer + "&sEditMode=" + tracking["cmi.core.edit_mode"];
	if (tracking["cmi.student_preference.audio"]) buffer = buffer + "&sStudentPreferenceAudio=" + tracking["cmi.student_preference.audio"];
	if (tracking["cmi.student_preference.language"]) buffer = buffer + "&sStudentPreferenceLanguage=" + tracking["cmi.student_preference.language"];
	if (tracking["cmi.student_preference.speed"]) buffer = buffer + "&sStudentPreferenceSpeed=" + tracking["cmi.student_preference.speed"];
	if (tracking["cmi.student_preference.text"]) buffer = buffer + "&sStudentPreferenceText=" + tracking["cmi.student_preference.text"];

	// historique trop long pour être envoyé directement au swf en parametre (limitation IE)
	// le swf doit demander au javascript de lui envoyer en plusieurs fois
	buffer  = buffer + "&sSuspendData=big";

	//si le LMS supporte les interactions, la fonction doit retourner la liste des champs supportés (exple : "id,result,type,weighting")
	aTrackInteractionsList = doLMSGetValueSCORM12("cmi.interactions._children").split(",");
	bTrackInteractions = (aTrackInteractionsList.length > 0);
	buffer  = buffer + "&bTrackInteractions=" + bTrackInteractions; // flag "Track Interactions"

	return buffer;
}


/*******************************************************************************
**
** Function doLMSSetValueSCORM12()
** Inputs:  sElement, sValue, bIsInteraction 
** Return:	none
**
** Description:
** Envoi et met à jour la valeur de sElement sur le LMS
**
*******************************************************************************/
function doLMSSetValueSCORM12(sElement, sValue, bIsInteraction) {
	if (!bIsInteraction) {
		API.LMSSetValue(sElement, sValue);
		
		//Prépare la validation de la transaction avec un délai d'une seconde
		clearInterval(nCommitIntervalID);
		nCommitIntervalID = setInterval(doLMSCommitSCORM12, 1000);

	} else { // interaction : on vérifie que l'interaction est supportée par le LMS
		// exple : cmi.interactions.1.correct_response_text
		if (isValueInArray(aTrackInteractionsList, getLastFieldName(sElement))) {
			API.LMSSetValue(sElement, sValue); // on n'envoie l'interaction que si elle est supportée par le LMS
			
			//Prépare la validation de la transaction avec un délai d'une seconde
			clearInterval(nCommitIntervalID);
			nCommitIntervalID = setInterval(doLMSCommitSCORM12, 1000);
		}
	}
}

/*******************************************************************************
**
** Function doLMSGetValueSCORM12()
** Inputs:  name - string representing a data model element 
**
** Return:  The value presently stored by the LMS for the data model element
**
** Description:
** Requests the value for the data model element
**
*******************************************************************************/
function doLMSGetValueSCORM12(name, defaultValue) {
	var buffer = API.LMSGetValue(name);
	if (buffer == undefined || buffer == null) buffer = defaultValue;

	return buffer;
}


/*******************************************************************************
**
** Function doLMSGetLastErrorSCORM12()
** Inputs:  none 
** Return:	Le dernier code d'erreur retourné par le LMS
**
** Description:
** Interroge le LMS pour obtenir le code d'erreur généré par la dernière commande
** envoyé au LMS
**
*******************************************************************************/
function doLMSGetLastErrorSCORM12() {
	return API.LMSGetLastError();
}


/*******************************************************************************
**
** Function doLMSCommitSCORM12()
** Inputs:  none 
** Return:	none
**
** Description:
** Cloture la transaction en validant les commandes envoyées au LMS
**
*******************************************************************************/
function doLMSCommitSCORM12() {
	clearInterval(nCommitIntervalID);
	API.LMSCommit(""); //on commit pour être sûr que le LMS stocke la valeur (certains LMS ont besoin de ceci pour réellement stocker la valeur)
}


/*******************************************************************************
**
** Function findAPI12(win)
** Inputs:  win - a Window Object
** Return:  If an API object is found, it's returned, otherwise null is returned
**
** Description:
** This function looks for an object named API in parent and opener windows
**
*******************************************************************************/
function findAPI12(win) {
   while ((win.API == null) && (win.parent != null) && (win.parent != win))
   {
      nFindAPITries++;
      // Note: 500 is a number that comes from the new IEEE API standard.
      //       See rational in ticket number 3547
      if (nFindAPITries > 500) {
         if (DEBUG_MODE) alert("Error finding API -- too deeply nested.");
         return null;
      }
      win = win.parent;
   }
   return win.API;
}
/*******************************************************************************
**
** Function getAPI12()
** Inputs:  none
** Return:  If an API object is found, it's returned, otherwise null is returned
**
** Description:
** This function looks for an object named API, first in the current window's
** frame hierarchy and then, if necessary, in the current window's opener window
** hierarchy (if there is an opener window).
**
*******************************************************************************/
function getAPI12() {
   theAPI = findAPI12(window);
   
   // Avec frame
   if ((theAPI == null) && (window.parent.opener != null) && (typeof(window.parent.opener) != "undefined")) {
	   theAPI = findAPI12(window.parent.opener);
	   if ((theAPI == null) && (window.parent.opener.opener != null) && (typeof(window.parent.opener.opener) != "undefined")) {
		   theAPI = findAPI12(window.parent.opener.opener);
	   }
   }

   if (theAPI == null)   {
      if (DEBUG_MODE) alert("Unable to find an API adapter");
   }

   return theAPI;
}
