// The variable interface_type is stored in file config.js
// If  LMS with SCORM:     interface_type = 1 
// If  no LMS:             interface_type =-1 

//SCORM Variables
var debug=true;  // For debuging the communication with SCORM 
var debug_text= new Array();
debug_text['e']="A connection problem occurred. Please close the session and restart it.\nIf the error appears again, please send error code to office@sts.ch.\nThanks for your help !\n\nError code:\n";
debug_text['f']="Un problème de connexion est apparu. Veuillez s.v.p. fermer le navigateur et le redémarrer.\nSi ce message d'erreur réapparaît, nous vous prions d'envoyer le code d'erreur à office@sts.ch.\nMerci de votre aide !\n\nCode d'erreur:\n";
debug_text['g']="Eine Verbindungsstörung ist aufgetreten. Bitte schliessen Sie den Browser und starten Sie neu.\nWenn diese Fehlermeldung erneut auftreten sollte, schicken Sie bitte den Fehlercode an office@sts.ch.\nDanke für Ihre Unterstützung!\n\nFehlercode:\n";
debug_text['s']="A connection problem occurred. Please close the session and restart it.\nIf the error appears again, please send error code to office@sts.ch.\nThanks for your help !\n\nError code:\n";
debug_text['v']="A connection problem occurred. Please close the session and restart it.\nIf the error appears again, please send error code to office@sts.ch.\nThanks for your help !\n\nError code:\n";
debug_text['j']="A connection problem occurred. Please close the session and restart it.\nIf the error appears again, please send error code to office@sts.ch.\nThanks for your help !\n\nError code:\n";
var API=null;		
var API_initialized = false;
var connectionError = false;

//Course Variables
var time_done=0;
var m_score=80.0/100.0;
var elnum=1;
var page=home;
var mastery_score="80";

//var suspend_data="x-am 3[BB][H]0;4;;50;1187834824;873;45;50;34;27#0;4;;50;1186727106;1719;45;50;25;13#0;4;;50;1185871314;1476;43;50;37;1#0;4;;200;1184138621;6203;179;200;158;16#0;2;L;5;1183533883;311;5;5;4;1#0;2;L;11;1183215988;660;9;11;8;6#0;1;7;63;1183215521;2770;52;63;57;29#0;2;L;32;1183114082;1650;32;32;19;18#0;1;p2;190;1183112513;4818;158;190;132;98#0;2;L;12;1183034551;736;12;12;6;9#0;1;6;66;1183033991;2209;54;66;20;22#0;2;L;8;1183017421;510;7;8;2;7#0;1;5;54;1183017152;1389;46;54;11;22#0;2;L;14;1182968484;757;14;14;10;1#0;1;4;98;1182967539;1563;84;98;15;21#0;2;L;11;1182938465;608;10;11;6;10#0;1;3;52;1182937911;1352;41;52;14;16#0;2;L;4;1182928050;249;4;4;1;2#0;1;1;84;1182927889;3641;80;84;1;52#0;2;L;14;1182865211;834;14;14;2;6#0;1;p5;53;1182864607;747;39;53;17;44#0;2;L;46;1182852883;2467;45;46;10;38#0;1;p4;161;1182850502;1665;115;161;153;55#0;2;L;35;1182591656;2025;34;35;24;31#0;1;p3;210;1182589220;4662;175;210;51;36#0;2;L;7;1182500262;417;7;7;6;3#0;1;p6;60;1182499942;1857;53;60;53;34#0;2;L;30;1182446052;1686;29;30;17;6#0;1;10;91;1182444457;1051;61;91;18;43#0;2;L;18;1182328864;1069;18;18;15;4#0;1;9;68;1182327703;281;50;68;38;21#0;2;L;14;1182244009;869;14;14;9;4#0;1;8;48;1182243516;1242;34;48;30;5#0;2;L;9;1182233888;580;9;9;2;3#0;2;L;20;1182233586;785;11;20;2;5#0;1;7;63;1182075304;722;43;63;19;56#0;2;L;32;1181998883;1813;30;32;17;23#0;1;6;66;1181996753;0;34;66;50;45#0;2;L;2;1181843463;133;2;2;1;1#0;2;L;22;1181843277;1089;20;22;7;9#0;1;5;54;1181841751;802;32;54;49;39#0;2;L;4;1181738621;257;4;4;3;2#0;2;L;42;1181738442;2121;38;42;22;28#0;1;4;98;1181729151;449;56;98;29;67#0;2;L;3;1181638344;189;3;3;1;2#0;2;L;30;1181638252;1482;27;30;19;4#0;1;3;52;1181636272;658;22;52;23;10#0;2;L;7;1181202204;437;7;7;4;6#0;2;L;27;1181201971;1487;20;27;10;9#0;2;L;41;1181200391;1447;14;41;17;30#0;1;2;124;1181147172;2704;83;124;30;117#0;2;L;1;1180796743;51;1;1;1;1#0;2;L;12;1180796676;724;11;12;1;8#0;2;L;52;1180796250;2553;40;52;32;49#0;2;L;87;1180792516;2051;35;87;73;43#0;2;L;20;1180614707;1039;18;20;12;19#0;1;p1;74;1180606997;1937;54;74;61;69#0;2;L;32;1180597286;1313;30;32;11;27#0;1;1;80;1180532302;933;48;80;62;64#[Q]11111¿1111111=11111111111=111111111=1111qqq111111q111qq11q1Áq1q1111q1q11q111qq11111111111]11q111111Â11q1¿q111111q11111q1q1111q1]111=11=1111=111111111q1=11111111q111111qqqqq111q1111111=111q11111q111111111Â11q1q1111=111q11111q1}11111q1qq1111qq1q111111111q1q11111111q1q1q=qq111=11qq11qq111111111}1==11111q111q111111111111q1=111=q111}1q11q11q1111}1=1111111q11q111111qq11111111q1111111111111111q=11111111111111111q11=1111111111q11=1111q111q111111111q1q11111q111=11111q]q1q11q11qq1qq1qq1q11qq1qq11111=111111111=1111q11111q1q1q1111q11111111q11111}1111=q11q11qq111111q111q111q111q11q1q11qqÀ111q111q11111q1111qq=1q1q1111==11q111111]1qq1qqq1111qq1qq11q1111111111111111=1q111111q111=111111111111q1q1q1111111=q11111Â11q1=q1qq1=1=1q111=111q=11111111q11111q11111!!!!!!!!!!!!!!!!!!111111111111111111!!!!!!!!!!!!!!!!!!!!1111111111111111111111111111111111111111111111!!!!!!!!1111111111111111111111111111111111111111111111111111111111111111111111111111111111111!!!!!!!!!!11111111111111111111111111111111111111111!!!!!!!!!!";
var suspend_data="";

