var nFindAPITries = 0;
var API = null;
var maxTries = 500;
var APIVersion = "";
var lastObjective=-1;
var scorm_sessionstart;
// The ScanForAPI() function searches for an object named API_1484_11
// in the window that is passed into the function. If the object is
// found a reference to the object is returned to the calling function.
// If the instance is found the SCO now has a handle to the LMS
// provided API Instance. The function searches a maximum number
// of parents of the current window. If no object is found the
// function returns a null reference. This function also reassigns a
// value to the win parameter passed in, based on the number of
// parents. At the end of the function call, the win variable will be
// set to the upper most parent in the chain of parents.
function ScanForAPI(win)
{
	while ((win.API_1484_11 == null) && (win.parent != null)
	&& (win.parent != win))
	{
		nFindAPITries++;
		if (nFindAPITries > maxTries)
		{
			return null;
		}
		win = win.parent;
	}
	return win.API_1484_11;
}
/**
* ResetApi
* Oneclick 2009
* reinicia la API Scorm, permitiendo cambiar de OA desde una interfaz SD
*/
function ResetApi(){
	API = null;
	nuevoApi();
	lastObjective=-1;
	nFindAPITries = 0;
	GetAPI(window);
}
// The GetAPI() function begins the process of searching for the LMS
// provided API Instance. The function takes in a parameter that
// represents the current window. The function is built to search in a
// specific order and stop when the LMS provided API Instance is found.
// The function begins by searching the current window’s parent, if the
// current window has a parent. If the API Instance is not found, the
// function then checks to see if there are any opener windows. If
// the window has an opener, the function begins to look for the
// API Instance in the opener window.
function GetAPI(win)
{
		API = ScanForAPI(win);
	
		if ((win.parent != null) && (win.parent != win) && (API == null))
		{
			API = ScanForAPI(win.parent);
		}
		if ((API == null) && (win.opener != null))
		{
			API = ScanForAPI(win.opener);
		}
		if (API != null)
		{
			APIVersion = API.version;
		}
}

/**
* getSuspendData
* Recuperar datos guardados
* Para recuperar los datos se debe Inicializar comunicación con la API scorm primero.
*/
function getSuspendData(){
	var resultado = null;
	if(API!=null){
		resultado = API.GetValue("cmi.suspend_data");
		//alert("cmi.suspend_data: " + resultado);
	}
	return resultado;
}

/**
* setSuspendData
* Guardar datos
* PARAMETRO: datos = cualquier cadena de caracteres, límite 64000 caracteres
*/
function setSuspendData( datos ){
	var resultado = true;
	if(API!=null){

		if(!API.SetValue("cmi.suspend_data", datos)){
			alert("Error cmi.suspend_data -> "+API.GetLastError());
			resultado = false;
		}
		if(!API.SetValue("cmi.exit", "suspend")){
			alert("Error cmi.exit -> "+API.GetLastError());
			resultado = false;
		}
		API.Commit();
		parada();
	}
	return resultado;
}

/**
Informa a la API SCORM de que el estudiante ha iniciado la ejecucion del SCO. Sin puntuaciones

**/
function inicioSimple()
{
	var today=new Date();
	scorm_sessionstart = today.getTime();
	
	if(API!=null)
	{
		var result=API.Initialize("");
		result=API.SetValue("cmi.completion_status","incomplete");
	}
	return 1;
}

