/* mekka intro               */
/* c a l o d o x   2 0 0 1   */

// nurbs ?? well not, but looks like

#include "main.h"
#include <math.h>
#include "vectors.h"


#define NURBS_MAX_POINTS	300
#define NURBS_MAX_SIDES		30




Vect3D NURBS_faces_nnormals[NURBS_MAX_SIDES][NURBS_MAX_POINTS];
Vect3D NURBS_faces_normals[NURBS_MAX_SIDES][NURBS_MAX_POINTS];
Vect3D NURBS_faces_points[NURBS_MAX_SIDES][NURBS_MAX_POINTS];


void NURBS_compute(int sides, int maxpoints, float param1)
{

	float borne=2*3.1415*2;
	float isteps=borne/(float)maxpoints;			//inherent a la fonction utilisee pour generer l'objet
	

	
	//calcule d'abord 1 lignee de points, qu'on va faire tourner ensuite autour de l'axe

	int index_pt=0;


//	fprintf(debugfile, "normal & points part1 \n");

	for (float i=0.0;i<borne-isteps;i+=isteps)
	{
		Vect3D v1,v2;
		Vect3D normal, axis;

		v1.x=i;
		v1.y=cos(sin(v1.x+param1));			//y1=f(i)
		v1.z=sin(v1.x+param1);
		
		v2.x=i+isteps;
		v2.y=cos(sin(v2.x+param1));		//y2=f(i+isteps)
		v2.z=sin(v2.x+param1);

		axis=Vect3D_Sub(v2,v1);	//v2-v1 -> gives the "axis", an approximation to the tangent

		normal.x=axis.y;		//find an orthogonal vector for the tangent in the XY plane 
		normal.y=-axis.x;
		normal.z=0;

		normal=Vect3D_Normalize(normal);


		float sectionsize=sin(sin(i*0.25))*cos(sin(TIMER_return_timer()*0.01));
		normal=Vect3D_MulScalar(normal, sectionsize);		//c'est ici que la section est modifiée.

		NURBS_faces_normals[0][index_pt]=normal;	
		NURBS_faces_points[0][index_pt]=v1;	

		//fprintf(debugfile, "%f %f %f %f %f %f %d \n", normal.x, normal.y, normal.z, v1.x, v1.y, v1.z, index_pt);

		index_pt++;

	}


	Vect3D n, p;

	
	//fprintf(debugfile, "rotated normals \n");

	for (int idxsides=0;idxsides<sides;idxsides++)
	{
		float theta=(2*3.1415)/sides;

		for (int idxpts=0;idxpts<maxpoints;idxpts++)
		{

		p=NURBS_faces_points[0][idxpts];
		n=NURBS_faces_normals[0][idxpts];
	
		Vect3D rotated_n=ArbitraryRotate(n, p, theta*idxsides);

		NURBS_faces_normals[idxsides][idxpts]=rotated_n;

		rotated_n=Vect3D_Normalize(rotated_n);
		NURBS_faces_nnormals[idxsides][idxpts]=rotated_n;
		
		//fprintf(debugfile, "%f %f %f %d \n", rotated_n.x, rotated_n.y, rotated_n.z, idxpts);
		}
	}

}



unsigned char NURBS_state=0;

void NURBS_test_object(int sides, int points, float rotat, int texture_id, float ecarte)
{


	glBindTexture(GL_TEXTURE_2D, texture_id);

	glBlendFunc(GL_SRC_ALPHA,GL_ONE);	// Blending Function For Translucency Based On Source Alpha Value
	glEnable(GL_BLEND);	
	glDisable(GL_DEPTH_TEST);

	float tt=ACCURATE_TIMER;
	glLoadIdentity();    

	glTranslatef(ecarte + sin(tt*0.001),cos(tt*0.001),-20.0);
	glRotatef(rotat,0.0f,1.0f,1.0f); 


	Vect3D n1,n2,n3,n4;
	Vect3D p1,p2,p3,p4;

	for (int i=0;i<sides;i++)
	{
		int ii=(i+1)%sides;

		for (int j=1;j<points-3;j++)
		{


			n1=NURBS_faces_normals[i][j];
			n2=NURBS_faces_normals[i][j+1];
		    n3=NURBS_faces_normals[ii][j+1];
		    n4=NURBS_faces_normals[ii][j];

			Vect3D a1=NURBS_faces_points[0][j];
			Vect3D a2=NURBS_faces_points[0][j+1];

			p1=Vect3D_Add(NURBS_faces_normals[i][j], a1);
			p2=Vect3D_Add(NURBS_faces_normals[i][j+1], a2);
			p3=Vect3D_Add(NURBS_faces_normals[ii][j+1], a2);
			p4=Vect3D_Add(NURBS_faces_normals[ii][j], a1);

		
		//	n1=ArbitraryRotate(n1, envmapaxis, TIMER_return_timer()*0.01);
		//	n2=ArbitraryRotate(n2, envmapaxis, TIMER_return_timer()*0.01);
		//	n3=ArbitraryRotate(n3, envmapaxis, TIMER_return_timer()*0.01);
		//	n4=ArbitraryRotate(n4, envmapaxis, TIMER_return_timer()*0.01);

	
/*
			n1=Vect3D_MulScalar(n1, 2.6);
			n2=Vect3D_MulScalar(n2, 2.6);
			n3=Vect3D_MulScalar(n3, 2.6);
			n4=Vect3D_MulScalar(n4, 2.6);

*/

	

			glBegin(GL_QUADS);
			

		
			
				glTexCoord3f(n1.x, n1.y, n1.z); 
				glVertex3f(p1.x, p1.y,  p1.z);
					glTexCoord3f(n2.x, n2.y, n2.z); 
				glVertex3f(p2.x, p2.y,  p2.z);	
					glTexCoord3f(n3.x, n3.y, n3.z); 
				glVertex3f(p3.x, p3.y,  p3.z);
					glTexCoord3f(n4.x, n4.y, n4.z); 
				glVertex3f(p4.x, p4.y,  p4.z);

			glEnd();

		}
	}

//	glPopMatrix();
//	glMatrixMode(GL_TEXTURE);
//	glPopMatrix();

//		  glDisable(GL_TEXTURE_GEN_S);
//			  glDisable(GL_TEXTURE_GEN_T);

	glDisable(GL_BLEND);	
	glEnable(GL_DEPTH_TEST);
}