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

}
