var fondo;
var puntos=new Array();
var spline=new Array();
var cerrado=false;
var selpunto=false;
var mov=false;
function Inicio() {
fondo=new ObjetoCapa("fondo2");
initMouseEvents();
}

/*********************************************************************/
function CalcularFBasicas(orden,x,npuntos,nodos)
{ 
	var i,j,k=0;
	var d,e;
	var nplusc=npuntos + orden;
	var temp=new Array();
	var salida=new Array();
	// Calcula las funciones básicas de primer orden Ni,1

	for (i=1;i<nplusc-1;i++){
		if (x>=nodos[i] && x<nodos[i+1]){
			temp[i]=1;
		}
		else
		{
			temp[i]=0;
		}
	}
	for (j=2;j<orden;j++){
		for (i=1;i<nplusc-j;i++){
			if (temp[i]!=0) {
				if ((nodos[i+j-1]-nodos[i])==0)
					d=0;
				else
					d=((x-nodos[i])*temp[i])/(nodos[i+j-1]-nodos[i]);
			}
			else
				d=0;
			if (temp[i+1]!=0){
				if ((nodos[i+j]-nodos[i+1])==0)
					e=0;
				else
					e=((nodos[i+j]-x)*temp[i+1])/(nodos[i+j]-nodos[i+1]);
			}
			else
				e=0;
			temp[i]=d+e;
		}
	}
	 if (x == nodos[nplusc])
		 temp[npuntos]=1;
	 // Ponerlo todo en el array de salida
	 for (i=0;i<=npuntos;i++)
		 salida[i]=temp[i+1];
	 if (x==nodos[nplusc])
		 salida[npuntos+1]=1;
	return salida;
}

function CalcularNodos(n,orden,salida){
	var nplusc=n+orden-1;
	var nplus2=n+2;
	var i;
	var salida=new Array();
	salida[1]=0;
	var cont=0;
	for (i=2;i<nplusc+2;i++){
		cont++;
		if (i>orden-1 && i<nplus2){
			salida[i]=salida[i-1]+1;
		}
		else
		{
			salida[i]=salida[i-1];
		}
	}
	return salida;
}

function GenerarSpline(npuntos,orden,ppc,puntos){
	var i,j,k;
	var npuntos2=0;
	var icont=0;
	var t=0;
	var temp=new Array();
	var basicas=new Array();
	var nodos=new Array();
	var entrada=new Array();
	var p=new Array();
	for (i=0;i<npuntos;i++){
		npuntos2+=puntos[i].mult;
	}
	i=0,k=0;
	while (i<npuntos) {
		for (j=0;j<puntos[i].mult;j++) {
			entrada[k]=new ObjetoCoordenada(puntos[i].x,puntos[i].y);
			k++;
		}
		i++;
	}
	var nplusc=npuntos2+orden;
	for (i=0;i<npuntos2;i++){
		basicas[i]=0;
	}
	for (i=0;i<nplusc+2;i++){
		nodos[i]=0;
	}
	nodos=CalcularNodos(npuntos2,orden+1);
	if (nodos[npuntos2+orden+1]>0){
	for (t=0;t<=nodos[npuntos2+orden+1];t=t+(nodos[npuntos2+orden+1]/(npuntos2*(ppc-1))))
	{
		icont++;
		basicas=CalcularFBasicas(orden+1,t,npuntos2,nodos,basicas);
		temp[0]=0;
		temp[1]=0;
		i=0;
		for (i=0;i<npuntos2;i++) {
			temp[0]+=basicas[i]*entrada[i].x;
			temp[1]+=basicas[i]*entrada[i].y;
		}
		p[icont]=new ObjetoPunto(temp[0],temp[1],1,icont,1,1,'blue','spline',4);
	}
	//p[icont]=new ObjetoPunto(entrada[i-1].x,entrada[i-1].y,1,icont,1,1,'blue','spline',4);
	}
	window.status="Listo";
	return p;
}


/* Splines Uniformes ***********************************************************************/