var lesson_status="";
var mod_score=0;
var sep1=":"
var sep2=";"
var initial_time=0; var now = new Date();  initial_time=now.getTime();
var exo_num=-1;
var exo_score=new Array();   // Exo object with score
var exo_id=new Array();  // ID of the exercises
var exo_max_score=new Array();
var test_score=0;
var test_id="";
var test_max_score=10;

var maxscore=0;
var m_info=1;
var suspend_data_length=0;
var gBuffer="";
var url_flash;
var obj_flash;

var objXAM = null;
var gStrHist = ""; //complete history except last session
var gStrQuest = ""; //Questions string
var newTest = false;

var gXmlIni = null;	//    fichier XML qui contient tous les numéros de questions avec leurs attributs (icb, ...)
var gXmlLang = null;//    fichier XML qui contient les textes dynamiques dans la langue actuelle
var gXmlAnalysis = null;//fichier XML qui contient les noms de domaines pour l'analyse, dépend de gAnalysis
var gAnalysis = ""; //Détermine par rapport à quoi se fait l'analyse, défini dans le tag <TYPE> du fichier INI, possible valeurs: ipma, pmi, sts,...

var trace_path = getURL("js/trace3.aspx");

function home_onload(){
	var flag=true; //needed to handle incorrect SCORM LMS initialization
	if (lms_name=="mos") { 
		window.sts_flash.document.location.href=trace_path;
	} 

	if (interface_type==1) { //SCORM
		if(!API_initialized){ // don't create a new API object when returning from lesson to module
			API=getAPI();
			if (API!=null){
				API_initialized=true;
				flag=get_SCORM_Data();
			}
		}
	}
	if (flag){
		initXmlIni();
	}
	//alert(suspend_data);
}
function home_onload2()
{
	window.sts_content.location.href=create_suspend_Data();
	m_score=m_score_f()/100.0;
}

function exit_m(mod){	// example of input: mod = m form  mi
	if (mod=="m") // Exit from index.htm
		{window.close(); return false;} 
	if (mod=="form")// Exit from index1.htm
		{return history.back();} 
	if (mod.substr(0,1)=="m"){ // Exit from m1r.htm
		if (interface_type==-1)
			{window.document.location.href="index_"+course_language+".htm";}
		else
			{exit_module();}
	}
	if (mod.substr(0,1)=="l"){ // Exit from less32.htm
		if (interface_type==-1)
			{go_module();}
		else
			exit_module();
	}
}

function exit_module(){ 
	var cur = new Date(); var time=cur.getTime()-initial_time; initial_time=cur.getTime();
	var dif = new Date(time);     
	var time_string="00:"+add0(dif.getMinutes())+":"+add0(dif.getSeconds())

	if ((interface_type==1) & (API_initialized) ){//SCORM
		set_time_Data(time_string);
	} 
	setTimeout("close_me()",500);
}

function exit_scorm_module(){
	if (API_initialized){
		var result = commitLMS();
		trace(1, "", "EXIT ");
		if (!result) { if(debug) alert(debug_text[course_language]+"commitLMS()"); } 
		if (endLMSConnection()!="true") {if(debug)alert(debug_text[course_language]+"endLMSConnection()"); }
		API_initialized=false;
		window.sts_content.location.href="bye.htm"; 
	}
}

