//Liste des bloques de données à transmettre par paquets
var CMI_BLOCK_NAME = ["cmi.suspend_data", "cmi.launch_data", "cmi.comments"];
var AICC_URL = ""; // url du serveur HACP
var AICC_SID = ""; // id de la session HACP
var sIsELW = ""; // s'il vient d'elw

var tracking = new Object();	//stockage des données de tracking
var isInitialized = false;
var isHACP = false;
var oneShotTracking = false;	//gestion des modes de tracking
var currentBlockIndex = 0; //Compteur de bloque de données en cours d'envoie
var canCloseWindow = false;

/*******************************************************************************
**
** Function doStart()
** Inputs:  sBgColor, sWidth, sHeight, sOneShotTracking
** Return:  None
**
** Description:
** 
**
*******************************************************************************/
function doStart(sBgColor, sWidth, sHeight, sOneShotTracking)
{
	oneShotTracking = (sOneShotTracking == "1");

	//Affiche et charge le player flash
	var sURL = "player.swf";

	splitURLArguments();
	// ouverture de session LMS
	var sInitialized = doLMSInitialize();
	switch (sInitialized)
	{
		case "1.2":
		case "2004":
			isInitialized = true;
			initTracking();

			//on ajoute les paramètres de tracking
			sURL += "?bAPIBased=1";
			sURL += "&bIsELW=" + sIsELW;
			sURL += "&scormversion=" + sInitialized;
			if (tracking["cmi.core.student_id"]) sURL += "&sStudentId=" + tracking["cmi.core.student_id"];
			if (tracking["cmi.core.student_name"]) sURL += "&sStudentName=" + tracking["cmi.core.student_name"];
			if (tracking["cmi.core.lesson_location"]) sURL += "&sLessonLocation=" + tracking["cmi.core.lesson_location"];
			if (tracking["cmi.core.credit"]) sURL += "&sCredit=" + tracking["cmi.core.credit"];
			if (tracking["cmi.core.lesson_status"]) sURL += "&sLessonStatus=" + tracking["cmi.core.lesson_status"];
			if (tracking["cmi.core.entry"]) sURL += "&sEntry=" + tracking["cmi.core.entry"];
			if (tracking["cmi.core.lesson_mode"]) sURL += "&sLessonMode=" + tracking["cmi.core.lesson_mode"];
			if (tracking["cmi.student_preference.audio"]) sURL += "&sStudentPreferenceAudio=" + tracking["cmi.student_preference.audio"];
			if (tracking["cmi.student_preference.language"]) sURL += "&sStudentPreferenceLanguage=" + tracking["cmi.student_preference.language"];
			if (tracking["cmi.student_preference.speed"]) sURL += "&sStudentPreferenceSpeed=" + tracking["cmi.student_preference.speed"];
			if (tracking["cmi.student_preference.text"]) sURL += "&sStudentPreferenceText=" + tracking["cmi.student_preference.text"];
			if (tracking["adl.nav.request_valid.continue"]) sURL += "&sNavRequestValidContinue=" + tracking["adl.nav.request_valid.continue"];
			if (tracking["adl.nav.request_valid.previous"]) sURL += "&sNavRequestValidPrevious=" + tracking["adl.nav.request_valid.previous"];

			// 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
			sURL += "&sSuspendData=big";
			currentBlockIndex = 0;

			//si le LMS supporte les interactions, la fonction doit retourner la liste des champs supportés (exple : "id,result,type,weighting")
			var interactions_children = doLMSGetValue("cmi.interactions._children").split(",");
			var bTrackInteractions = (interactions_children.length > 0);
			sURL += "&bTrackInteractions=" + bTrackInteractions; // flag "Track Interactions"
			break;
		
		case "hacp":
			//Prépare la chaine URL contenant les paramètres à destination du Flash
			//on récupère les paramètres passés à la page
			sURL += "?AICC_URL=" + AICC_URL;
			sURL += "&AICC_SID=" + AICC_SID;
			sURL += "&bTrackInteractions=1";
			isHACP = true;
			break;
	}

	// cadrage
	document.writeln('<table width="100%" height="100%" cellspacing="0" cellpadding="0"><tr><td valign="middle" align="center" id="mainCell" bgcolor="#FFFFFF">');
	
	// IExplorer
	document.writeln('<OBJECT classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" ID="player" width="' + sWidth + '" height="' + sHeight + '">');
	document.writeln('<param name="allowScriptAccess" value="sameDomain">');
	document.writeln('<param name="movie" value="' + sURL + ' ">');
	document.writeln('<param name="quality" value="high">');
	document.writeln('<param name="bgcolor" value="' + sBgColor + '">');		
	
	// Netscape
	document.writeln('<EMBED SRC="' + sURL + '" quality="high" bgcolor="' + sBgColor + '" width="' + sWidth + '" height="' + sHeight + '" name="player" align="middle" swLiveConnect="true" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer">');
	document.writeln('</EMBED></OBJECT>');
	document.writeln('</td></tr></table>');
}