function CalcularFBasicasU(orden,x,npuntos,nodos)
{ 
	var i,j,k=0;
	var d,e;
	var nplusc=npuntos + orden+1;
	var temp=new Array();
	var salida=new Array();
	// Calcula las funciones básicas de primer orden Ni,1

	for (i=1;i<nplusc-1;i++){
		if (x>=nodos[i] && x<nodos[i+1]){
			temp[i]=1;
		}
		else
		{
			temp[i]=0;
		}
	}
	if (x==nodos[npuntos+1]) {
		temp[npuntos]=1;
		temp[npuntos+1]=0;
	}
	for (j=2;j<orden+1;j++){
		for (i=1;i<nplusc-j;i++){
			if (temp[i]!=0) {
				if ((nodos[i+j-1]-nodos[i])==0)
					d=0;
				else
					d=((x-nodos[i])*temp[i])/(nodos[i+j-1]-nodos[i]);
			}
			else
				d=0;
			if (temp[i+1]!=0){
				if ((nodos[i+j]-nodos[i+1])==0)
					e=0;
				else
					e=((nodos[i+j]-x)*temp[i+1])/(nodos[i+j]-nodos[i+1]);
			}
			else
				e=0;
			temp[i]=d+e;
		}
	}
	 if (x == nodos[nplusc])
		 temp[npuntos]=1;
	 // Ponerlo todo en el array de salida
	 for (i=0;i<=npuntos;i++)
		 salida[i]=temp[i+1];
	 if (x==nodos[nplusc])
		 salida[npuntos+1]=1;
	 return salida;
}

function CalcularNodosU(n,orden) {
	var nplusc=n+orden;
	var salida=new Array()
	var i;
	for (i=1;i<nplusc;i++){
		salida[i]=i-1;
	}
	return salida;
}


function GenerarSplineU(npuntos,orden,ppc,puntos,cerrar){
	var i,j,k;
	var icont=0;
	var npuntos2=0;
	var t=0;
	var temp=new Array();
	var basicas=new Array();
	var nodos=new Array();
	var entrada=new Array();
	var p=new Array();
	var color='red';
	for (i=0;i<npuntos;i++){
		npuntos2+=puntos[i].mult;
	}
	i=0,k=0;
	while (i<npuntos) {
		for (j=0;j<puntos[i].mult;j++) {
			entrada[k]=new ObjetoCoordenada(puntos[i].x,puntos[i].y);
			k++;
		}
		i++;
	}

	if (cerrar) {
		for (i=npuntos2;i<npuntos2+orden;i++) {
			entrada[i]=new ObjetoCoordenada(entrada[i-npuntos2].x,entrada[i-npuntos2].y);
		}
	npuntos2+=orden;
	color='green';
	}
	var nplusc=npuntos2+orden+1;
	for (i=0;i<npuntos2;i++){
		basicas[i]=0;
	}
	for (i=0;i<nplusc+2;i++){
		nodos[i]=0;
	}
	nodos=CalcularNodosU(npuntos2,orden);
	if ((npuntos2-orden)>0){
	for (t=orden;t<=npuntos2;t=t+((npuntos2-orden)/(npuntos2*(ppc-1))))
	{
		icont++;
		basicas=CalcularFBasicasU(orden,t,npuntos2,nodos);
		temp[0]=0;
		temp[1]=0;
		for (i=1;i<npuntos2;i++) {
		temp[0]+=basicas[i]*entrada[i-1].x;
		temp[1]+=basicas[i]*entrada[i-1].y;
		}
		p[icont]=new ObjetoPunto(temp[0],temp[1],1,icont,1,1,color,'spline',4);
	}
	}
	window.status="Listo";
	return p;
}


/**************************************************************************/

function ComprobarDentro(x,y,capa) {
	if (checkWithin(x,y,capa.x,capa.x+capa.w,capa.y,capa.y+capa.h)) 
		return true
	else
		return false
}