function go(type, param)
{
	//alert("go:\ntype: "+type+"\nparam: "+param);
	if(window.NW && !NW.closed){
		NW.focus();
	}
	else{
		if(type==SCORES || type==SCORENUM){
			window.sts_content.location.href="xamscores.htm";
		}
		else if(type==SCOREGRAPH){
			window.sts_content.location.href="xamscores_graphical.htm";
		}
		else if(type==SCORELAST){
			window.sts_content.location.href="xamscores_graphical.htm";
		}
		else if(type==REVIEW){
			if(objXAM && objXAM.active==false){
				objXAM.resume=false;
				objXAM.source=xamSrc;
				objXAM.xmlIni=gXmlIni;
				objXAM.xmlLang=gXmlLang;
				objXAM.xmlAnalysis=gXmlAnalysis;
				//objXAM.alert();
				setExo();
			}
		}
		else{
			if(objXAM){
				gStrHist = objXAM.historyToString()+"#"+gStrHist;
				objXAM = null;
			}
			objXAM = new XAM(gMode, course_language, lIni);
			objXAM.active=true;
			objXAM.mode=type;
			objXAM.source=xamSrc;
			objXAM.param=param;
			objXAM.numQuestions=0;
			objXAM.setDate();
			objXAM.timeRemaining=-1;
			objXAM.correctAnswers=0;
			objXAM.givenAnswers=0;
			objXAM.timePerQuestion=gTime;
			objXAM.qStr=gStrQuest;
			if(objXAM.mode==SIMULATION){	
				if(isNaN(objXAM.param)){	//questions auxquelles on a jamais répondu
					objXAM.param="NEVERANSWERED";
				}
				else{	//exam simulation 50, 70, 100, 200 questions
					objXAM.numQuestions=param;
					objXAM.param="";
				}
			}
			if(objXAM.mode==WRONGANSWERS){
				objXAM.param=(param==1) ? "A" : "L";
			}
			objXAM.xmlIni=gXmlIni;
			objXAM.xmlLang=gXmlLang;
			objXAM.xmlAnalysis=gXmlAnalysis;
			//objXAM.alert();
			
			newTest = true; //flag pour vérifier et adapter la longueur de suspend_data; utilisé dans updateExam()
			setExo();
		}
	}
}

function resume(type)
{
	if(window.NW && !NW.closed){
		NW.focus();
	}
	else{
		if(type==IGNORE){
			if(objXAM){
				updateExam(type);
			}
			window.sts_content.location.href="xamhome.htm";
		}
		else{
			if(type==STOP){
				objXAM.active=false;
				objXAM.source=xamSrc;
				objXAM.resume=false;
				objXAM.stopAndReview=true;
			}
			else{
				objXAM.source=xamSrc;
				objXAM.xmlIni=gXmlIni;
				objXAM.xmlLang=gXmlLang;
				objXAM.xmlAnalysis=gXmlAnalysis;
				objXAM.resume=true;
			}
			//objXAM.alert();
			setExo();
		}
	}
}

function setExo(){
	var top = (screen.availHeight - 768) / 2;
	var left = (screen.availWidth - 1024) / 2;
	NW=window.open('exam.htm','NW','left='+left+',top='+top+',status=yes,resizable=yes,scrollbars=yes,toolbar=no,width=1024,height=768');
	return true;
}

function lesson_init(p){  // Initialises the suspend_data, exo_score, test_score, ...
	trace(1, "", "START");
}

function close_me(){ 
     if (interface_type==1) exit_scorm_module(); 
     if (self==top) { window.close();}   // Close window if there is no parent.
}

//Course Functions
function create_suspend_Data(){
	var rHome=getURL("x-am/html/xamhome.htm"); 
	if(suspend_data==null){
		suspend_data="";
	}
	else{
		if(suspend_data.indexOf("[H]")>=0 && suspend_data.indexOf("[Q]")>=0){
			var strq = suspend_data.substr((suspend_data.indexOf("[Q]")+3)); //extraire les questions
			/* parcourir les questions */
			for(i=0; i<strq.length; i++){
				var n = strq.charCodeAt(i); //retransformer les caractères spéciaux evités 0-32 et 127-160
				gStrQuest += (n>=161) ? String.fromCharCode(n-67) : String.fromCharCode(n-33); //n >= 161 : -67 -> caractères 127-160 ; n <= 160 : -33 -> caractères 0-32
			}
			var w = suspend_data.substring(suspend_data.indexOf("[H]")+3,suspend_data.indexOf("[Q]")); //extraire l'historique
			/* S'il y a un historique */
			if(w.length>0){
				var lastXam=w.substring(0, w.indexOf("#"));//extraire les données du dernier test effectué
				gStrHist = w.substr(w.indexOf("#")+1); //garder le reste de l'historique dans une variable globale
				if(lastXam.length>1){ //si lastXam.length==1 le dernier test a été ignoré 
					var t = string_to_Object(lastXam); //créer un objet XAM
					// vérifier si le dernier test est actif
					if(objXAM.active){
						rHome=getURL("x-am/html/xamresume.htm");
					}
				}
			}
		}
	}
/*---------------------------*/
	if(gMode=="pmtok"){
		rHome=getURL("x-am/html/pmtokhome"+course_id+".htm");
	}
/*---------------------------*/

	return rHome;
}

