﻿$TTFlash con tracciamento SCORM 2004
$DS
Modello di pubblicazione per comunicazioni SCORM 2004. È stato modificato specificamente per supportare le interazioni di apprendimento. Include JavaScript per trovare e inizializzare un oggetto ADL API per SCORM 2004 e il comando FSCommand 'glue' per consentire la chiamata delle funzioni LMS mediante Flash.

$DF

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="it" lang="it">
<head>
$CS
<script type="text/javascript" language="JavaScript" name="fsIeVbscript">
<!--
// Hook per Internet Explorer
if (navigator.appName && navigator.appName.indexOf("Microsoft") != -1 && navigator.userAgent.indexOf("Windows") != -1 && navigator.userAgent.indexOf("Windows 3.1") == -1) {
	document.write('<script language=\"VBScript\"\>\n');
	document.write('On Error Resume Next\n');
	document.write('Sub $TI_FSCommand(ByVal command, ByVal args)\n');
	document.write('	Call $TI_DoFSCommand(command, args)\n');
	document.write('End Sub\n');
	document.write('</script\>\n');
}
//-->
</script>
<title>$TI</title>
</head>
<script type="text/javascript" language="JavaScript" name="cmifrag">
<!--

// FS SCORM - adattatore fscommand per ADL SCORM 2004 e per le interazioni di apprendimento di Flash MX 2004
// versione 1.0    12/10/04
// 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.
// Metodo di ricerca di un oggetto API (0 - dal basso verso l'alto; 1 - dall'alto verso il basso)
var g_intAPIOrder = 1;
var g_bShowApiErrors = false; 	// impostate su true per mostrare i messaggi di errore

var g_bInitializeOnLoad = true; // impostate su false per non inizializzare LMS al caricamento della pagina HTML

// Traducete queste stringhe se g_bShowApiErrors è true e dovete 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.";

// Impostate g_bSetCompletedAutomatically su true se desiderate 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") "passed" or "failed" (both of which imply "completed")"
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".
// Impostate su null se il codice ActionScript di Flash usa un proprio metodo per determinare lo stato "riuscito" e "non riuscito"; in caso contrario, impostate 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 modificate nessun valore dopo questa riga se non siete certi dell'operazione che state 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. Impostatelo su false se non desiderate 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;

var g_varInterval = "";			// intervallo globale
var g_intIntervalSecs = 3 		// Numero di secondi di attesa per il caricamento dell'API SCORM
var g_intPollSecs = 0.25			// Numero di secondi per il polling dell'API
var g_intCurrentTime = new Date().getTime();
var g_intAPI = 0;				// Tipo di API da iniziare a cercare; valori consentiti: 0 - SCORM 2004; 1 - SCORM 1.2 (o 1.1)
var g_aryAPI = ["1.0", "0.2"]	// Array che memorizza le versioni API
var g_strAPIVersion = -1;

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)
{
	// Cerca nella gerarchia delle finestre un oggetto di nome "API_1484_11" per SCORM 2004 o "API" per SCORM 1.2 o precedente
	// Cerca nella finestra corrente (win) e ricorsivamente in ogni fotogramma secondario
	if(g_intAPI == 0)
	{
		if(win.API_1484_11 != null)
		{
			return win.API_1484_11;
		}
	} else if(g_intAPI == 1 || g_intAPI == "") {
		if (win.API != null)
		{
			g_strAPIVersion = g_aryAPI[g_intAPI];
			return win.API;
		}
	}

	if (win.length > 0)  // verifica fotogrammi
	{
		for (var i=0;i<win.length;i++)
		{
			var objAPI = findAPI(win.frames[i]);
			if (objAPI != null)
			{
				return objAPI;
			}
		}
	}
	return null;
}


