/********************************************************************************************************************************************************
					tracciamento
********************************************************************************************************************************************************/


<!--
// FS SCORM - adattatore fscommand per ADL SCORM 1.2 e per le interazioni di apprendimento di Flash MX 2004
// versione 1.0    08/19/03
// Modificato da Andrew Chemey, Macromedia
// Basato sulla versione 1.2.4 dell'adattatore FS SCORM:
// 		Fragments Copyright 2002 Pathlore Software Corporation. Tutti i diritti riservati.
// 		Fragments Copyright 2002 Macromedia Inc. Tutti i diritti riservati.
// 		Fragments Copyright 2003 Click2learn, Inc. Tutti i diritti riservati.
// 		Sviluppato da Tom King, Macromedia,
// 		             Leonard Greenberg, Pathlore,
// 		             e Claude Ostyn, Click2learn, Inc.
// 		Include codice di Jeff Burton e Andrew Chemey, Macromedia (09/01/02)
// -----------------------------------------------------------------
// Modifica questi valori preimpostati consentendo di adattarli al gusto e alle esigenze personali.
var g_bShowApiErrors = false; 	// impostare su true per mostrare i messaggi di errore
var g_bInitializeOnLoad = false; // impostare su false per non inizializzare LMS al caricamento della pagina HTML
// Traduce queste stringhe se g_bShowApiErrors è true
// ed è necessario localizzare l'applicazione
var g_strAPINotFound = "Management system interface not found.";
var g_strAPITooDeep = "Cannot find API - too deeply nested.";
var g_strAPIInitFailed = "Found API but LMSInitialize failed.";
var g_strAPISetError = "Trying to set value but API not available.";
var g_strFSAPIError = 'LMS API adapter returned error code: "%1"\nWhen FScommand called API.%2\nwith "%3"';
var g_strDisableErrorMsgs = "Select cancel to disable future warnings.";
// Impostare g_bSetCompletedAutomatically su true se si desidera che lo stato
// venga impostato in modo completamente automatico quando si richiama LMSFinish. Generalmente,
// questo flag resta false se lo stato viene impostato dal filmato Flash stesso
// su completato inviando un FSCommand per impostare lo stato su "completato",
// "riuscito" o "non riuscito" (in entrambi i casi "completato")
var g_bSetCompletedAutomatically = false;
// Questo valore viene normalmente fornito da LMS ma, in caso contrario,
// questo è il valore predefinito da usare per determinare se lo stato è "riuscito" o "non riuscito".
// Impostare su null se il codice ActionScript di Flash usa un proprio metodo
// per determinare lo stato "riuscito" e "non riuscito"; in caso contrario, impostare su un valore tra 0 e 1
// compreso (può anche essere un valore a virgola mobile, ad esempio "0,75").
var g_SCO_MasteryScore = null; // valori consentiti: 0.0..1.0 o null
//==================================================================
// AVVERTENZA!!
// Non modificare nessun valore dopo questa riga se non si è certi
// dell'operazione che si sta eseguendo.
// Non dovrebbe essere necessario modificare questi due valori, poiché i valori preimpostati del modello di Flash
// sono basati su di essi.
var g_nSCO_ScoreMin = 0; 		// deve essere un numero
var g_nSCO_ScoreMax = 100; 		// deve essere un numero > nSCO_Score_Min
// Per la specifica SCORM, il punteggio di abilità LMS fornito,
// se presente, determinerà se il punteggio
// deve essere o meno interpretato una volta stabilito lo stato riuscito/non riuscito.
// Il modello tenta di ricavare il punteggio di abilità e se questo
// è disponibile, di impostare di conseguenza lo stato "riuscito" o "non riuscito"
// quando viene inviato un punteggio dallo SCO. Il sistema LMS non è in grado di
// determinare questo elemento fino al termine dello SCO.
// Il valore predefinito per questo flag è true. Impostarlo su false se non
// si desidera predeterminare come il sistema LMS imposterà lo stato riuscito/non riuscito in base al
// punteggio di abilità (il sistema LMS avrà comunque la priorità).
var g_bInterpretMasteryScore = true;
// Questo script implementa vari aspetti del
// comportamento di logica comune di uno SCO.
/////////// LE FUNZIONI DI INIZIALIZZAZIONE DELL'INTERFACCIA API E LE FUNZIONI CATCHER ////////
var g_nFindAPITries = 0;
var g_objAPI = null;
var g_bInitDone = false;
var g_bFinishDone = false;
var	g_bSCOBrowse = false;
var g_dtmInitialized = new Date(); // verranno regolate dopo l'inizializzazione
var g_bMasteryScoreInitialized = false;
function AlertUserOfAPIError(strText) {
	if (g_bShowApiErrors) {
		var s = strText + "\n\n" + g_strDisableErrorMsgs;
		if (!confirm(s)){
			g_bShowApiErrors = false
		}
	}
}
function ExpandString(s){
	var re = new RegExp("%","g")
	for (i = arguments.length-1; i > 0; i--){
		s2 = "%" + i;
		if (s.indexOf(s2) > -1){
			re.compile(s2,"g")
			s = s.replace(re, arguments[i]);
		}
	}
	return s
}
function FindAPI(win) {
	while ((win.API == null) && (win.parent != null) && (win.parent != win)) {
		g_nFindAPITries ++;
		if (g_nFindAPITries > 5000) {
			AlertUserOfAPIError(g_strAPITooDeep);
			return null;
		}
		win = win.parent;
	}
	return win.API;
}
function APIOK() {
	return ((typeof(g_objAPI)!= "undefined") && (g_objAPI != null))
}
function SCOInitialize() {

	var err = true;
	if (!g_bInitDone) {
		if ((window.parent) && (window.parent != window)){
			g_objAPI = FindAPI(window.parent)
		}
		if ((g_objAPI == null) && (window.opener != null))	{
			g_objAPI = FindAPI(window.opener)
		}
		if (!APIOK()) {
			AlertUserOfAPIError(g_strAPINotFound);
			err = false
		} else {
			err = g_objAPI.LMSInitialize("");
			if (err == "true") {
				g_bSCOBrowse = (g_objAPI.LMSGetValue("cmi.core.lesson_mode") == "browse");
				if (!g_bSCOBrowse) {
					if (g_objAPI.LMSGetValue("cmi.core.lesson_status") == "not attempted") {
						err = g_objAPI.LMSSetValue("cmi.core.lesson_status","incomplete")
					}
				}
			} else {
				AlertUserOfAPIError(g_strAPIInitFailed)
			}
		}
		if (typeof(SCOInitData) != "undefined") {
			// La funzione SCOInitData può essere definita in un altro script dello SCO
			SCOInitData()
		}
		g_dtmInitialized = new Date();
	}
	
	g_bInitDone = true;
	return (err + "") // Forza il tipo su "string"
}
function SCOFinish() {
	if ((APIOK()) && (g_bFinishDone == false)) {
		SCOReportSessionTime()
		if (g_bSetCompletedAutomatically){
			SCOSetStatusCompleted();
		}
		if (typeof(SCOSaveData) != "undefined"){
			// La funzione SCOSaveData può essere definita in un altro script dello SCO
			SCOSaveData();
		}
		g_bFinishDone = (g_objAPI.LMSFinish("") == "true");
	}
	return (g_bFinishDone + "" ) // Forza il tipo su "string"
}
// Richiama queste funzioni catcher anziché tentare di richiamare direttamente l'adattatore API
function SCOGetValue(nam)			{return ((APIOK())?g_objAPI.LMSGetValue(nam.toString()):"")}
function SCOCommit()					{return ((APIOK())?g_objAPI.LMSCommit(""):"false")}
function SCOGetLastError()		{return ((APIOK())?g_objAPI.LMSGetLastError():"-1")}
function SCOGetErrorString(n)	{return ((APIOK())?g_objAPI.LMSGetErrorString(n):"No API")}
function SCOGetDiagnostic(p)	{return ((APIOK())?g_objAPI.LMSGetDiagnostic(p):"No API")}
//LMSSetValue viene implementato mediante logica di gestione
//dei dati più complessa riportata di seguito
var g_bMinScoreAcquired = false;
var g_bMaxScoreAcquired = false;
// La logica speciale inizia qui
function SCOSetValue(nam,val){
	var err = "";
	if (!APIOK()){
			AlertUserOfAPIError(g_strAPISetError + "\n" + nam + "\n" + val);
			err = "false"
	} else if (nam == "cmi.core.score.raw") err = privReportRawScore(val)
	if (err == ""){
			err = g_objAPI.LMSSetValue(nam,val.toString() + "");
			if (err != "true") return err
	}
	if (nam == "cmi.core.score.min"){
		g_bMinScoreAcquired = true;
		g_nSCO_ScoreMin = val
	}
	else if (nam == "cmi.core.score.max"){
		g_bMaxScoreAcquired = true;
		g_nSCO_ScoreMax = val
	}
	return err
}
function privReportRawScore(nRaw) { // richiamato solo da SCOSetValue
	if (isNaN(nRaw)) return "false";
	if (!g_bMinScoreAcquired){
		if (g_objAPI.LMSSetValue("cmi.core.score.min",g_nSCO_ScoreMin+"")!= "true") return "false"
	}
	if (!g_bMaxScoreAcquired){
		if (g_objAPI.LMSSetValue("cmi.core.score.max",g_nSCO_ScoreMax+"")!= "true") return "false"
	}
	if (g_objAPI.LMSSetValue("cmi.core.score.raw", nRaw)!= "true") return "false";
	g_bMinScoreAcquired = false;
	g_bMaxScoreAcquired = false;
	if (!g_bMasteryScoreInitialized){
		var nMasteryScore = parseInt(SCOGetValue("cmi.student_data.mastery_score"),10);
		if (!isNaN(nMasteryScore)) g_SCO_MasteryScore = nMasteryScore
	}
  	if ((g_bInterpretMasteryScore)&&(!isNaN(g_SCO_MasteryScore))){
    	var stat = (nRaw >= g_SCO_MasteryScore? "passed" : "failed");
    	if (SCOSetValue("cmi.core.lesson_status",stat) != "true") return "false";
  	}
  	return "true"
}
function MillisecondsToCMIDuration(n) {
//Converte la durata da millisecondi in formato 0000:00:00.00
	var hms = "";
	var dtm = new Date();	dtm.setTime(n);
	var h = "000" + Math.floor(n / 3600000);
	var m = "0" + dtm.getMinutes();
	var s = "0" + dtm.getSeconds();
	var cs = "0" + Math.round(dtm.getMilliseconds() / 10);
	hms = h.substr(h.length-4)+":"+m.substr(m.length-2)+":";
	hms += s.substr(s.length-2)+"."+cs.substr(cs.length-2);
	return hms
}
// SCOReportSessionTime viene richiamato automaticamente da questo script,
// ma può essere richiamato in qualsiasi momento anche dallo SCO
function SCOReportSessionTime() {
	var dtm = new Date();
	var n = dtm.getTime() - g_dtmInitialized.getTime();
	return SCOSetValue("cmi.core.session_time",MillisecondsToCMIDuration(n))
}
// Poiché solo chi ha creato lo SCO conosce il significato dello stato "completato", un altro
// script dello SCO può richiamare questa funzione per impostare lo stato "completato"
// La funzione controlla che lo SCO non si trovi in modalità Sfoglia ed
// evita di sovrascrivere gli stati "riuscito" e "non riuscito" poiché costituiscono stati di tipo "completato".
function SCOSetStatusCompleted(){
	var stat = SCOGetValue("cmi.core.lesson_status");
	if (SCOGetValue("cmi.core.lesson_mode") != "browse"){
		if ((stat!="completed") && (stat != "passed") && (stat != "failed")){
			return SCOSetValue("cmi.core.lesson_status","completed")
		}
	} else return "false"
}
// Logica di gestione degli oggetti
function SCOSetObjectiveData(id, elem, v) {
	var result = "false";
	var i = SCOGetObjectiveIndex(id);
	if (isNaN(i)) {
		i = parseInt(SCOGetValue("cmi.objectives._count"));
		if (isNaN(i)) i = 0;
		if (SCOSetValue("cmi.objectives." + i + ".id", id) == "true"){
			result = SCOSetValue("cmi.objectives." + i + "." + elem, v)
		}
	} else {
		result = SCOSetValue("cmi.objectives." + i + "." + elem, v);
		if (result != "true") {
			// Il sistema LMS potrebbe accettare solo voci di libro giornale
			i = parseInt(SCOGetValue("cmi.objectives._count"));
			if (!isNaN(i)) {
				if (SCOSetValue("cmi.objectives." + i + ".id", id) == "true"){
					result = SCOSetValue("cmi.objectives." + i + "." + elem, v)
				}
			}
		}
	}
	return result
}
function SCOGetObjectiveData(id, elem) {
	var i = SCOGetObjectiveIndex(id);
	if (!isNaN(i)) {
		return SCOGetValue("cmi.objectives." + i + "."+elem)
	}
	return ""
}
function SCOGetObjectiveIndex(id){
	var i = -1;
	var nCount = parseInt(SCOGetValue("cmi.objectives._count"));
	if (!isNaN(nCount)) {
		for (i = nCount-1; i >= 0; i--){ //Tornare indietro se il sistema LMS supporta l'inserimento di voci di libro giornale
			if (SCOGetValue("cmi.objectives." + i + ".id") == id) {
				return i
			}
		}
	}
	return NaN
}
// Funzioni di conversione di token o di abbreviazioni compatibili AICC in token SCORM
function AICCTokenToSCORMToken(strList,strTest){
	var a = strList.split(",");
	var c = strTest.substr(0,1).toLowerCase();
	for (i=0;i<a.length;i++){
			if (c == a[i].substr(0,1)) return a[i]
	}
	return strTest
}
function normalizeStatus(status){
	return AICCTokenToSCORMToken("completed,incomplete,not attempted,failed,passed", status)
}
function normalizeInteractionType(theType){
	return AICCTokenToSCORMToken("true-false,choice,fill-in,matching,performance,sequencing,likert,numeric", theType)
}
function normalizeInteractionResult(result){
	return AICCTokenToSCORMToken("correct,wrong,unanticipated,neutral", result)
}
// Rileva Internet Explorer
var g_bIsInternetExplorer = navigator.appName.indexOf("Microsoft") != -1;
// Gestisce messaggi fscommand da un filmato Flash, mappa nuovamente
// eventuali comandi del modello AICC di Flash in SCORM, se necessario
function main_DoFSCommand(command, args){

	//se gli alert sono abilitati
	if(alertEnabled){
		strDebug = "#command: " + command;
		strDebug = strDebug + " args: " + args;
		alert("strDebug " + strDebug);
	}
		
	var mainObj = g_bIsInternetExplorer ? main : document.main;
	// no-op se non è disponibile alcun API SCORM
	var myArgs = new String(args);
	var cmd = new String(command);
	var v = "";
	var err = "true";
	var arg1, arg2, n, s, i;
	var sep = myArgs.indexOf(",");
	if (sep > -1){
		arg1 = myArgs.substr(0, sep); // Nome dell'elemento di dati da ottenere da API
		arg2 = myArgs.substr(sep+1) 	// Nome della variabile del filmato Flash da impostare
	} else {
		arg1 = myArgs
	}
	if (!APIOK() && !apiDisabled){
		return;
	}
	
	if (cmd.substring(0,3) == "LMS"){
		// Gestisce FScommands "LMSxxx" (compatibile con il modello HTML fsSCORM)
		if ( cmd == "LMSInitialize" ){
			err = (APIOK() + "")
			// LMSInitialize viene automaticamente richiamato dal modello
		} else if ( cmd == "LMSSetValue" ){
			err = SCOSetValue(arg1,arg2)
			//se gli alert sono abilitati
			if(alertEnabled){
				alert("salvataggio suspend data");
			}
		} else if ( cmd == "LMSFinish" ){
			err = SCOFinish()
			// Gestito automaticamente dal modello; tuttavia, è possibile che
			// venga richiamato prima dal modello.
		}	else if ( cmd == "LMSCommit" ){
			err = SCOCommit()
		}	else if ( cmd == "LMSFlush" ){
			// no-op
			// LMSFlush non è definito in SCORM e, se richiamato, causa un errore di prova della suite
		}	else if ((arg2) && (arg2.length > 0)){
			if ( cmd == "LMSGetValue") {
				
				//se gli alert sono abilitati
				if(alertEnabled){
					alert("richiesta suspend data");
				}
				
				//se la ricerca api è disabilitata
				if(apiDisabled){
					mainObj.SetVariable(arg2,visitedStr);
					if(alertEnabled){
						alert("visitedStr " + visitedStr);
					}
				}
				else{
					mainObj.SetVariable(arg2,SCOGetValue(arg1));
					//se gli alert sono abilitati
					if(alertEnabled){
						alert("restituito *" + SCOGetValue(arg1) + "*");
					}
				}
				
				
			}	else if ( cmd == "LMSGetLastError") {
				mainObj.SetVariable(arg2, SCOGetLastError(arg1));
			}	else if ( cmd == "LMSGetErrorString") {
				mainObj.SetVariable(arg2, SCOGetLastError(arg1));
			}	else if ( cmd == "LMSGetDiagnostic") {
				mainObj.SetVariable(arg2, SCOGetDiagnostic(arg1));
			}	else {
				// per estensioni LMSGetxxxx sconosciute
				v = eval('g_objAPI.' + cmd + '(\"' + arg1 + '\")');
				mainObj.SetVariable(arg2,v);
			}
		} else if (cmd.substring(0,3) == "LMSGet") {
			err = "-2: No Flash variable specified"
		}
		// fine della gestione comandi "LMSxxx"
	} else if ((cmd.substring(0,6) == "MM_cmi")||(cmd.substring(0,6) == "CMISet")) {
		// Gestisce FScommands nei componenti di apprendimento di Macromedia.
		// Si tratta di convenzioni per l'uso dei modelli di dati AICC HACP.
		// Pertanto, mappano nuovamente i dati da AICC in SCORM come opportuno.
		var F_intData = myArgs.split(";");
		if (cmd == "MM_cmiSendInteractionInfo") {
			n = SCOGetValue("cmi.interactions._count");
			s = "cmi.interactions." + n + ".";
			// Individua errori grossolani per evitare che la prova di conformità a SCORM non venga superata
			// Se non viene fornito alcun ID per questa interazione, non è possibile registrarla
			v = F_intData[2]
			if ((v == null) || (v == "")) err = 201; // If no ID, makes no sense to record
			if (err =="true"){
				err = SCOSetValue(s + "id", v)
			}
			if (err =="true"){
				var re = new RegExp("[{}]","g")
				for (i=1; (i<9) && (err=="true"); i++){
					v = F_intData[i];
					if ((v == null) || (v == "")) continue
					if (i == 1){
						err = SCOSetValue(s + "time", v)
					} else if (i == 3){
						err = SCOSetValue(s + "objectives.0.id", v)
					} else if (i == 4){
						err = SCOSetValue(s + "type", normalizeInteractionType(v))
					} else if (i == 5){
						// strip out "{" and "}" from response
						v = v.replace(re, "");
						err = SCOSetValue(s + "correct_responses.0.pattern", v)
					} else if (i == 6){
						// strip out "{" and "}" from response
						v = v.replace(re, "");
						err = SCOSetValue(s + "student_response", v)
					} else if (i == 7){
						err = SCOSetValue(s + "result", normalizeInteractionResult(v))
					} else if (i == 8){
						err = SCOSetValue(s + "weighting", v)
					} else if (i == 9){
						err = SCOSetValue(s + "latency", v)
					}
				}
			}
		} else if (cmd == "MM_cmiSendObjectiveInfo"){
			err = SCOSetObjectiveData(F_intData[1], ".score.raw", F_intData[2])
			if (err=="true"){
				SCOSetObjectiveData(F_intData[1], ".status", normalizeStatus(F_intData[3]))
			}
		} else if ((cmd=="CMISetScore") ||(cmd=="MM_cmiSendScore")){
			err = SCOSetValue("cmi.core.score.raw", F_intData[0]);
		} else if ((cmd=="CMISetStatus") || (cmd=="MM_cmiSetLessonStatus")){
			err = SCOSetValue("cmi.core.lesson_status", normalizeStatus(F_intData[0]))
		} else if (cmd=="CMISetTime"){
			err = SCOSetValue("cmi.core.session_time", F_intData[0])
		} else if (cmd=="CMISetCompleted"){
			err = SCOSetStatusCompleted()
			//se gli alert sono abilitati
			if(alertEnabled){
				alert("corso completato");
			}
		} else if (cmd=="CMISetStarted"){
			err = SCOSetValue("cmi.core.lesson_status", "incomplete")
		} else if (cmd=="CMISetPassed"){
			err = SCOSetValue("cmi.core.lesson_status", "passed")
		} else if (cmd=="CMISetFailed"){
			err = SCOSetValue("cmi.core.lesson_status", "failed")
		} else if (cmd=="CMISetData"){
			err = SCOSetValue("cmi.suspend_data", F_intData[0])
		} else if (cmd=="CMISetLocation"){
			err = SCOSetValue("cmi.core.lesson_location", F_intData[0])
		} else if (cmd=="CMISetTimedOut"){
			err = SCOSetValue("cmi.core.exit", "time-out")
		} // Altri FScommands dei componenti di apprendimento sono azioni di tipo no-op in questo contesto
	} else {
		
		if (cmd=="CMIFinish" || cmd=="CMIExitAU"){
			err = SCOFinish()
		} else if (cmd=="CMIInitialize" || cmd=="MM_StartSession"){
			err = SCOInitialize()
		}
		
		//comandi personalizzati
		else if (cmd.substring(0,5) == "PFSC_"){
			
			//passo ad una funzione il comando	
			PFSCmanage(cmd);	
			
		}
		
		
		else {
				// Comando sconosciuto; potrebbe richiamare un'estensione API
				// Se il comando contiene un secondo argomento, è previsto un valore;
				// in caso contrario, si tratta di un semplice comando				
				if (eval('g_objAPI.' + cmd)) {
					v = eval('g_objAPI.' + cmd + '(\"' + arg1 + '\")');
					if ((arg2) && (arg2.length > 0)){
						mainObj.SetVariable(arg2,v)
					} else {
						err = v
					}
				} else {
					err = "false"
				}
		}
	}
	// Fine della traduzione e dell'elaborazione dei comandi
	// gestisce gli errori rilevati, ad esempio errori LMS
	if ((g_bShowApiErrors) && (err != "true")) {
		AlertUserOfAPIError(ExpandString(g_strFSAPIError, err, cmd, args))
	}
	return err
}
//-->