function string_to_Object(pH){ // converts History into objXAM
	arr = pH.split(";");
	objXAM = new XAM(gMode, course_language, lIni);
	objXAM.active=(arr[0]=="1") ? true : false;				// STATUS       = 0;
	objXAM.source=xamSrc;
	objXAM.mode=arr[1];										// MODE         = 1;
	objXAM.param=arr[2];									// PARAM        = 2;
	objXAM.numQuestions=parseInt(arr[3], 10);				// QUESTIONS    = 3;
	objXAM.date=parseInt(arr[4], 10);						// DATE		    = 4;
	objXAM.timeRemaining=parseInt(arr[5], 10);				// TIME         = 5;
	objXAM.correctAnswers=parseInt(arr[6], 10);				// CORRECT      = 6;
	objXAM.givenAnswers=parseInt(arr[7], 10);				// GIVEN        = 7;
	objXAM.randomSeed1=parseInt(arr[8], 10);				// RANDOMSEED1  = 8;
	objXAM.randomSeed2=parseInt(arr[9], 10);				// RANDOMSEED2  = 9;
	objXAM.timePerQuestion=gTime;
	objXAM.qStr=gStrQuest;
	objXAM.xmlIni=gXmlIni;
	objXAM.xmlLang=gXmlLang;
	objXAM.xmlAnalysis=gXmlAnalysis;
	
	return true;
}

function object_to_String(){ 
	var str=suspend_data;
	for (var i=0;i<=exo_num;i++){
		if (exo_score[i]>0)
			str=putVal(exo_id[i]+sep1,sep2,str,exo_score[i]);
	}
	suspend_data=str;
}

function examIsClosing(){
	if(gMode=="pmtok"){
		window.sts_content.location.reload();
	}
	else{
		if(objXAM.active){
			window.sts_content.location.href="xamresume.htm";
		}
		else{
			window.sts_content.location.href="xamhome.htm";
		}
	}
}

function updateExam(sender)
{
	// mettre à jour la variable globale des questions
	gStrQuest=objXAM.qStr;
	var strH = "";
	var strQ = "";
	/* parcourir les questions */
	for(i=0;i<objXAM.qStr.length;i++){
		var n = objXAM.qStr.charCodeAt(i); //les caractères 0-32 et 127-160 ne peuvent pas être stockés -> il faut les éviter
		strQ += (n<=93) ? String.fromCharCode(n+33) : String.fromCharCode(n+67); //n <= 93 : +33 -> éviter 0-32 ; n >= 94 : +67 -> éviter 127-160
	}
	// Si le test précédant à été ignoré 
	if(sender==IGNORE){
		objXAM=null; //détruire l'objet XAM
		strH="I#"+gStrHist;
	}
	else{
		//Si c'est le premier enregistrement d'un test
		if(newTest){
			//on fait un nettoyage de l'historique pour éviter qu'il devienne trop long (max. 4096 Bytes)
			gStrHist = cleanUpHistory(gStrHist);
			newTest =false;
		}
		strH=objXAM.historyToString()+"#"+gStrHist; //ajouter l'historique du test en cours
	}
	
	var sd = VERSION+"[BB]"+"[H]"+strH+"[Q]"+strQ; //créer l'actuel suspend_data
	// S'il existe déjà un suspend_data
	if(suspend_data.length>0){
		//si le suspend_data existant est plus grand que le nouveau sd, il faut ajouter du buffer: [B----B]
		if(suspend_data.length-sd.length>0){
			sd = VERSION+"[B"+getBuffer(suspend_data.length-sd.length)+"B]"+"[H]"+strH+"[Q]"+strQ; 
		}
	}
	suspend_data=sd;
	var lmsScore = calculateLMSScore(strH);
	put_lms_data(lmsScore);
}

function cleanUpHistory(pStrHist)
{
	//la page des scores affiche au max. 8 scores par Knowledge Area, Process ou Exam Simulation
	//en prenant en compte que le test en cours peut être ignoré, l'historique ne doit pas contenir plus de
	//8 test terminés et 1 test actif pour le même knowledge area, process,...
	
	if(pStrHist.length>0){
		//STATUS=0;MODE=1;PARAM=2;QUESTIONS=3;DATE=4;TIME=5;CORRECT=6;GIVEN=7;RANDOMSEED1=8;RANDOMSEED2=9;
		//EXAM=4;PREP=1;
		var arHist = pStrHist.split("#");
		arHist.pop(); //Enlève le dernier element qui est vide
		var toDelete = new Array();
		var nbrSame = 0;
		for(var i=0; i<arHist.length; i++){
			
			var arT=arHist[i].split(";");
			//arT[0] = STATUS: 1=actif, 0=terminé
			//Si par erreur un test garde son statut actif, il ne sera pas affiché dans les scores et peut être effacé
			var lStatus = arT[0];
			//arT[1] = MODE: 1=Preparation, 2=Wrong answers, 4=Exam simulation
			//les revues de question auxquelles on a mal répondu peuvent être effacés, sont inutiles
			var lMode = arT[1];
			//arT[2] = PARAM: knowledge area (1-10), process (p1-p5), domaine ipma(1-5), wrong answers (A/L)
			//ça ne sert à rien de garder plus de 8 test du même knowledge area, process, etc.
			var lParam = arT[2];
			if(lMode=="2"){
				toDelete[toDelete.length] = i; //on retient la position de l'élément à effacer dans l'historique
			}
			else if(lParam==objXAM.param.toString()){
				nbrSame++;			//on compte le nombre de tests du même domaine que le test en cours
				if(nbrSame > 8){	//S'il y en a plus que 8 on peut enlever le plus vieux
					toDelete[toDelete.length] = i; //on retient la position de l'élément à effacer dans l'historique
				}
			}
			else if(lStatus=="1"){		//si un test est resté actif par erreur
				toDelete[toDelete.length] = i; //on retient la position de l'élément à effacer dans l'historique
			}
		}
		//on parcourt le tableau toDelete à l'envers (!) pour éviter que les position des éléments à effacer changent
		for (k=(toDelete.length-1); k >=0 ; k-- ){
			arHist.splice(toDelete[k], 1); //array.splice( position de l'élément à effacer, nombre d'éléments à effacer )
		}
		
		//S'assurer que la longueur totale de suspend_data ne dépasse pas les 4096 Bytes
		var tempSD = VERSION+"[BB]"+"[H]"+arHist.join("#")+"#[Q]"+objXAM.qStr;
		//si suspend_data est quand même trop long, on enlève le plus ancien test
		if(tempSD.length > 4050){
			arHist.pop(); 
		}

		pStrHist = arHist.join("#") + "#";
	}
	return pStrHist;
}