/*******************************************************************************
**
** Function doQuit()
** Inputs:  None
** Return:  None
**
** Description:
** Close communication with LMS by calling the LMSFinish
** function which will be implemented by the LMS
**
*******************************************************************************/
function doQuit()
{
	if (isInitialized || isHACP)
	{
		//Si le tracking a lieu en une seule fois à la fin
		//C'est le moment pour l'envoyer au LMS
		if (oneShotTracking)
		{
			//Désactive le One Shot Tracking pour forcer l'envoi des données maintenant
			oneShotTracking = false;
			
			//Envoi l'ensemble des données stockées
			for (var str in tracking) doLMSSetValue(str, tracking[str]);
			
			//Force l'envoi du lesson_status en dernier pour être certain qu'il a au moins été mis à jour une fois (pour écraser le "not attempted")
			if (tracking["cmi.core.lesson_status"].toLowerCase().charAt(0) == "n") tracking["cmi.core.lesson_status"] = "incomplete"; 
			doLMSSetValue("cmi.core.lesson_status", tracking["cmi.core.lesson_status"]);
		}
		else
		{
			// envoie de toutes les données stockées
			if (tracking["cmi.core.score.raw"] != null) doLMSSetValue("cmi.core.score.raw", tracking["cmi.core.score.raw"]);
			if (tracking["cmi.core.session_time"] != null) doLMSSetValue("cmi.core.session_time", tracking["cmi.core.session_time"]);
			if (tracking["cmi.core.lesson_status"] != null) doLMSSetValue("cmi.core.lesson_status", tracking["cmi.core.lesson_status"]);
			if (tracking["cmi.core.lesson_location"] != null) doLMSSetValue("cmi.core.lesson_location", tracking["cmi.core.lesson_location"]);
			if (tracking["cmi.suspend_data"] != null) doLMSSetValue("cmi.suspend_data", tracking["cmi.suspend_data"]);
		}

		doLMSCommit();
		doLMSFinish();
		
		if (isInitialized) {
			canCloseWindow = true;
			isInitialized = false;
		}
		
		if (isHACP) {
			canCloseWindow = false;
			isHACP = false;
		}
	}
}

/*******************************************************************************
**
** Function doSendValue()
** Inputs:  name, value 
** Return:	none
**
** Description:
** Envoi et met à jour la valeur de sElement sur le LMS
** Dans le cas du "One Shot Tracking", on stocke simplement les données dans
** des variables : le véritable envoie vers le LMS se fera dans doTerminate()
**
** Le Flash envoi toutes les commandes au format de tracking SCORM 1.2
** la fonction doLMSSetValueSCORM13 permet de convertir l'envoi au format SCORM 1.3
** Et pour le cas de l'HACP, les données sont juste stockées dans des variables
** en vue d'être envoyées à la fin de la session, à la fermeture du contenu.
**
*******************************************************************************/
function doSendValue(name, value)
{
	var buffer = false;

	if (value == undefined || value == "undefined") return;

	switch (name)
	{
		case "score": name = "cmi.core.score.raw"; break;
		case "session_time": name = "cmi.core.session_time"; break;
		case "lesson_status": name = "cmi.core.lesson_status"; break;
		case "lesson_location": name = "cmi.core.lesson_location"; break;
		case "suspend_data": name = "cmi.suspend_data"; break;
		case "author_data": name = "cmi.core.author_data"; break;
	}
	
	//Stocke l'intéraction
	tracking[name] = value;
		
	if ( (isInitialized || isHACP) && !oneShotTracking)
	{
		buffer = doLMSSetValue(name, value);
	}

	return buffer;
}

