/** * SCORM API Wrapper * Compatible con SCORM 1.2 */ (function() { 'use strict'; const SCORM = { API: null, APIHandle: null, isInitialized: false, isCompleted: false, /** * Buscar la API SCORM en el objeto window */ findAPI: function(win) { let findAttempts = 0; const findAttemptLimit = 7; let traceMsgPrefix = "SCORM.findAPI "; while ((win.API == null || win.API_1484_11 == null) && (win.parent != null) && (win.parent != win)) { findAttempts++; if (findAttempts > findAttemptLimit) { console.error(traceMsgPrefix + "Error: No se encontró la API SCORM después de " + findAttemptLimit + " intentos."); return null; } win = win.parent; } if (win.API != null) { return win.API; } else if (win.API_1484_11 != null) { return win.API_1484_11; } else { return null; } }, /** * Inicializar la conexión con SCORM */ initialize: function() { if (this.isInitialized) { return "true"; } this.API = this.findAPI(window); if (this.API == null) { console.warn("SCORM API no encontrada. Modo demo activado."); return "false"; } const result = this.API.LMSInitialize(""); if (result == "true") { this.isInitialized = true; console.log("SCORM inicializado correctamente"); } return result; }, /** * Obtener valor de SCORM */ getValue: function(element) { if (!this.isInitialized) { this.initialize(); } if (this.API == null) { // Modo demo: retornar valores por defecto return this.getDemoValue(element); } const value = this.API.LMSGetValue(element); const errorCode = this.API.LMSGetLastError().toString(); if (errorCode != "0") { console.warn("SCORM GetValue Error: " + this.API.LMSGetErrorString(errorCode)); return this.getDemoValue(element); } return value; }, /** * Establecer valor en SCORM */ setValue: function(element, value) { if (!this.isInitialized) { this.initialize(); } if (this.API == null) { // Modo demo: solo log console.log("SCORM SetValue (demo): " + element + " = " + value); return "true"; } const result = this.API.LMSSetValue(element, value); const errorCode = this.API.LMSGetLastError().toString(); if (errorCode != "0") { console.warn("SCORM SetValue Error: " + this.API.LMSGetErrorString(errorCode)); return "false"; } return result; }, /** * Commit (guardar cambios) */ commit: function() { if (this.API == null) { return "true"; } return this.API.LMSCommit(""); }, /** * Finalizar sesión SCORM */ terminate: function() { if (!this.isInitialized) { return "true"; } if (this.API == null) { return "true"; } const result = this.API.LMSFinish(""); this.isInitialized = false; return result; }, /** * Valores demo para cuando no hay API SCORM */ getDemoValue: function(element) { const demoValues = { "cmi.core.lesson_status": "incomplete", "cmi.core.score.raw": "0", "cmi.core.total_time": "00:00:00", "cmi.core.lesson_location": "1", "cmi.core.student_name": "Usuario Demo" }; return demoValues[element] || ""; }, /** * Marcar como completado */ setCompleted: function() { this.setValue("cmi.core.lesson_status", "completed"); this.setValue("cmi.core.score.raw", "100"); this.commit(); this.isCompleted = true; }, /** * Actualizar progreso */ updateProgress: function(currentSection, totalSections) { const progress = Math.round((currentSection / totalSections) * 100); this.setValue("cmi.core.lesson_location", currentSection.toString()); this.setValue("cmi.core.score.raw", progress.toString()); if (currentSection === totalSections) { this.setValue("cmi.core.lesson_status", "completed"); } else { this.setValue("cmi.core.lesson_status", "incomplete"); } this.commit(); } }; // Inicializar automáticamente SCORM.initialize(); // Exponer globalmente window.SCORM = SCORM; })();