function getAPI(intAPISearchOrder)
{
	// Se il parametro intAPISearchOrder è 0, la ricerca inizia dalla finestra corrente e procede verso l'alto; se è 1 la ricerca inizia dalla finestra di livello superiore e procede verso il basso.
	var objAPI = null;
	intAPISearchOrder=((typeof(intAPISearchOrder)=='undefined')?0:intAPISearchOrder);
	if(intAPISearchOrder==0)
	{
		// inizia dalla finestra corrente e sale ricorsivamente attraverso le finestre/i fotogrammi principali
		objAPI = findAPI(window);
		if((objAPI==null) && (window.opener != null) && (typeof(window.opener) != "undefined"))
		{
			objAPI = findAPI(window.opener);
		} else if((objAPI==null) && (window.parent != null) && (typeof(window.parent) != "undefined")) {
			objAPI = findAPI(window.parent);
		}
		if((objAPI==null) && (g_intAPI < (g_aryAPI.length-1)))
		{
			g_intAPI++;
			objAPI = getAPI(intAPISearchOrder);
		}
	} else {
		// inizia dalla finestra di livello superiore e scende ricorsivamente attraverso i fotogrammi secondari
		objAPI = findAPI(this.top);

		if (objAPI == null)
		{
			// L'API non è stata trovata nella gerarchia di finestre corrente. Se la finestra corrente dispone di una finestra di apertura (è stata aperta da un'altra finestra), verificate la gerarchia di finestre della finestra di apertura.
			objTopWindow=window.top;

			objTopWindow = objTopWindow.opener;

			while (objTopWindow && !objAPI)
			{
				// verifica della finestra di apertura in corso
				objAPI = findAPI(objTopWindow.top);
				if (objAPI==null) objTopWindow = objTopWindow.opener;
			}
			if(objAPI==null && g_intAPI < (g_aryAPI.length-1))
			{
				g_intAPI++;
				objAPI = getAPI(intAPISearchOrder);
			}
		}
	}
	if(objAPI==null)
	{
		// impossibile trovare l'API
	} else if(objAPI != null && g_strAPIVersion == -1) {
		g_strAPIVersion = objAPI.version;
	}

	return objAPI;
}

function waitForAPI()
{
	if(new Date().getTime() > (g_intCurrentTime + g_intIntervalSecs*1000) || APIOK())
	{
		// timeout o API trovata
		clearInterval(g_varInterval);
		if(!APIOK())
		{
			g_objAPI = null;
		} else {
			if (g_bInitializeOnLoad) {
				SCOInitialize()
			}
		}
	} else {
		g_objAPI = getAPI(g_intAPIOrder);
	}
}

function APIOK() {
	return ((typeof(g_objAPI)!= "undefined") && (g_objAPI != null))
}

