#define PI              (3.14159265358979323846)

#include <sys/types.h>
#include <sys/timeb.h>
#include "view.h"
#include <stdio.h>


void printMatrix(m)
Matrix m;
{
	int i,j;

	for(i=0;i<4;++i){
		for(j=0;j<4;++j) printf(" %f ",m[i][j]);
		printf("\n");
	}
}

void tempStop()
{
	char c;
	c=getchar();
}

main()
{

	Vertex *roomVertex,*bookcaseVertex,*windowVertex,*deskVertex,
		   *qiskVertex,*macVertex,*bookVertex;
	FaceList *facelist;
	Index *index;
	Tree *t;
	View *view,*view2;
	Surface *surface,*surface2;
	TMatrix matT,matR,mat;
	Object *roomObj,*bookcaseObj,*windowObj,*deskObj,*qiskObj,*macObj,*bookObj[4];
	Object *bookcaseObj2,*deskObj2,*deskObj3,*bookcaseObj3;
	int i,j,n,m;
	Lighting *lighting;
	Light ambient,light;
	Face *face;
	struct timeb tickCount1,tickCount2;
	REAL t1,t2;

/*
#define PROFILING
*/
/*#define TWOLIGHTS */
/*#define NEARBOOKCASE */
#define FARBOOKCASE
#define NEARDESK
#define FARDESK

printf("7 ");


#ifdef PROFILING
	moncontrol(0);
#endif

	facelist = newFaceList(7000);


	/*enclosing room*/
	roomVertex = newVertex(12000);
	m = NEXTFreeFaceList(facelist);
	FrontRoom(roomVertex,facelist);
	n = NEXTFreeFaceList(facelist);
	roomObj = newObject(facelist,7);
	for(i=m;i<n;++i) addFaceToObject(roomObj,i);

	/*windows*/
	windowVertex = newVertex(500);
	m = NEXTFreeFaceList(facelist);
	Windows(windowVertex,facelist);
	n = NEXTFreeFaceList(facelist);
	windowObj = newObject(facelist,1);
	for(i=m; i<n; ++i) addFaceToObject(windowObj,i);

	/*large bookcase*/
	bookcaseVertex = newVertex(3000);
	m = NEXTFreeFaceList(facelist);
	BookCase(bookcaseVertex,facelist);
	n = NEXTFreeFaceList(facelist);
	bookcaseObj = newObject(facelist,5);
	for(i=m;i<n;++i) addFaceToObject(bookcaseObj,i);

	/*desk*/
	deskVertex = newVertex(2000);
	m = NEXTFreeFaceList(facelist);
	Desk(deskVertex,facelist);
	n = NEXTFreeFaceList(facelist);
	deskObj = newObject(facelist,1);
	for(i=m;i<n;++i) addFaceToObject(deskObj,i);


	/*qisk disk*/
	qiskVertex = newVertex(400);
	m = NEXTFreeFaceList(facelist);
	QiskDisk(qiskVertex,facelist);
	n = NEXTFreeFaceList(facelist);
	qiskObj = newObject(facelist,1);
	for(i=m;i<n;++i) addFaceToObject(qiskObj,i);

	/*mac*/
	macVertex = newVertex(2000);
	m = NEXTFreeFaceList(facelist);
	MacPlus(macVertex,facelist);
	n = NEXTFreeFaceList(facelist);
	macObj = newObject(facelist,1);
	for(i=m;i<n;++i) addFaceToObject(macObj,i);

	/*a book*/
	bookVertex = newVertex(400);
	m = NEXTFreeFaceList(facelist);
	Book(bookVertex,facelist);
	n = NEXTFreeFaceList(facelist);
	bookObj[0] = newObject(facelist,0);
	for(i=m;i<n;++i) addFaceToObject(bookObj[0],i);

	for(i=1;i<2;++i) bookObj[i] = cloneObject(bookObj[0]);

#ifdef NEARBOOKCASE
	bookcaseObj2 = cloneObject(bookcaseObj);
#endif
#ifdef FARBOOKCASE
	bookcaseObj3 = cloneObject(bookcaseObj);
#endif


#ifdef FARDESK
	deskObj2 = cloneObject(deskObj);
#endif
#ifdef NEARDESK
	deskObj3 = cloneObject(deskObj);
#endif

#ifdef NEARBOOKCASE
	addChildToObject(roomObj,bookcaseObj2);
	TRANSLATION(mat,80.0,130.0,0.0);
	setLocalMatrixOfObject(bookcaseObj2,&mat);
#endif


	addChildToObject(roomObj,bookcaseObj);
	TRANSLATION(mat,36.0,130.0,0.0);
	setLocalMatrixOfObject(bookcaseObj,&mat);

#ifdef FARBOOKCASE
	addChildToObject(roomObj,bookcaseObj3);
	TRANSLATION(mat,85.0,20.0,0.0);
	setLocalMatrixOfObject(bookcaseObj3,&mat);
#endif
	addChildToObject(roomObj,windowObj);

	addChildToObject(roomObj,deskObj);
	TRANSLATION(mat,32.0,3.0,29.1);
	setLocalMatrixOfObject(deskObj,&mat);

#ifdef FARDESK
	addChildToObject(roomObj,deskObj2);
	ZROTATION(matR,(PI/2.0));
	TRANSLATION(matT,120.0,45.0,29.1);
	multiplyMatrix(matR.TM,matT.TM,mat.TM);
	setLocalMatrixOfObject(deskObj2,&mat);
#endif

#ifdef NEARDESK
	addChildToObject(roomObj,deskObj3);
	ZROTATION(matR,(PI/2.0));
	TRANSLATION(matT,60.0,45.0,29.1);
	multiplyMatrix(matR.TM,matT.TM,mat.TM);
	setLocalMatrixOfObject(deskObj3,&mat);
#endif

	addChildToObject(deskObj,qiskObj);
	TRANSLATION(mat,29.0,5.0,0.1);
	setLocalMatrixOfObject(qiskObj,&mat);

	addChildToObject(qiskObj,macObj);
	TRANSLATION(mat,0.5,-0.5,2.6);
	setLocalMatrixOfObject(macObj,&mat);

	addChildToObject(bookcaseObj,bookObj[0]);
	TRANSLATION(mat,2.0,-8.0,57.76);
	setLocalMatrixOfObject(bookObj[0],&mat);

	addChildToObject(bookcaseObj,bookObj[1]);
	TRANSLATION(mat,20.0,-8.0,57.76);
	setLocalMatrixOfObject(bookObj[1],&mat);

	FLATTENObject(roomObj);
	setIntensityOfLight(&ambient,0.2,0.2,0.2);
	lighting = newLighting(&ambient);

	setPositionOfLight(&light,62.0,76.0,77.0);
	setIntensityOfLight(&light,0.6,0.6,0.6);
	addLightToLighting(lighting,&light);


#ifdef TWOLIGHTS
	setPositionOfLight(&light,-10.0,80.0,77.0);
	setIntensityOfLight(&light,0.5,0.5,0.5);
	addLightToLighting(lighting,&light);
#endif

/*
	setPositionOfLight(&light,100.0,100.0,77.0);
	setIntensityOfLight(&light,1.0,1.0,1.0);
	addLightToLighting(lighting,&light);
*/

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

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

#ifdef PROFILING
	moncontrol(1);
#endif

	setShadowsOnTree(t,facelist,lighting);

#ifdef PROFILING
	moncontrol(0);
#endif

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

	n = NEXTFreeFaceList(facelist);


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

#ifdef DRAWING
	initialiseDrawables();


	surface = newSurface(50,50,400,400);
	view = newView(surface);
	setVRP(view,-34.0,84.0,68.0);
	setVPN(view,1.0,0.0,0.0);
	setClipView(view,0.0,1000.0);
	setCOP(view,0.0,0.0,-4.0);
	setVUV(view,0.0,0.0,1.0);
	setVPWindowView(view,-3.0,3.0,-3.0,3.0);

	setView(view);
	displayTreeOnView(view,facelist,t);
	flushDrawable();
	delayOnDrawable(GETDrawableOfSurface(surface));
	clearDrawable();
	flushDrawable();

	setVRP(view,-15.0,84.0,68.0);
	setView(view);
	displayTreeOnView(view,facelist,t);
	flushDrawable();
	delayOnDrawable(GETDrawableOfSurface(surface));
	clearDrawable();
	flushDrawable();


	setVRP(view,10.0,84.0,68.0);
	setVPN(view,0.5,-0.5,0.0);
	setView(view);
	displayTreeOnView(view,facelist,t);
	flushDrawable();
	delayOnDrawable(GETDrawableOfSurface(surface));
	clearDrawable();
	flushDrawable();

	setVRP(view,10.0,84.0,68.0);
	setVPN(view,1.0,0.0,0.0);
	setView(view);
	displayTreeOnView(view,facelist,t);
	flushDrawable();
	delayOnDrawable(GETDrawableOfSurface(surface));
	clearDrawable();
	flushDrawable();

	setVRP(view,20.0,84.0,68.0);
	setView(view);
	displayTreeOnView(view,facelist,t);
	flushDrawable();
	delayOnDrawable(GETDrawableOfSurface(surface));
	clearDrawable();
	flushDrawable();

	setVRP(view,30.0,84.0,68.0);
	setView(view);
	displayTreeOnView(view,facelist,t);
	delayOnDrawable(GETDrawableOfSurface(surface));
	clearDrawable();

	setVRP(view,40.0,84.0,68.0);
	setView(view);
	displayTreeOnView(view,facelist,t);
	flushDrawable();
	delayOnDrawable(GETDrawableOfSurface(surface));
	clearDrawable();
	flushDrawable();

	setVRP(view,110.0,66.0,68.0);
	setVPN(view,-1.0,0.0,0.0);
	setView(view);
	displayTreeOnView(view,facelist,t);
	flushDrawable();
	delayOnDrawable(GETDrawableOfSurface(surface));
	clearDrawable();
	flushDrawable();

	setVRP(view,100.0,20.0,68.0);
	setVPN(view,-1.0,1.0,0.0);
	setView(view);
	displayTreeOnView(view,facelist,t);
	flushDrawable();
	delayOnDrawable(GETDrawableOfSurface(surface));
	clearDrawable();
	flushDrawable();

	setVRP(view,100.0,120.0,68.0);
	setVPDView(view,0.0);
	setClipView(view,0.0,1000.0);
	setCOP(view,0.0,0.0,-4.0);
	setVUV(view,0.0,0.0,1.0);
	setVPWindowView(view,-3.0,3.0,-3.0,3.0);
	setVPN(view,-1.0,-1.0,0.0);
	setView(view);
	displayTreeOnView(view,facelist,t);
	flushDrawable();
	delayOnDrawable(GETDrawableOfSurface(surface));
	clearDrawable();
	flushDrawable();

	setVRP(view,70.0,100.0,68.0);
	setVPDView(view,0.0);
	setClipView(view,0.0,1000.0);
	setCOP(view,0.0,0.0,-4.0);
	setVUV(view,0.0,0.0,1.0);
	setVPWindowView(view,-3.0,3.0,-3.0,3.0);
	setVPN(view,-1.0,-1.0,0.0);
	setView(view);
	displayTreeOnView(view,facelist,t);
	flushDrawable();
	delayOnDrawable(GETDrawableOfSurface(surface));

/*
	surface2 = newSurface(300,20,400,400);
	view2 = newView(surface2);
*/
#endif
	printf(" !tiling\n");
}


