#include <sys/types.h>
#include <sys/timeb.h>

#include "view.h"
#include <stdio.h>

#define SPACE ' '
#define NL    '/n'

/*globals for reading data*/
static float copX,copY,copZ;
static float vpnX,vpnY,vpnZ;
static float vuvX,vuvY,vuvZ;
static float angle;
static float hither;
static float resX,resY;
static float backRED,backGREEN,backBLUE;
static float lightX,lightY,lightZ;
static float red,green,blue,Kd,Ks,Shine,T,index_of_refraction;
static float x,y,z;
float nx,ny,nz;

static int NumVertices = 0;
static int NumFaces = 0;

/*globals for data declaration and viewing*/
static Vertex *vertex;
static FaceList *facelist;
static Surface *surface;
static View *view;

#ifdef MYPRINTING
void printOut()
{
	register int i;

	printf("COP %f %f %f\n",copX,copY,copZ);
	printf("VPN %f %f %f\n",vpnX,vpnY,vpnZ);
	printf("VUV %f %f %f\n",vuvX,vuvY,vuvZ);
	printf("Light position %f %f %f\n",lightX,lightY,lightZ);
	printf("colour %f %f %f\n",red,green,blue);
	printf("polygon vertices %d\n",NumVertices);

	for(i=0;i<NumVertices;++i) printf("%f %f %f\n",x[i],y[i],z[i]);
}
#endif

char getNext()
{
	char c;

	c = getchar();
	while(c==SPACE) c = getchar();

	return(c);
}


void viewing()
{
	scanf("\nfrom %f %f %f\n",&copX,&copY,&copZ);
	scanf("at %f %f %f\n",&vpnX,&vpnY,&vpnZ);
	vpnX -= copX;
	vpnY -= copY;
	vpnZ -= copZ;
	scanf("up %f %f %f\n",&vuvX,&vuvY,&vuvZ);
	scanf("angle %f\n",&angle);
	scanf("hither %f\n",&hither);
	scanf("resolution %f %f\n",&resX,&resY);

	setVRP(view,(double)copX,(double)copY,(double)copZ);
	setVPN(view,(double)vpnX,(double)vpnY,(double)vpnZ);
	setVUV(view,(double)vuvX,(double)vuvY,(double)vuvZ);
	setCOP(view,0.0,0.0,-2.0);
	setVPDView(view,(double)hither);
	setClipView(view,0.0,1000.0);
	setVPWindowView(view,-1.0,1.0,-1.0,1.0);
}

void background()
{
	scanf("%f %f %f\n",&backRED,&backGREEN,&backBLUE);
}

void light()
{
	scanf("%f %f %f\n",&lightX,&lightY,&lightZ);
}

void properties()
{
	scanf("%f %f %f %f %f %f %f %f\n",
			&red,&green,&blue,&Kd,&Ks,&Shine,&T,&index_of_refraction);
}

void patch()
{
	register int i;
	int n;
	Face *face;
	Shading *s;

	scanf("%d\n",&n);
	for(i=0;i<n;++i){
		scanf("%f %f %f %f %f %f\n",&x,&y,&z,&nx,&ny,&nz);
		atPutCoordVertex(vertex,NumVertices+i,(double)x,(double)y,(double)z);
	}

	face = newFace(vertex,NumVertices);
	for(i=1;i<n;++i) addToBackFace(face,NumVertices+i);

	s = newShading((double)red,(double)green,(double)blue);
	setShadingOfFace(face,s);
	atPutFaceList(facelist,NumFaces,face);

	NumFaces++;
	NumVertices += n;
}

void polygon()
{
	register int i;
	int n;
	Face *face;
	Shading *s;

	scanf("%d\n",&n);
	for(i=0;i<n;++i){
		scanf("%f %f %f\n",&x,&y,&z);
		atPutCoordVertex(vertex,NumVertices+i,(double)x,(double)y,(double)z);
	}

	face = newFace(vertex,NumVertices);
	for(i=1;i<n;++i) addToBackFace(face,NumVertices+i);

	s = newShading((double)red,(double)green,(double)blue);
	setShadingOfFace(face,s);
	atPutFaceList(facelist,NumFaces,face);

	NumFaces++;
	NumVertices += n;
}

void defaultAction(c)
char c;
{
	printf("An unexpected character '%c' has been encountered\n",c);
}


void convert()
{
	char c;

	c = getNext();
	while(c != EOF){
		switch(c){
			case 'v'        :       viewing();
							break;

			case 'b'        :       background();
							break;

			case 'l'        :       light();
							break;

			case 'f'        :       properties();
							break;

			case 'p'        :       if((c=getchar())=='p') patch();
							else polygon();
							break;

			default         :       defaultAction(c);
							break;
		}
		c = getNext();
	}
}

main()
{
	Index *index;
	Tree *t;
	Lighting *lighting;
	Light ambient,light;
	register int i,j,n;
	register Face *face;
	struct timeb tickCount1,tickCount2;
	REAL t1,t2;
	Vertex *sVertex;

	vertex = newVertex(12000);
	facelist = newFaceList(10000);

	/*initialise the viewing stuff*/
	initialiseDrawables();
	surface = newSurface(10,10,410,410);
	view = newView(surface);

	/*read the file*/
	convert();

	/*do the special for this - tetra only*/
	special(&vertex,facelist);

	/*initialise the lighting*/
	setIntensityOfLight(&ambient,0.5,0.5,0.5);
	lighting = newLighting(&ambient);

	setPositionOfLight(&light,(double)lightX,(double)lightY,(double)lightZ);
	setIntensityOfLight(&light,0.5,0.5,0.5);
	addLightToLighting(lighting,&light);

	/*set the view*/
	setView(view);

	/*set the plane equations and the lighting*/
	for(i=0;i<NEXTFreeFaceList(facelist);++i){
		setPlaneEqOfFace(atFaceList(facelist,i));

		setAmbientLightingOnFace((face=atFaceList(facelist,i)),&AMBIENT(lighting));
		for(j=0;j<NOOfLightsIn(lighting);++j)
			setCentreColourOfFace(face,&LIGHTOf(lighting,j),j);
	}

	/*make the tree*/


	index = makeSetFromFaceList(facelist);


	printf("%d ",NEXTFreeFaceList(facelist));

	ftime(&tickCount1);
	t1 = (REAL)(tickCount1.time + (tickCount1.millitm/1000.0));
	t = makeTree(facelist,index);
	ftime(&tickCount2);
	t2 = (REAL)(tickCount2.time + (tickCount2.millitm/1000.0));
	printf(" %f ",t2-t1);
	n = NEXTFreeFaceList(facelist);

	printf(" %d ",NEXTFreeFaceList(facelist));

	ftime(&tickCount1);
	t1 = (REAL)(tickCount1.time + (tickCount1.millitm/1000.0));

	setShadowsOnTree(t,facelist,lighting);

	ftime(&tickCount2);
	t2 = (REAL)(tickCount2.time + (tickCount2.millitm/1000.0));
	printf(" %f ",t2-t1);

	n = NEXTFreeFaceList(facelist);

	printf(" %d\n",NEXTFreeFaceList(facelist));

	displayTreeOnView(view,facelist,t);

	/*mainEventLoop(view,facelist,t); */
	/*delayOnDrawable(GETDrawableOfSurface(surface)); */

}