function getBuffer(delta)
{
	var buf="";
	for(i=0; i<delta; i++){
		buf+="-";
	}
	return buf;
}

function calculateLMSScore(pHist)
{
	var res = 0;
	
	if(objXAM && objXAM.calculateLmsScore){ 
		objXAM.calculateLmsScore=false; //éviter que lms_score soit calculé une deuxième fois inutilement
		//STATUS=0;MODE=1;PARAM=2;QUESTIONS=3;DATE=4;TIME=5;CORRECT=6;GIVEN=7;
		var arHist = pHist.split("#");  //transformer le historique en tableau
		var bestScoreExam=0;
		var lastScorePrep=0;
		var domainScores;
		if(xamSrc=="pmi"||xamSrc=="pmi2004")		{ domainScores = new Array(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1); }
		else if(xamSrc=="ipma"||xamSrc=="sts")	{ domainScores = new Array(-1,-1,-1,-1); }
		else if(xamSrc=="pmfund"||xamSrc=="pmadv")	{ domainScores = new Array(-1,-1,-1,-1,-1,-1,-1,-1,-1); }

		for(var i=0 ; i<(arHist.length-1) ; i++){
			var arSession = arHist[i].split(";");
			if(arSession[1]==SIMULATION){
				var curScoreExam = Math.round( (parseInt(arSession[6], 10)/parseInt(arSession[3], 10)*100 ));
				if(curScoreExam>bestScoreExam){
					bestScoreExam=curScoreExam;
				}
			}
			else if(arSession[1]==PREPARATION){
				var curScorePrep = Math.round( (parseInt(arSession[6], 10)/parseInt(arSession[7], 10)*100 ));
				var domain = parseInt(arSession[2],10);
				if( !(isNaN(curScorePrep) || isNaN(domain))){
					if(domainScores[domain-1]==-1){			//Si'l'on prend le dernier résultat de chaque domaine
						domainScores[domain-1]=curScorePrep;
					}
				}
			}
		}
		for(var j=0; j<domainScores.length; j++){
			lastScorePrep+=(domainScores[j]>0) ? domainScores[j] : 0;
		}
		lastScorePrep=Math.round((lastScorePrep/domainScores.length));
		res=(lastScorePrep>bestScoreExam) ? lastScorePrep : bestScoreExam; 
	}

	return res;
}

function put_exo_strings(flag){ // flag==true : send data to the LMS
}

function put_lms_data(c_score){ // Sends the data to a LMS
	var lesson_done=false;
	var LMS_score=c_score;
	lesson_done=(LMS_score >= m_score*100);

	var cur = new Date(); var time=cur.getTime()-initial_time;  initial_time=cur.getTime();
	var dif = new Date(time);
	var time_string="00:"+add0(dif.getMinutes())+":"+add0(dif.getSeconds());
	var lesson_status=(lesson_done)?"passed":"incomplete";

	if ((interface_type==1) & (API_initialized)){ // SCORM
		if(LMS_score>0)// must be > 0 otherwise an internal server error (bug) in statistics of MOS occurs
			set_student_Score(LMS_score);
		set_lesson_status(lesson_status);
		set_time_Data(time_string);
		set_suspend_Data(suspend_data);
	}
}