/*******************************************************************************
**
** Function doFSCommand()
** Inputs:  command, args
** Return:  None
**
** Description:
** 
**
*******************************************************************************/
function doFSCommand(command, args)
{
	args = String(args);
	command = String(command);
	
	switch (command)
	{
		case "LMSSetValue": 
			var arrayOfArguments = args.split(";");
			var arg0 = arrayOfArguments.shift();
			var arg1 = arrayOfArguments.join(";");
			doSendValue(arg0, arg1);
			break;

		case "LMSCommit":
			doLMSCommit();
			break;

		case "UpdateSessionTime":
			tracking["cmi.core.session_time"] = args;
			break;

		case "sendQuit":
		case "LMSFinish":
			doQuit();
			if (canCloseWindow) exitWindow(2);
			break;

		case "OnOpenDocument":
			showDocument(args);
			break;

		case "OnGetSuspendDataBlock":
			sendSuspendDataToPlayer(args);
			break;
	}
}

function exitWindow(nCounter) {
	//if (exitIntervalID != undefined && exitIntervalID != null) clearInterval(exitIntervalID);
	var sHTML = "";
	
	if (nCounter == 10) {
		//Affiche un message indiquant à l'utilisateur qu'il peut fermer la fenêtre
		sHTML += 'Vous pouvez maintenant fermer la fen&ecirc;tre<br/>';
		sHTML += 'Now you can close the window<br/>';
		sHTML += 'Usted puede ahora cerrar la ventana<br/>';
		document.getElementById('mainCell').innerHTML = sHTML;
	} else {
		//Affiche un message pour faire patienter l'utilisateur
		var sWait = "";
		for (i=0; i<nCounter; i++) sWait += ".";
		sHTML += 'Veuillez patienter' + sWait + '<br/>';
		sHTML += 'Please wait' + sWait + '<br/>';
		sHTML += 'Por favor espere' + sWait + '<br/>';
		document.getElementById('mainCell').innerHTML = sHTML;
		
		setTimeout('exitWindow(' + String(nCounter + 1) + ')', 300);
	}

	//Si on est dans une popup et pas dans une frame, alors on ferme la fenêtre
	if (window == window.parent || window.parent == null || window.parent == undefined) {
		//On est sur d'être dans une popup, car il n'y a aucune frame supérieure
		window.close();
	}
}

/*******************************************************************************
**
** Function showDocument()
** Inputs:  document
** Return:  None
**
** Description:
**  Sous IE, il est pas possible de faire un window.open vers un document. Cette fonction permet de contourner ce problème en renvoyant vers une page qui va permettre d'afficher le document
**
*******************************************************************************/
function showDocument(document){
    var sUserAgent = navigator.userAgent.toLowerCase();
    if(sUserAgent.indexOf("msie") != -1){ //Si IE
		window.open("t_popup_elm_document.html?document=" + escape(document), 'edoceo_document',''); return false;
	}else{
		window.open(document, 'edoceo_document', ''); return false;
	}
        //IE: window.open("popup_open_document.html?document=" + args, 'edoceo_document',''); return false;
        //FF: window.open(args, 'edoceo_document',''); return false;
}