function Regenerar() {
if (puntos.length==0) return
window.status="Regenerando Spline. Espere unos momentos...";
if (spline.length>2) {
	for (var i=1;i<spline.length;i++) {
	destruirCapa('spline'+i);
	}
}
if (br.ns) {
	if (document.layers[2].document.parametros.tipo.selectedIndex==0 && !cerrado)
	spline=GenerarSpline(puntos.length,parseInt(document.layers[2].document.parametros.grado.value),parseInt(document.layers[2].document.parametros.ppc.value),puntos);
	else
	spline=GenerarSplineU(puntos.length,parseInt(document.layers[2].document.parametros.grado.value),parseInt(document.layers[2].document.parametros.ppc.value),puntos,cerrado);
}
else {
	if (document.parametros.tipo.selectedIndex==0 && !cerrado)
	spline=GenerarSpline(puntos.length,parseInt(document.parametros.grado.value),parseInt(document.parametros.ppc.value),puntos);
	else
	spline=GenerarSplineU(puntos.length,parseInt(document.parametros.grado.value),parseInt(document.parametros.ppc.value),puntos,cerrado);
}
}

function BorrarSpline() {
window.status="Borrando spline...";
for (var i=1;i<spline.length;i++) {
destruirCapa('spline'+i);
}
for (var i=0;i<puntos.length;i++) {
destruirCapa('punto'+i);
destruirCapa('punto'+i+'sel');
drag.remove(puntos[i].capa);
drag.remove(puntos[i].capasel);
}
spline=new Array();
puntos=new Array();
window.status="Listo";
}

function ModificarPunto(e) {
if (!selpunto) {
alert("Seleccione un punto primero para poder modificarlo");
return false;
}

var num=parseInt(e.num.value);
if (ComprobarDentro(parseInt(e.x.value),parseInt(e.y.value),fondo)) {
puntos[num].x=parseInt(e.x.value);
puntos[num].y=parseInt(e.y.value);
puntos[num].mult=parseInt(e.multipun.value);
puntos[num].capa.moverA(puntos[num].x-1,puntos[num].y-1);
puntos[num].capasel.moverA(puntos[num].x-2,puntos[num].y-2);
Regenerar();
}
else {
window.status="El punto indicado se sale de la zona preparada para el spline, por favor, introduzca otro valor";
e.x.value=puntos[num].x;
e.y.value=puntos[num].y;
e.multipun.value=puntos[num].mult;
e.num.value=num;
}
}

function AnadirPunto(x,y){
OcultarSeleccionados();
selpunto=false;
if (cerrado){
	if (br.ns)
		document.layers[2].document.parametros.button3.value="Cerrar Spline";
	else
		document.parametros.button3.value="Cerrar Spline";
}
cerrado=false;
if (br.ns)
puntos[puntos.length]=new ObjetoPunto(x,y,parseInt(document.layers[2].document.parametros.multi.value),puntos.length,2,2,'black','punto',5);
else
puntos[puntos.length]=new ObjetoPunto(x,y,parseInt(document.parametros.multi.value),puntos.length,3,3,'black','punto',5);
Regenerar();
}

function CerrarSpline(e){
if (cerrado) {
	e.button3.value="Cerrar Spline";
	window.status="Abriendo Spline. Espere unos momentos...";
	}
else {
	e.button3.value="Abrir Spline";
	window.status="Cerrando Spline. Espere unos momentos...";
}
cerrado=!cerrado;
if (spline.length>2) {
	for (var i=1;i<spline.length;i++) {
	destruirCapa('spline'+i);
	}
}
if (br.ns) {
	if (document.layers[2].document.parametros.tipo.selectedIndex==0 && !cerrado)
	spline=GenerarSpline(puntos.length,parseInt(document.layers[2].document.parametros.grado.value),parseInt(document.layers[2].document.parametros.ppc.value),puntos);
	else
	spline=GenerarSplineU(puntos.length,parseInt(document.layers[2].document.parametros.grado.value),parseInt(document.layers[2].document.parametros.ppc.value),puntos,cerrado);
}
else {
	if (document.parametros.tipo.selectedIndex==0 && !cerrado)
	spline=GenerarSpline(puntos.length,parseInt(document.parametros.grado.value),parseInt(document.parametros.ppc.value),puntos);
	else
	spline=GenerarSplineU(puntos.length,parseInt(document.parametros.grado.value),parseInt(document.parametros.ppc.value),puntos,cerrado);
}
}

function ObjetoCoordenada(x,y) {
this.x=x;
this.y=y;
}

