var nFindAPITries = 0;
var API = null;
var maxTries = 500;
var APIVersion = "";
var lastObjective=-1;
// 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;
}
// 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)
{
		if ((win.parent != null) && (win.parent != win))
		{
			API = ScanForAPI(win.parent);
		}
		if ((API == null) && (win.opener != null))
		{
			API = ScanForAPI(win.opener);
		}
		if (API != null)
		{
			APIVersion = API.version;
		}
}

function inicioSimple()
{
/**
Informa al LMS de que el estudiante ha iniciado la ejecucion del SCO. Sin puntuaciones

**/
	if(API!=null)
	{
		var result=API.Initialize("");
		result=API.SetValue("cmi.completion_status","incomplete");
	}
	return 1;
}

function inicio(minScore,maxScore)
{
/**
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
**/
	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;
}

function fin()
{
/**
Informa al LMS de que el estudiante ha terminado el SCO. Si se definen objetivos esta funcion es invocada automaticamente al cumplirse todos los objetivos
**/
	if(API!=null)
	{
		var result=API.SetValue("cmi.completion_status","completed");
		result=API.Terminate("");
		API=null;
		APIVersion="";
	}
}

function parada()
{
/**
Informa al LMS de que el estudiante ha interrumpido el SCO. 
**/
	if(API!=null)
	{
		result=API.Terminate("");
		API=null;
		APIVersion="";
	}
}

function defineObjetivo(id,minScore,maxScore)
{
/**
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
**/
	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());
				}
			}
		}
	}
}

function objetivo(n,score)
{
/**
Informa al LMS 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
**/
	if(API!=null){
		var result;
		if(!API.SetValue("cmi.objectives."+n+".completion_status","completed")){
			alert("Error completion_status"+API.GetLastError());
		}
		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 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();
		}
	}
}

function defineObjetivoSimple(id)
{
/**
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
**/
	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");
			}
		}
	}
}

function objetivoSimple(n){
/**
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
**/
	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();
		}
	}
}

function puntuacionglobal(score)
{
/**
Establece la puntuacion global del SCO. Solo deberia ser invocada si no se definen objetivos.

- score: puntuacion global del SCO

**/
	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);