/**
Informa al LMS de que el estudiante ha iniciado la ejecucion del SCO

- minScore: minima puntuacion del OA. Si se definen objetivos deberia ser igual a la minima suma de puntuaciones de objetivos
- maxScore: maxima puntuacion del OA. Si se definen objetivos deberia ser igual a la maxima suma de puntuaciones de objetivos
**/
function inicio(minScore,maxScore)
{
	var today=new Date();
	scorm_sessionstart = today.getTime();
	
	if(API!=null)
	{
		var result=API.Initialize("");
		result=API.SetValue("cmi.completion_status","incomplete");
		if(!API.SetValue("cmi.score.min",minScore))
		{
			alert("Error score.min"+API.GetLastError());
		}
		if(!API.SetValue("cmi.score.max",maxScore))
		{
			alert("Error score.max"+API.GetLastError());
		}
	}
	return 1;
}
/**
Informa a la API SCORM de que el estudiante ha terminado el SCO. 
Si se definen objetivos esta funcion es invocada automaticamente al cumplirse todos los objetivos
**/
function fin()
{
	if(API!=null)
	{
		var result=API.SetValue("cmi.completion_status","completed");
		result = API.Terminate("");
		
		API=null;
		APIVersion="";
		
	}
}

/**
Informa al LMS de que el estudiante ha interrumpido el SCO. 
**/
function parada()
{
	if(API!=null)
	{
		result=API.Terminate("");
		API=null;
		APIVersion="";
	}
}
/**
Define un nuevo objetivo y le asigna un estado "incomplete". El primer objetivo definido tiene indice 0, el segundo 1 y asi sucesivamente.
- id: identificador del objetivo para el LMS
- minScore: minima puntuacion del objetivo
- maxScore: maxima puntuacion del objetivo
**/
function defineObjetivo(id,minScore,maxScore)
{
	if(API!=null)
	{
		lastObjective++;
		if(!API.GetValue("cmi.objectives."+lastObjective+".id"))
		{
			if(API.SetValue("cmi.objectives."+lastObjective+".id",id))
			{
				API.SetValue("cmi.objectives."+lastObjective+".completion_status","incomplete");
				if(!API.SetValue("cmi.objectives."+lastObjective+".score.min",minScore))
				{
					alert("Error score.min"+API.GetLastError());						
				}
				if(!API.SetValue("cmi.objectives."+lastObjective+".score.max",maxScore))
				{
					alert("Error score.max"+API.GetLastError());
				}
			}
		}
	}
}
/**
Buscamos la posición del objetivo en base a un ID (nombre pantalla)

- id: identificador del objetivo para el LMS
- score: puntuacion del objetivo
**/
function objetivo_puntuacion( id, score )
{
	if(API!=null)
	{
		var i = -1;
		var objcount = parseInt(API.GetValue("cmi.objectives._count"));
		for(i=0; i<objcount; i++)
		{
			var objid=API.GetValue("cmi.objectives."+i+".id");
			if(objid==id){
				break;
			}
			
		}
		if(i>-1){
			objetivo(i, score);
		}
	}
}
/**
Informa a la API SCORM de que se ha cumplido un objetivo con una determinada puntuacion. 
Si este era el ultimo objetivo que faltaba por cumplir, llama a la funcion fin()

- n: indice del objetivo
- score: puntuacion del objetivo

**/
function objetivo( n, score )
{
	if(API!=null){
		var result;
		if(!API.SetValue("cmi.objectives."+n+".completion_status","completed")){
			alert("Error completion_status"+API.GetLastError());
		}
		var score_anterior = API.GetValue("cmi.objectives."+n+".score.raw");
		//alert("score_anterior: " + score_anterior + " score: " + score);
		// Si la puntuación es mayor
		if(score_anterior && score_anterior<score){
			if(!API.SetValue("cmi.objectives."+n+".score.raw",score)){
				alert("Error score.raw"+API.GetLastError());
			}
		}
		// no tiene puntuación definida
		if(!score_anterior || score_anterior == ""){
			if(!API.SetValue("cmi.objectives."+n+".score.raw",score)){
				alert("Error score.raw"+API.GetLastError());
			}
		}
		var min= API.GetValue("cmi.objectives."+n+".score.min");
		var max= API.GetValue("cmi.objectives."+n+".score.max");
		if(max>min){
			if(!API.SetValue("cmi.objectives."+n+".score.raw",score)){
				alert("Error score.raw"+API.GetLastError());
			}
			if(!API.SetValue("cmi.objectives."+n+".score.scaled",-1+2*(score-min)/(max-min))){
				alert("Error score.scaled"+API.GetLastError());	
			}
		}
		var nn=API.GetValue("cmi.objectives._count");
		if(!nn){
			alert("Error="+API.GetLastError());
			return;
		}
		var status="completed";
		var scoret=0;
		for(i=0;i<nn;i++){
			var id=API.GetValue("cmi.objectives."+i+".id");
			if(!id){
				//alert("Error: "+API.GetLastError());
				break;
			}
			status=API.GetValue("cmi.objectives."+i+".completion_status");
			if(status!="completed"){
				break;
			}
			min= API.GetValue("cmi.objectives."+i+".score.min");
			max= API.GetValue("cmi.objectives."+i+".score.max");
			if(max>min){
				var scoreraw=Number(API.GetValue("cmi.objectives."+i+".score.raw"));
				scoret+=scoreraw;
			}
			
		}
		var session_time = parseInt(((new Date()).getTime() - scorm_sessionstart)/1000);
		API.SetValue("cmi.session_time","PT"+session_time+"S");
		
		var globalmin = API.GetValue("cmi.score.min")
		var globalmax = API.GetValue("cmi.score.max")
		API.SetValue("cmi.score.raw",scoret)
		scoret = -1+2*(scoret-globalmin)/(globalmax-globalmin);
		API.SetValue("cmi.score.scaled",scoret);
		if(status=="completed"){
			fin();
		}
	}
}
/**
Define un nuevo objetivo y le asigna un estado "incomplete". El primer objetivo definido tiene indice 0, el segundo 1 y asi sucesivamente. Sin puntuaciones.
- id: identificador del objetivo para el LMS
**/
function defineObjetivoSimple(id)
{
	if(API!=null)
	{
		lastObjective++;
		if(!API.GetValue("cmi.objectives."+lastObjective+".id"))
		{
			if(API.SetValue("cmi.objectives."+lastObjective+".id",id))
			{
				API.SetValue("cmi.objectives."+lastObjective+".completion_status","incomplete");
			}
		}
	}
}
/**
Informa al LMS de que se ha cumplido un objetivo. Si este era el ultimo objetivo que faltaba por cumplir, llama a la funcion fin(). Sin puntuaciones

- n: indice del objetivo
**/
function objetivoSimple(n){
	if(API!=null){
		var result;
		//if(!API.SetValue("cmi.objectives."+n+".completion_status","completed")){
		//	alert("Error completion_status"+API.GetLastError());
		//}
		var nn=API.GetValue("cmi.objectives._count");
		if(!nn){
//			alert("Error="+API.GetLastError());
			return;
		}
		var status="completed";
		for(i=0;i<nn;i++){
			var id=API.GetValue("cmi.objectives."+i+".id");
			if(!id){
				//alert("Error: "+API.GetLastError());
				break;
			}
			status=API.GetValue("cmi.objectives."+i+".completion_status");
			if(status!="completed"){
				break;
			}
		}
		if(status=="completed"){
			fin();
		}
	}
}
/**
Establece la puntuacion global del SCO. Solo deberia ser invocada si no se definen objetivos.

- score: puntuacion global del SCO

**/
function puntuacionglobal(score)
{
	if(API!=null)
	{
		var min= API.GetValue("cmi.score.min");
		var max= API.GetValue("cmiscore.max");
		if(max>min)
		{
			if(!API.SetValue("cmi.score.raw",score))
			{
				alert("Error score.raw"+API.GetLastError());
			}
			score=-1+2*(score-min)/(max-min);
			if(!API.SetValue("cmi.score.scaled",score))
			{
				alert("Error score.scaled"+API.GetLastError());
			}
		}
	}
}

GetAPI(window);