function ObjetoPunto(x,y,k,num,w,h,color,nombre,zindex){
this.x=x;
this.y=y;
this.mult=k;
this.num=num;
this.id=nombre+num;
if (nombre=="punto") {
	crearCapa(this.id,null,x-1,y-1,w,h,'',color,'visible',zindex,'cursor:move;');
	crearCapa(this.id+'sel',null,x-2,y-2,w+2,h+2,'','purple','hidden',zindex,'cursor:move;');
	this.capasel=new ObjetoCapa(this.id+'sel');
	}
else {
	crearCapa(this.id,null,x,y,w,h,'',color,'visible',zindex,'');
	}
this.capa=new ObjetoCapa(this.id);
if (nombre=="punto") {
drag.add(this.capa);
DragSetGrab(this.capa,-5,10,10,-5)
DragSetGrab(this.capasel,-5,10,10,-5)
}
}
drag.onDragStart=DragStart;
drag.onDragEnd=DragEnd;
drag.onDragMove=DragMove;

function OcultarSeleccionados() {
for (var i=0;i<puntos.length;i++) {
	puntos[i].capa.mostrar();
	puntos[i].capasel.ocultar();
	}
selpunto=false;
if (br.ns) {
document.layers[2].document.parametros.x.value='';
document.layers[2].document.parametros.y.value='';
document.layers[2].document.parametros.multipun.value='';
document.layers[2].document.parametros.num.value='';
}
else {
document.parametros.x.value='';
document.parametros.y.value='';
document.parametros.multipun.value='';
document.parametros.num.value='';
}
}

function DragStart(x,y) {
OcultarSeleccionados();
var num=parseInt(this.obj.id.substring(5,this.obj.id.length));
if (br.ns) {
document.layers[2].document.parametros.x.value=x;
document.layers[2].document.parametros.y.value=y;
document.layers[2].document.parametros.multipun.value=puntos[num].mult;
document.layers[2].document.parametros.num.value=num;
}
else {
document.parametros.x.value=x;
document.parametros.y.value=y;
document.parametros.multipun.value=puntos[num].mult;
document.parametros.num.value=num;
}

puntos[num].capa.ocultar();
drag.remove(puntos[num].capa);
puntos[num].capasel.mostrar();
drag.add(puntos[num].capasel);
selpunto=true;
mov=false;
}

function DragMove(x,y){
var num=parseInt(this.obj.id.substring(5,this.obj.id.length));
if (ComprobarDentro(x,y,fondo)) {
puntos[num].x=x-2;
puntos[num].y=y-2;
puntos[num].capa.moverA(puntos[num].x-1,puntos[num].y-1);
puntos[num].capasel.moverA(puntos[num].x-2,puntos[num].y-2);
if (br.ns) {
document.layers[2].document.parametros.x.value=x;
document.layers[2].document.parametros.y.value=y;
document.layers[2].document.parametros.multipun.value=puntos[num].mult;
document.layers[2].document.parametros.num.value=num;
}
else {
document.parametros.x.value=x;
document.parametros.y.value=y;
document.parametros.multipun.value=puntos[num].mult;
document.parametros.num.value=num;
}
}
else {
puntos[num].capa.moverA(puntos[num].x-1,puntos[num].y-1);
puntos[num].capasel.moverA(puntos[num].x-2,puntos[num].y-2);
}
mov=true;
}
function DragEnd(x,y){
if (!mov) return
var num=parseInt(this.obj.id.substring(5,this.obj.id.length));
puntos[num].x=x-2;
puntos[num].y=y-2;
if (br.ns) {
document.layers[2].document.parametros.x.value=x;
document.layers[2].document.parametros.y.value=y;
document.layers[2].document.parametros.multipun.value=puntos[num].mult;
document.layers[2].document.parametros.num.value=num;
}
else {
document.parametros.x.value=x;
document.parametros.y.value=y;
document.parametros.multipun.value=puntos[num].mult;
document.parametros.num.value=num;
}
if (ComprobarDentro(x,y,fondo)) {
puntos[num].capa.moverA(puntos[num].x-1,puntos[num].y-1);
puntos[num].capasel.moverA(puntos[num].x-2,puntos[num].y-2);
}
Regenerar();
}

function DefMouseDown(x,y){}
function DefMouseMove(x,y){}
function DefMouseUp(x,y){
if (ComprobarDentro(x,y,fondo)) {
	AnadirPunto(x,y);
	}
}