function SCOInitialize() {
	var err = true;
	if (!g_bInitDone) {
		if (!APIOK()) {
			AlertUserOfAPIError(g_strAPINotFound);
			err = false
		} else {
			err = g_objAPI.Initialize("");
			if (err == "true") {
				g_bSCOBrowse = (g_objAPI.GetValue("cmi.mode") == "browse");
				if (!g_bSCOBrowse) {
					if (g_objAPI.GetValue("cmi.completion_status") == "not attempted") {
						err = g_objAPI.SetValue("cmi.completion_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.Terminate("") == "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.GetValue(nam.toString()):"")}
function SCOCommit()					{return ((APIOK())?g_objAPI.Commit(""):"false")}
function SCOGetLastError()		{return ((APIOK())?g_objAPI.GetLastError():"-1")}
function SCOGetErrorString(n)	{return ((APIOK())?g_objAPI.GetErrorString(n):"No API")}
function SCOGetDiagnostic(p)	{return ((APIOK())?g_objAPI.GetDiagnostic(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.score.raw") err = privReportRawScore(val)
	if (err == ""){
			err = g_objAPI.SetValue(nam,val.toString() + "");
			if (err != "true") return err
	}
	if (nam == "cmi.score.min"){
		g_bMinScoreAcquired = true;
		g_nSCO_ScoreMin = val
	}
	else if (nam == "cmi.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.SetValue("cmi.score.min",g_nSCO_ScoreMin+"")!= "true") return "false"
	}
	if (!g_bMaxScoreAcquired){
		if (g_objAPI.SetValue("cmi.score.max",g_nSCO_ScoreMax+"")!= "true") return "false"
	}
	if (g_objAPI.SetValue("cmi.score.raw", nRaw)!= "true") return "false";
	g_bMinScoreAcquired = false;
	g_bMaxScoreAcquired = false;
	if (!g_bMasteryScoreInitialized){
		var nTemp = SCOGetValue("cmi.scaled_passing_score");
		nTemp = (nTemp <= 0?0:nTemp * 100);
		var nMasteryScore = parseInt(nTemp,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.success_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 = "PT" + h.substr(h.length-4)+"H"+m.substr(m.length-2)+"M";
	hms += s.substr(s.length-2)+"S";
	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.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.completion_status");
	if (SCOGetValue("cmi.lesson_mode") != "browse"){
		if ((stat!="completed") && (stat != "passed") && (stat != "failed")){
			return SCOSetValue("cmi.completion_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--){ //Tornate 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){
	var strInteractionResult = AICCTokenToSCORMToken("correct,wrong,unanticipated,neutral", result)
	strInteractionResult = (strInteractionResult=="wrong"?"incorrect":strInteractionResult);
	return strInteractionResult;
}

function checkInteractionResponse(response_str)
{
	var result_str = "";
	for(var char_int=0;char_int<response_str.length;char_int++)
	{
		if(response_str.substr(char_int,1) == "." || response_str.substr(char_int,1) == ",")
		{
			if(response_str.substr(char_int - 1,1) != "[" && response_str.substr(char_int + 1,1) != "]")
			{
				result_str += "[" + response_str.substr(char_int,1) + "]";
			} else {
				result_str += response_str.substr(char_int,1);
			}
		} else {
			result_str += response_str.substr(char_int,1);
		}
	}
	result_str = (result_str==""?"0":result_str);
	return result_str;
}

function formatTimestamp(time_var)
{
	return formatDate() + "T" + formatTime(time_var, undefined, undefined, 2);
}


// ******************************************************************
// *
// *     Metodo:           formatTime
// *     Descrizione:      formatta i secondi (passati come parametro) in PTxHyMzS
// *     Valori restituiti:          stringa (ora formattata come HHHH:MM:SS)
// *
// ******************************************************************
function formatTime(time_var, minutes_str, seconds_str, typeFormat_int)
{
	var days_str, hours_str, formattedTime_str;
	days_str = "0";
	if(time_var == undefined)
	{
		// crea l'ora in base all'ora corrente di oggi
		var time_obj = new Date();
		hours_str = time_obj.getHours();
		minutes_str = time_obj.getMinutes();
		seconds_str = time_obj.getSeconds();
	} else if(typeof(time_var) == "string" && time_var.indexOf(":") > -1) {
		var time_obj = time_var.split(":");
		hours_str = time_obj[0];
		minutes_str = time_obj[1];
		seconds_str = time_obj[2];
	} else {
		days_str    = "0";
		seconds_str = "0";
		minutes_str = "0";
		hours_str     = "0";

		seconds_str = Math.round(time_var);
		if(seconds_str > 59)
		{
			minutes_str = Math.round(seconds_str / 60);
			seconds_str = seconds_str - (minutes_str * 60);
		}
		if(minutes_str > 59)
		{
			hours_str = Math.round(minutes_str / 60);
			minutes_str = minutes_str - (hours_str * 60);
		}
		if(hours_str > 23)
		{
			days_str = Math.round(hours_str / 24);
			hours_str = hours_str - (days_str * 24);
		}
	}

	if(typeFormat_int == undefined || typeFormat_int == 1)
	{
		formattedTime_str = "P";

		if(days_str != "0")
		{
			formattedTime_str += days_str + "D";
		}
		formattedTime_str += "T" + hours_str + "H" + minutes_str + "M" + seconds_str + "S";
	} else {
		formattedTime_str = formatNum(hours_str, 2) + ":" + formatNum(minutes_str, 2) + ":" + formatNum(seconds_str, 2);
	}
	return formattedTime_str;
}

// ******************************************************************
// *
// *     Metodo:           formatDate
// *     Descrizione:      formatta i secondi o "MM/GG/AAAA"
// *     Valori restituiti:          stringa (data formattata come "AAAA-MM-GG")
// *
// ******************************************************************
function formatDate(date_var, day_str, year_str)
{
	if (date_var == undefined) {
		// Crea data in base alla data di oggi
		var date_obj = new Date();
		date_var = formatNum((date_obj.getMonth()+1), 2);
		day_str  = formatNum((date_obj.getDate()), 2);
		year_str = (date_obj.getFullYear());
	} else if(typeof(date_var) == "string" && date_var.indexOf("/") > -1) {
		// Converti da MM/GG/AAAA
		var date_obj = date_var.split("/");
		date_var = formatNum(date_obj[0], 2);
		day_str  = formatNum(date_obj[1], 2);
		year_str = formatNum(date_obj[2], 4);
	}
	var formattedDate_str = (year_str + "-" + date_var + "-" + day_str);
	return formattedDate_str;
}

// ******************************************************************
// *
// *    Metodo:         formatNum
// *    Descrizione:     converte il numero passato a questa funzione in un valore con zeri di riempimento, generalmente un numero di 2 o 4 cifre (ad es. 2 in 02 oppure 2 in 0002)
// *    Valori restituiti:        stringa (riempita con numero di zeri passati
// *
// ******************************************************************
function formatNum (initialValue_var, numToPad_int)
{
	var paddedValue_str = "";                         // Stringa; contiene il valore riempito con zeri
	var i = 0;                                     // Intero; variabile utilizzata per la ripetizione ciclica
	var initialValue_str = initialValue_var.toString();    // Stringa; converte il parametro "initializeValue_var" in una stringa in modo esplicito

	if (initialValue_str.length > numToPad_int)
	{
		// errore - la lunghezza iniziale del valore supera già il numero da riempire.  Restituisce initialValue_var senza riempimento aggiuntivo
	} else {
		for (var i = 1; i <= (numToPad_int - initialValue_str.length); i++)
		{
			paddedValue_str = paddedValue_str + "0";
		}
	}
	paddedValue_str = paddedValue_str + initialValue_var;
	return paddedValue_str;
}

// 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 $TI_DoFSCommand(command, args){

	var $TIObj = g_bIsInternetExplorer ? $TI : document.$TI;

	// 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()) 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" ){
			alert('LMSSetValue: \r\rArg1: ' + arg1 + '\rArg2: ' + arg2);
			err = SCOSetValue(arg1,arg2)
		} 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") {
				alert('LMSSetValue: \r\rArg1: ' + arg1 + '\rArg2: ' + arg2);
				$TIObj.SetVariable(arg2, SCOGetValue(arg1));
			}	else if ( cmd == "LMSGetLastError") {
				$TIObj.SetVariable(arg2, SCOGetLastError(arg1));
			}	else if ( cmd == "LMSGetErrorString") {
				$TIObj.SetVariable(arg2, SCOGetLastError(arg1));
			}	else if ( cmd == "LMSGetDiagnostic") {
				$TIObj.SetVariable(arg2, SCOGetDiagnostic(arg1));
			}	else {
				// per estensioni LMSGetxxxx sconosciute
				v = eval('g_objAPI.' + cmd + '(\"' + arg1 + '\")');
				$TIObj.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 + "timestamp", formatTimestamp(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", checkInteractionResponse(v))
					} else if (i == 6){
						// strip out "{" and "}" from response
						v = v.replace(re, "");
						err = SCOSetValue(s + "learner_response", checkInteractionResponse(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.score.raw", F_intData[0]);
		} else if ((cmd=="CMISetStatus") || (cmd=="MM_cmiSetLessonStatus")){
			var strTempStatus = normalizeStatus(F_intData[0]);
			if (strTempStatus == "passed" || strTempStatus == "failed")
			{
				err = SCOSetValue("cmi.success_status", normalizeStatus(F_intData[0]))
			} else {
				err = SCOSetValue("cmi.completion_status", normalizeStatus(F_intData[0]))
			}
		} else if (cmd=="CMISetTime"){
			err = SCOSetValue("cmi.session_time", formatTime(F_intData[0]))
		} else if (cmd=="CMISetCompleted"){
			err = SCOSetStatusCompleted()
		} else if (cmd=="CMISetStarted"){
			err = SCOSetValue("cmi.completion_status", "incomplete")
		} else if (cmd=="CMISetPassed"){
			SCOSetValue("cmi.completion_status", "completed");
			err = SCOSetValue("cmi.success_status", "passed")
		} else if (cmd=="CMISetFailed"){
			SCOSetValue("cmi.completion_status", "completed");
			err = SCOSetValue("cmi.success_status", "failed")
		} else if (cmd=="CMISetData"){
			err = SCOSetValue("cmi.suspend_data", F_intData[0])
		} else if (cmd=="CMISetLocation"){
			err = SCOSetValue("cmi.location", F_intData[0])
		} else if (cmd=="CMISetTimedOut"){
			err = SCOSetValue("cmi.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()
		} 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)){
					$TIObj.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
}
//-->
</script>
<body bgcolor="$BG" onunload="SCOFinish()" onbeforeunload="SCOFinish()">
<script type="text/javascript" language="JavaScript" name="earlyInit">
<!--
// Determina se tentare l'inizializzazione API prima del caricamento del filmato nel caso in cui sia presente codice ActionScript eseguito prima che il resto della pagina HTML venga caricata completamente. 
// Questa operazione è configurabile impostando il parametro booleano globale (g_bInitializeOnLoad) all'inizio di questo file. Il valore predefinito è TRUE.

// Cerca API SCORM
g_varInterval = setInterval('waitForAPI()', (g_intPollSecs * 1000));

//-->
</script>
<!-- URL utilizzato nel filmato-->
$MU
<!-- testo utilizzato nel filmato-->
$MT
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=$FV,$JR,$NR,0" id="$TI" width="$WI" height="$HE" align="$HA">
<param name="allowScriptAccess" value="sameDomain" />
$PO
<embed $PEwidth="$WI" height="$HE" name="$TI" align="$HA" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer_it" />
</object>
</body>
</html>
