#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gltk.h>

float xoff,yoff,zoff;
float xrot,yrot,zrot;
float xchange,ychange,zchange;

void reshape(int width, int height) {

        // Set the new viewport size
        glViewport(0, 0, (GLint)width, (GLint)height);

        // Choose the projection matrix to be the matrix 
        // manipulated by the following calls
        glMatrixMode(GL_PROJECTION);

        // Set the projection matrix to be the identity matrix
        glLoadIdentity();
	glTranslatef(-(xoff),-(yoff),-(zoff));
	glTranslatef(0,0,-10);
//	glTranslatef(xoff,yoff,zoff);
//	glRotatef(xrot,1,0,0);
//	glRotatef(yrot,0,1,0);
//	glRotatef(zrot,0,0,1);
        glFrustum(-200.0, 200.0, -200.0, 200.0, -200.0, 200.0);

	tkSwapBuffers();

        // Choose the modelview matrix to be the matrix
        // manipulated by further calls
        glMatrixMode(GL_MODELVIEW);
}

GLenum key_down(int key, GLenum state) {
  
  xchange = xoff;
  ychange = yoff;
  zchange = zoff;

        if ((key == TK_ESCAPE) || (key == TK_q) || (key == TK_Q))
                tkQuit();

	switch (key)
	  {
	  case TK_ESCAPE:
	    tkQuit();
	    printf("\n\n");
	    break;
	  case TK_q:
	    tkQuit();
	    printf("\n\n");
	    break;
	  case TK_Q:
	    printf("\n\n");
	    tkQuit();
	    break;

	  case TK_UP:
	    xchange += 1;
	    break;
	  case TK_DOWN:
	    xchange -= 1;
	    break;

	  case TK_9:
	    zchange += 1;
	    break;
	  case TK_3:
	    zchange -= 1;
	    break;

	  }

	printf("VP: %f %f %f Rot: %f %f %f\r",xchange,ychange,zchange,xrot,yrot,zrot);
	fflush(stdout);

}

void draw(void) 
{
  FILE *inf;
  float mx,my,mz,xsiz,ysiz,zsiz;

  // Clear the RGB buffer and the depth buffer
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glTranslatef(-(xoff),-(yoff),-(zoff));
  glTranslatef(xchange,ychange,zchange);
  xoff=xchange;
  yoff=ychange;
  zoff=zchange;

//  glRotatef(xrot,1,0,0);
//  glRotatef(yrot,0,1,0);
//  glRotatef(zrot,0,0,1);
//  glOrtho(-20.0, 20.0, -20.0, 20.0, -20.0, 20.0);
//  glFlush();
  glMatrixMode(GL_MODELVIEW);

  inf = fopen("inf.dat","r");

  while (fscanf(inf,"%f %f %f %f %f %f\n",&mx,&my,&mz,&xsiz,&ysiz,&zsiz) != EOF)
    {
//      printf("Cube at %f x %f x %f is %f x %f x %f.\n",mx,my,mz,xsiz,ysiz,zsiz);
      // Set the modelview matrix to be the identity matrix
      glLoadIdentity();
      glTranslatef(mx,my,mz);
      tkSolidBox(0,xsiz,ysiz,zsiz);

    }

  glLoadIdentity();
  glTranslatef(0,0,0);
  tkSolidSphere(0,2);

  glFlush();
  fclose(inf);
  tkSwapBuffers();
}


void main(int argc, char **argv) {
  GLfloat specular [] = { 1.0, 1.0, 1.0, 1.0 };
  GLfloat shininess [] = { 100.0 };
  GLfloat position [] = { 1.0, 1.0, 1.0, 0.0 };

  printf("Room Renderer 0.01\n");

  xoff = 0;
  yoff = 0;
  zoff = -10;

  xchange = 0;
  ychange = 0;
  zchange = -10;

        // Set top left corner of window to be at location (0, 0)
        // Set the window size to be 500x500 pixels
        tkInitPosition(0, 0, 500, 500);

        // Initialize the RGB and Depth buffers
        tkInitDisplayMode(TK_RGB | TK_DEPTH | TK_DOUBLE);


	     if (tkInitWindow("Room Renderer") == GL_FALSE) {
                tkQuit();
	     }

        // Set the clear color to black
        glClearColor(0.0, 0.0, 0.0, 0.0);

        // Set the shading model
        glShadeModel(GL_SMOOTH);

        // Set the polygon mode to fill
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

        // Enable depth testing for hidden line removal
        glEnable(GL_DEPTH_TEST);

        // Define material properties of specular color and degree of 
        // shininess.  Since this is only done once in this particular 
        // example, it applies to all objects.  Material properties can 
        // be set for individual objects, individual faces of the objects,
        // individual vertices of the faces, etc... 
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
        glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);

        // Set the GL_AMBIENT_AND_DIFFUSE color state variable to be the
        // one referred to by all following calls to glColor
        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
        glEnable(GL_COLOR_MATERIAL);

        // Create a Directional Light Source
        glLightfv(GL_LIGHT0, GL_POSITION, position);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);

        // Assign reshape() to be the function called whenever
        // an expose event occurs
        tkExposeFunc(reshape);

        // Assign reshape() to be the function called whenever 
        // a reshape event occurs
        tkReshapeFunc(reshape);

        // Assign key_down() to be the function called whenever
        // a key is pressed
        tkKeyDownFunc(key_down);

        // Assign draw() to be the function called whenever a display
        // event occurs, generally after a resize or expose event
        tkDisplayFunc(draw);

	tkIdleFunc(draw);

        // Pass program control to tk's event handling code
        // In other words, loop forever
        tkExec();
}