// SCORM Functions
function get_SCORM_Data(){
	var result=startLMSConnection();
	if ((result=="false") || (result==null)){
		alert("There is no LMS Initialization");
		if (endLMSConnection()!="true") {
			if(debug) alert(debug_text[course_language]+"endLMSConnection()");
		}
		API_initialized = false;
		window.sts_content.location.href="bye.htm";
		return false;
	}
	var w=getLMSValue("cmi.student_data.mastery_score");
	mastery_score= ((w>0) & (w<=100))? w : "80";
	if (mastery_score==""){
		errnum=getLastLMSError();
		if(errnum=="401" || errnum!="0"){ mastery_score="not available";}
	}
	suspend_data=getLMSValue("cmi.suspend_data");

	var tmpLng=getVal("lng"+sep1,sep2,suspend_data);//chercher la langue dans suspend_data
	var valCookieLng=GetCookie("_cookielngmod");
	if (tmpLng)
		if ((tmpLng =='e') ||(tmpLng =='f') ||(tmpLng =='g')){
			if(!valCookieLng){
				SetCookie("_cookielngmod",course_language,date_exp,myDomain);
			}
		}
	
	if(valCookieLng&&(valCookieLng!=tmpLng)){
//		course_language=valCookieLng;
//		if ((interface_type==1) & (API_initialized)){
//			suspend_data=putVal("lng"+sep1,sep2,suspend_data,course_language); // save the language in suspend_data
//			var st=getLMSValue("cmi.core.lesson_status");
//			if (st=="not attempted"){
//				set_lesson_status("incomplete");
//			}
//			set_suspend_Data(suspend_data); // send suspend_data to the LMS
//			trace("LANG ");
//		}
	}	
	return true;
}

function set_suspend_Data(suspend_data){
	if(suspend_data_length > suspend_data.length){
		alert(debug_text[course_language]+" 1 set_suspend_Data");
  		connectionError=true; }
	else{
		suspend_data_length=suspend_data.length;
		if (setLMSValue("cmi.suspend_data", suspend_data)!="true"){
			if(debug){
				alert(debug_text[course_language]+" 2 set_suspend_Data");
				connectionError=true;
			}
		}
	}

	var result = commitLMS();
}

function set_time_Data(time_string){
	if (setLMSValue("cmi.core.session_time", time_string)!="true"){
		if(debug)alert(debug_text[course_language]+"set_time_Data time_data="+time_string);
	}
}
function set_student_Score(score){ // student_score=score;
	score_=(score>0)? ""+score:"";
	if (setLMSValue("cmi.core.score.raw", score_)!="true"){if(debug)alert(debug_text[course_language]+"set_student_Score  score="+score);}
	if (setLMSValue("cmi.core.score.max", 100)!="true"){if(debug) alert(debug_text[course_language]+"set_student_Score  max=100");}
}
function set_lesson_status(status){
	lesson_status=status;
	var st=getLMSValue("cmi.core.lesson_status");
	if (st!=status){
		if (setLMSValue("cmi.core.lesson_status", status)!="true"){
			if(debug){
				alert(debug_text[course_language]+"setLMSValue(cmi.core.lesson_status)");
				connectionError=true;
			}
		}
	}
}
function findAPI(win){
	var findAPITries = 0;
	while ( (win.API == null) &&  (win.parent != null) &&  (win.parent != win)){
		findAPITries++;
		if (findAPITries > 7) {if(debug)alert(debug_text[course_language]+"Error finding API -- too deeply nested.");return null;}
		win = win.parent;
	}
	return win.API;
}
function getAPI(){
	var theAPI = findAPI(window);
	if ( (theAPI == null) && (window.opener != null) && (typeof(window.opener)!="undefined")){
		theAPI = findAPI(window.opener);
	}
	if (theAPI == null){
		if(debug){
			alert(debug_text[course_language]+"Unable to find an API adapter");
			connectionError = true;
		}
	}
	return theAPI;
}
function startLMSConnection(){return (API!=null) ? API.LMSInitialize(""):null }
function endLMSConnection() {return (API!=null)? API.LMSFinish(""):null}
function getLMSValue(dataobject) {return (API!=null)? API.LMSGetValue(dataobject):null}
function setLMSValue(dataobject, value) { return (API!=null)? API.LMSSetValue(dataobject,value):null}//o.k evantually commit
function commitLMS(){return (API!=null)? API.LMSCommit(""):null}
function getLastLMSError(){ return (API!=null)? API.LMSGetLastError():null}

// Service Functions
function getVal(key1,key2,dstr){// returns a part of string between substrings key1 and key2
	if(!dstr){ 
		return null;
	}
	dstr=dstr.replace(/\[/g,'<');
	dstr=dstr.replace(/\]/g,'>');
	re=new RegExp(key1+"[^"+key2+"]*","i");
	var ar=re.exec(dstr);
	if (ar){
		return (ar[0])? delStr(key1,ar[0]) : null;
	}
	else
		return null;
}

function putVal(key1,key2,datastr,val){// puts string val between substrings key1 and key2
	var m=datastr.indexOf(key1);
	if (m>-1){
		var str1=datastr.substring(0,m+key1.length);
		var n=datastr.indexOf(key2,m+key1.length);
		n=(n>-1)?n:datastr.length;
		var str2=datastr.substr(n);
		str1=str1+val+str2;
	}
	else{
		var str1=datastr+key1+val+key2;
	}
	return str1;
}

// deletes key in the string datastr
function delStr(key,datastr){
	if(!datastr)return null;
	re=new RegExp(key,"ig");datastr=datastr.replace(re,'');
	return datastr
}

function m_score_f() {
 var w=mastery_score;
 var g=(w=="100")?100:parseInt(w,10);
 if ((g<=0) | (g>100)) g=80;
 return g;
}