/*******************************************************************************
**
** Function setFlashVariable()
** Inputs:  name, value
** Return:  None
**
** Description:
** 
**
*******************************************************************************/
function setFlashVariable(name, value)
{
	var movie = null;
	var movieName = "player";

	if (window.document[movieName])
	{
		movie = window.document[movieName];
	}
	else
	{
		if (navigator.appName.indexOf("Microsoft Internet") == -1)
		{
			if (document.embeds && document.embeds[movieName]) movie = document.embeds[movieName]; 
		}
		else
		{
			movie = document.getElementById(movieName);
		}
	}

	if (movie != null) movie.SetVariable(name, value);
}


/*******************************************************************************
**
** Function setFlashVariable()
** Inputs:  sIndex
** Return:  None
**
** Description:
** on découpe le suspend_data en bloc de NB_MAX_SIZE_SUSPEND_DATA
** caractères pour contourner la limitation de IE
**
*******************************************************************************/
function sendSuspendDataToPlayer(sIndex)
{
	var sTrackingDataRef = CMI_BLOCK_NAME[currentBlockIndex];
	var sTrackingData = new String(tracking[sTrackingDataRef]);

	var nL = sTrackingData.length;
	var n = Math.floor((nL - 1) / NB_MAX_SIZE_SUSPEND_DATA) + 1;
	var nIndex = Number(sIndex);

	if (nIndex >= 0 && nIndex < n)
	{
		// on envoie le bloc nIndex
		setFlashVariable("sSuspendData", sTrackingData.substr(nIndex * NB_MAX_SIZE_SUSPEND_DATA, NB_MAX_SIZE_SUSPEND_DATA)); 
	}
	else
	{
		if (currentBlockIndex < CMI_BLOCK_NAME.length - 1)
		{
			currentBlockIndex++;
			// on signale le début de l'envoi d'une nouvelle variable
			setFlashVariable("sSuspendData", CMI_BLOCK_NAME[currentBlockIndex]); 
		}
		else
		{
			// on signale la fin de l'envoi
			setFlashVariable("sSuspendData", "stop"); 
		}
	}
}

/*******************************************************************************
**
** Function isValueInArray()
** Inputs:  aArray, sValue
** Return:  Un booléen indiquant si sValue se trouve dans aArray
**
** Description:
** Vérifie la présence de sValue dans aArray
**
*******************************************************************************/
function isValueInArray(aArray, sValue)
{
	var buffer = false;
	var i = 0;
	var n = aArray.length;
	while(i < n && !buffer)
	{
		buffer = (aArray[i] == sValue);
		i++;
	}
	
	return buffer; 
}

/*******************************************************************************
**
** Function splitURLArguments()
** Inputs:  
** Return:  
**
** Description:
** Découpe les arguments de l'url pour en extraire les params
**
*******************************************************************************/
function splitURLArguments()
{
	var win = findAICCwindow(window);
	
	var parameters = unescape(win.location.search.substring(1));
	var arrayOfParameters = parameters.split("&");
	
	var n = arrayOfParameters.length;
	for (var i = 0; i < n; i++)
	{
		var arrayOfArgument = arrayOfParameters[i].split("=");
		if (arrayOfArgument.length > 1)
		{
			var name = arrayOfArgument[0].toUpperCase();
			var value = arrayOfArgument[1];

			switch (name)
			{
				case "AICC_URL":
					AICC_URL = value;
					break;

				case "AICC_SID":
					AICC_SID = value;
					break;
					
				case "BISELW":
					sIsELW = value;
					break;
			}
		}
	}
}

/*******************************************************************************
**
** Function findAICCwindow()
** Inputs:  
** Return:  
**
** Description:
** renvoie la fenêtre qui contiendrait les paramètres d'URL
**
*******************************************************************************/
function findAICCwindow(win)
{
	// This is a simple mechanism to walk up a frameset tree to find the window with AICC parameters.  This
	// function should be modified, if the parameters are in a more complicated structure.
	if (win.location.search.toUpperCase().indexOf("AICC_URL") == -1)
	{
		if (win!=window.top)
		{
			win = (findAICCwindow(win.parent));
		}
	}
	return win;
}