function module_score(output_type){ // output_type==true : Module Value
	var st=suspend_data; var sum=0; var i=0; var les_score=0;
	var j=st.indexOf("les");
	while (j>=0){
		st=st.substr(j+3);
		ttt=getVal(sep1,sep2,st);
		les_score=parseInt(ttt,10);
		sum=sum+les_score;
		if (les_score>=m_score*100) i++;
		j=st.indexOf("les");
	}
	if (output_type) // True : all lessons has credits>0
		return (elnum<=i);
	if (elnum>i) // elnum = number of lessons in the module
		i=elnum;
	if (i>1)
		sum=Math.round(sum/i);
	return sum; 
}

function add0(v){var t=""; t+=v; if (t.length<2) t="0"+t;  return t}; // Adds leading zero

function check_suspend_data(s){
	var result=true;
	if(s.length>6){//minimum length is 6 -> lng:e;
		if(s.indexOf("m"+sep1)<0) result=false;
		if(s.indexOf("m"+sep1)!=s.lastIndexOf("m"+sep1)) result=false;
		var st=s; var sum=0; var i=0;
		var j=st.indexOf(sep1)
		while (j>=0){
			st=st.substr(j);
			ttt=getVal(sep1,sep2,st)
				if((ttt!="")&&(ttt!="e")&&(ttt!="f")&&(ttt!="g")&&(ttt!="s")){
				sum=parseInt(ttt,10);
				if(!((sum>=0)&&(sum<=100)))
					result=false;
			}
			//else
			//	result=false;
			st=st.substr(1);
			j=st.indexOf(sep1);
		 }
	}
	if (!result) alert("Suspend_data is not correct. Please send the screenshot of this alert to STS. suspend_data:\n"+s);

}

function module_unload(){
	if(window.NW && !NW.closed){NW.close();} //Close exo window when changing module
	if(window.GL && !GL.closed){GL.close();} //Close glossary when changing module
	if(window.NS && !NS.closed){NS.close();} //Close forms when changing module
	if(window.HLP && !HLP.closed){HLP.close(); //Close help when changing module
	}
	if (interface_type==1){ //SCORM
		if(API_initialized){ //save credits & time and end LMS connection
			var cur = new Date(); var time=cur.getTime()-initial_time; initial_time=cur.getTime();
			var dif = new Date(time);     
			var time_string="00:"+add0(dif.getMinutes())+":"+add0(dif.getSeconds());
			set_time_Data(time_string);
			exit_scorm_module();
		}
	}
}

// loads the corresponding page in frame sts_content when the language is changed
function changeLang(pLang){
	course_language=pLang; //set new language for this module
	//SetCookie("_cookielngmod",course_language,date_exp,myDomain);
	window.sts_content.document.location.reload();
	if(objXAM){
		objXAM.language=course_language;
	}
}

function trace(type, exoID, param)
{
	if (lms_name=="mos"){
		var str="";
		var mosCours="";
		var mosGroupe="";
		var mosUser=""
		
		if (!top.serveur){			
			if (top.API){
				qqq="API exists. "; }
			else
				qqq="There is no API. ";
			str="! ERROR: there is no top.serveur. "+qqq+"  !  ! ";
			mosUser="ERRORS";
		}
		else{
			var mosFormation=top.donneStageCourant();
			mosCours=mosFormation.codeStage;//nom du cours
			mosGroupe=mosFormation.codeGroupe;//nom du groupe
			mosUser=top.serveur.getId();//identifiant de l'utilisateur
			//str+=mosUser;
		}

		if(type == 1){
			str+=mosGroupe+" ! "+mosCours;
			str+=" ! "+navigator.appName+" "+navigator.appVersion;
			str+=" ! "+param; 
			str+=" ! "+home.substring(0,home.length-4);
			//str+=" ! "+getVal("m:",";",suspend_data);
			str+=" ! "+lesson_status.substr(0,4)
			str+=" ! "+suspend_data;
			str=str.replace("Microsoft Internet Explorer", "IE");
		}
		else if(type == 2){
			str+=exoID+" ! "+course_language+" ! "+param.substring(0, param.lastIndexOf("[]"))+" ! "+param.substr(param.lastIndexOf("[]")+2);
		}
		else if(type == 3){
			//str+=exoID+" ! "+" ! "+" ! "+" ! "+" ! "+" ! "+" ! "+suspend_data;
			str+=" ! "+suspend_data;
		}
		else{
			str+=exoID+" ! "+param;
		}

		if(mosUser!=""){
			try{
				window.sts_flash.document.forms["traceform"].elements["usr"].value = mosUser;
				window.sts_flash.document.forms["traceform"].elements["v"].value = type;
				window.sts_flash.document.forms["traceform"].elements["str"].value = str;
				window.sts_flash.document.forms["traceform"].submit();
			}
			catch(Exception){
				//alert("trace3.aspx not loaded");
			}
		}
	}
}

function initXmlIni()
{
	var xmldoc=getURL("x-am/exo/ini_"+lIni+".xml");
	if(loadXmlDocument(xmldoc, HandleXmlIni)!=true){
		alert("Unable to load INI file:\n"+xmldoc);
	}
}

function initXmlLang()
{
	var xmldoc=getURL("x-am/html/xamlang.xml");
	if(loadXmlDocument(xmldoc, HandleXmlLang)!=true){
		handleError("Unable to load language file:\n"+xmldoc, 105);
	}
}

function initXmlAnalysis()
{
	var xmldoc=getURL("x-am/html/analysis_"+gAnalysis+".xml");
	if(loadXmlDocument(xmldoc, HandleXmlAnalysis)!=true){
		handleError("Unable to load analysis file:\n"+xmldoc, 200);
	}
}

//CHARGE LE FICHIER XML DEPUIS L'URL SPECIFIE DANS xmlFile ET APPELLE LA FONCTION cbFun QUI TRAITE LE XML
function loadXmlDocument(xmlFile, cbFun)
// Copyright (C) 2002-2003, CodeHouse.com. All rights reserved.
{
	var res = true;
	var xdoc;
	if( window.ActiveXObject && /Win/.test(navigator.userAgent) ){
		try{
			xdoc = new ActiveXObject("Microsoft.XMLDOM");
			xdoc.async = false;
			//xdoc.onreadystatechange=verify;
			xdoc.load(xmlFile);
			cbFun(xdoc);
		}
		catch(e){res = false;}
	}
	else if( document.implementation && document.implementation.createDocument ){
		try{
			xdoc = document.implementation.createDocument("", "", null);
			xdoc.load(xmlFile);
			xdoc.onload = function(){cbFun(xdoc);}
		}
		catch(e){alert(e);res = false;}
	}
	else{  
		res = false; 
	}
	return res;
}
//VERIFIE SI LE FICHIER XML EST COMPLETEMENT CHARGE PAR IE
function verify()
{  
	if (xmlDoc.readyState != 4){  
		return false;  
	}
} 
//TRAITE L'XML INI
function HandleXmlIni(xdoc)
{
    gXmlIni = xdoc.documentElement;
	gAnalysis=gXmlIni.childNodes[0].childNodes[0].firstChild.data;
	initXmlLang();
}
//TRAITE L'XML DE LANGUE
function HandleXmlLang(xdoc)
{
    gXmlLang = xdoc.documentElement;
	initXmlAnalysis();
}

function HandleXmlAnalysis(xdoc)
{
	gXmlAnalysis = xdoc.documentElement;
	home_onload2();
}

function getXmlValue(objXml, attribLang, attribId)
{
	var cn1 = 0;
	var cn2 = 0;
	while(objXml.childNodes[cn1].getAttribute("lang")!=attribLang){
		cn1++;
	}
	while(objXml.childNodes[cn1].childNodes[cn2].getAttribute("id")!=attribId){
		cn2++;
	}
	return objXml.childNodes[cn1].childNodes[cn2].firstChild.data;
}

function getFlashParams()
{
	var rev="1"; //review de la dernière session
	var qil="1"; //questions incorrect last session
	var qia="1"; //questions incorrect all sessions
	var qna=10;   //questions never answered, init > 0 for the very first session where gStrQuest.length=0

	//Si l'objet XAM existe et si une erreur s'est produite lors du dernier test, l'objet XAM est détruit
	if(objXAM && objXAM.error){
		objXAM=null;
	}
	
	//Test si revue de la dernière est possible
	if(!objXAM || (objXAM.active==true)){
		rev="2";
	}
	
	//Test s'il est possible de repasser les questions incorrectes de la dernière session / de toutes les sessions
	if(!objXAM && (suspend_data.length==0 || gStrHist.length==0)){
		qil="2";
		qia="2"; //"Sorry, it is impossible to re-ask wrongly answered questions. This is either your first visit or you have chosen to ignore previous sessions.";
	}
	else if(!objXAM && (suspend_data.length>5 || gStrHist.length>5)){
		qil="5"; //"Sorry, it is impossible to re-ask wrongly answered questions of your last session because you have chosen to ignore it.";
	}
	else{
		var h=gStrHist;
		var wrongLast=0;
		var wrongAll=0;
		var givenLast=0;
		var givenAll=0;
		if(objXAM){
			h=objXAM.historyToString()+"#"+h;
		}
		var arH=h.split("#");
		for(i=0; i<(arH.length-1); i++){
			var arT = arH[i].split(";");
			givenAll+=parseInt(arT[7], 10);
			wrongAll+=(parseInt(arT[7], 10)-parseInt(arT[6], 10));
			if(i==0){
				givenLast=givenAll;
				wrongLast=wrongAll;
			}
		}
		if(wrongLast<=0){
			if(givenLast>0){
				qil="3"; //"You have answered "+given+" questions in your last session and you did not give a wrong answer.";
			}
			else{
				qil="4"; //"You have not answered any question in your last session.";
			}
		}
		if(wrongAll<=0){
			if(givenAll>0){
				qia="3"; //"You have answered "+given+" questions so far and you never gave a wrong answer.";
			}
			else{
				qia="4"; //"You have never answered any question.";
			}
		}
	}

	//test s'il y a des questions auxquelles on n'a jamais répondu
	if(gStrQuest.length>0){
		qna=0;
		for (i=0 ; i<gStrQuest.length ; i++){
			if( ((gStrQuest.charCodeAt(i)>>4) & 1)==0 ){
				qna++;
			}
		}
	}
	var params="&review="+rev+"&qincolast="+qil+"&qincoall="+qia+"&qna="+qna;
	return params;
}

function getURL(file)
{
	return base_path+file;
}
