///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
//													 //
//                      OZ - 2006					 //
//													 //
//  This program is intended to be a virtual museum  //
//  to display and access CANVAS/CAVE/CUBE           //
//  applications.									 //
//													 //
//  Parts of this code are from the KAMScript code   //
//	and were written by Rose Marshack and Nicholas   //
//	Duchnowski.										 //		
//													 //
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////


// precompiled header include MUST appear as the first non-comment line
#include "arPrecompiled.h"
#include "arMasterSlaveFramework.h"
#include "arOBJ.h"

//LRESULT	CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);		

arMasterSlaveFramework* framework;
arMatrix4 worldMatrix;



//Lighting stuff
GLfloat whiteLight[] = {0.5f, 0.5f, 0.5f, 1.0f};
GLfloat sourceLight[]= {0.8f, 0.8f, 0.8f, 1.0f};
GLfloat lightPos[] = {1.0f, 1.0f, 1.0f, 0.0f};

  GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  GLfloat mat_shininess[] = { 128.0 };
  GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
  
  arTexture floor01;
  arTexture ceiling01;
  arTexture ceiling02;
  arTexture wall01;

void setup()
{


}


void draw(){ 


GLfloat height = 60;
GLfloat cHeight = height*1.75;
GLfloat xzOffset = 0;
GLfloat yOffset= 0;
GLfloat sideLength = 60;
GLfloat cLength = sideLength*.75;

glEnable(GL_LIGHTING); 

glColor3f(1.0f,0.0,0.0);


if(!floor01.readJPEG("floor01.jpg", ".", ".", -1, true))
{
	cout<<"BLARG: Couldn't open floor01 file!  ";
}

if(!ceiling01.readJPEG("ceiling01.jpg", ".", ".", -1, true))
{
	cout<<"BLARG: Couldn't open ceiling01 file!  ";
}

if(!ceiling02.readJPEG("ceiling02.jpg", ".", ".", -1, true))
{
	cout<<"BLARG: Couldn't open ceiling01 file!  ";
}

if(!wall01.readJPEG("wall01.jpg", ".", ".", -1, true))
{
	cout<<"BLARG: Couldn't open wall01 file!  ";
}

/*
    //octagon
	glRotatef(90.0f,1.0f,0.0f,0.0f);
	glBegin(GL_POLYGON) ;
	glColor3f(1.0, 0.0, 1.0);

	glVertex3f(0, 0, 0);
	glVertex3f(-30, 0, 0);
	glVertex3f(-60, -30, 0);
	glVertex3f(-60, -60, 0);
	glVertex3f(-30, -90, 0);
	glVertex3f(-0, -90, 0);
	glVertex3f(30, -60, 0);
	glVertex3f(30, -30, 0);

	glEnd();
	glRotatef(-90.0f,1.0f,0.0f,0.0f);
*/
//floor
floor01.activate();
	glBegin(GL_QUADS) ;
	glColor3f(1.0, 1.0, 1.0);

	glTexCoord2f(0,0);
	glVertex3f(1.5*sideLength+xzOffset, yOffset, xzOffset);

	glTexCoord2f(0,1);
	glVertex3f(-2.5*sideLength+xzOffset, yOffset, xzOffset);

	glTexCoord2f(1,1);
	glVertex3f(-2.5*sideLength+xzOffset, yOffset, -3*sideLength+xzOffset);

	glTexCoord2f(1,0);
	glVertex3f(1.5*sideLength+xzOffset, yOffset, -3*sideLength+xzOffset);

	glEnd();
floor01.deactivate();
/*
//ceiling
floor01.activate();
	glBegin(GL_QUADS) ;
	glColor3f(1.0, 1.0, 1.0);

	glTexCoord2f(0,0);
	glVertex3f(sideLength+xzOffset, yOffset+height, xzOffset);

	glTexCoord2f(0,1);
	glVertex3f(-2*sideLength+xzOffset, yOffset+height, xzOffset);

	glTexCoord2f(1,1);
	glVertex3f(-2*sideLength+xzOffset, yOffset+height, -3*sideLength+xzOffset);

	glTexCoord2f(1,0);
	glVertex3f(sideLength+xzOffset, yOffset+height, -3*sideLength+xzOffset);

	glEnd();
floor01.deactivate();
*/
//wall one
wall01.activate();
	glBegin(GL_QUADS) ;
	glColor3f(1.0, 1.0, 1.0);

	glTexCoord2f(0,0);
	glVertex3f(xzOffset, yOffset, xzOffset);

	glTexCoord2f(0,1);
	glVertex3f(xzOffset, yOffset+height, xzOffset);

	glTexCoord2f(1,1);
	glVertex3f(-sideLength+xzOffset, yOffset+height, xzOffset);

	glTexCoord2f(1,0);
	glVertex3f(-sideLength+xzOffset, yOffset, xzOffset);

	glEnd();
wall01.deactivate();
	

//wall two
wall01.activate();
	glBegin(GL_QUADS) ;

	glTexCoord2f(0,0);
	glVertex3f(-sideLength+xzOffset, yOffset, xzOffset);

	glTexCoord2f(0,1);
	glVertex3f(-sideLength+xzOffset, height+yOffset, xzOffset);

	glTexCoord2f(1,1);
	glVertex3f(-2*sideLength+xzOffset, height+yOffset, -sideLength+xzOffset);

	glTexCoord2f(1,0);
	glVertex3f(-2*sideLength+xzOffset, yOffset, -sideLength+xzOffset);

	glEnd();
wall01.deactivate();

//wall three
wall01.activate();
	glBegin(GL_QUADS) ;

	glTexCoord2f(0,0);
	glVertex3f(-2*sideLength+xzOffset, yOffset, -sideLength+xzOffset);

	glTexCoord2f(0,1);
	glVertex3f(-2*sideLength+xzOffset, height+yOffset, -sideLength+xzOffset);

	glTexCoord2f(1,1);
	glVertex3f(-2*sideLength+xzOffset, height+yOffset, -2*sideLength+xzOffset);

	glTexCoord2f(1,0);
	glVertex3f(-2*sideLength+xzOffset, yOffset, -2*sideLength+xzOffset);

	glEnd();
wall01.deactivate();

//wall four
wall01.activate();
	glBegin(GL_QUADS) ;

	glTexCoord2f(0,0);
	glVertex3f(-2*sideLength+xzOffset, yOffset, -2*sideLength+xzOffset);

	glTexCoord2f(0,1);
	glVertex3f(-2*sideLength+xzOffset, height+yOffset, -2*sideLength+xzOffset);

	glTexCoord2f(1,1);
	glVertex3f(-sideLength+xzOffset, height+yOffset, -3*sideLength+xzOffset);

	glTexCoord2f(1,0);
	glVertex3f(-sideLength+xzOffset, yOffset, -3*sideLength+xzOffset);

	glEnd();
wall01.deactivate();

//wall five
wall01.activate();
	glBegin(GL_QUADS) ;

	glTexCoord2f(0,0);
	glVertex3f(-sideLength+xzOffset, yOffset, -3*sideLength+xzOffset);

	glTexCoord2f(0,1);
	glVertex3f(-sideLength+xzOffset, height+yOffset, -3*sideLength+xzOffset);

	glTexCoord2f(1,1);
	glVertex3f(xzOffset, height+yOffset, -3*sideLength+xzOffset);

	glTexCoord2f(1,0);
	glVertex3f(xzOffset, yOffset, -3*sideLength+xzOffset);

	glEnd();
wall01.deactivate();

//wall six
wall01.activate();
	glBegin(GL_QUADS) ;

	glTexCoord2f(0,0);
	glVertex3f(xzOffset, yOffset, -3*sideLength+xzOffset);

	glTexCoord2f(0,1);
	glVertex3f(xzOffset, height+yOffset, -3*sideLength+xzOffset);

	glTexCoord2f(1,1);
	glVertex3f(sideLength+xzOffset, height+yOffset, -2*sideLength+xzOffset);

	glTexCoord2f(1,0);
	glVertex3f(sideLength+xzOffset, yOffset, -2*sideLength+xzOffset);

	glEnd();
wall01.deactivate();

//wall seven
wall01.activate();
	glBegin(GL_QUADS) ;

	glTexCoord2f(0,0);
	glVertex3f(sideLength+xzOffset, yOffset, -2*sideLength+xzOffset);

	glTexCoord2f(0,1);
	glVertex3f(sideLength+xzOffset, height+yOffset, -2*sideLength+xzOffset);

	glTexCoord2f(1,1);
	glVertex3f(sideLength+xzOffset, height+yOffset, -sideLength+xzOffset);

	glTexCoord2f(1,0);
	glVertex3f(sideLength+xzOffset, yOffset, -sideLength+xzOffset);

	glEnd();
wall01.deactivate();

//wall eight
wall01.activate();
	glBegin(GL_QUADS) ;

	glTexCoord2f(0,0);
	glVertex3f(sideLength+xzOffset, yOffset, -sideLength+xzOffset);

	glTexCoord2f(0,1);
	glVertex3f(sideLength+xzOffset, height+yOffset, -sideLength+xzOffset);

	glTexCoord2f(1,1);
	glVertex3f(xzOffset, height+yOffset, xzOffset);

	glTexCoord2f(1,0);
	glVertex3f(xzOffset, yOffset, xzOffset);

	glEnd();
wall01.deactivate();

//ceiling one
ceiling01.activate();
glColor3f(1.0,0.0,0.0);
    glBegin(GL_TRIANGLES);

	glTexCoord2f(1,0);
	glVertex3f(-sideLength+xzOffset, height+yOffset, xzOffset);
	glTexCoord2f(0,1);
	glVertex3f(-0.5*sideLength+xzOffset, cHeight+yOffset, -1.5*sideLength+xzOffset);
	glTexCoord2f(1,1);
	glVertex3f(xzOffset, height+yOffset, xzOffset);

	glEnd();
ceiling01.deactivate();

//ceiling two
ceiling01.activate();
glColor3f(0.0,1.0,0.0);
    glBegin(GL_TRIANGLES);

	glTexCoord2f(1,0);
	glVertex3f(-2*sideLength+xzOffset, height+yOffset, -sideLength+xzOffset);
	glTexCoord2f(0,1);
	glVertex3f(-0.5*sideLength+xzOffset, cHeight+yOffset, -1.5*sideLength+xzOffset);
	glTexCoord2f(1,1);
	glVertex3f(-sideLength+xzOffset, height+yOffset, xzOffset);

	glEnd();
ceiling01.deactivate();

//ceiling three
ceiling01.activate();
glColor3f(1.0,0.0,0.0);
    
	glBegin(GL_TRIANGLES);

	glTexCoord2f(1,0);
	glVertex3f(-2*sideLength+xzOffset, height+yOffset, -2*sideLength+xzOffset);
	glTexCoord2f(0,1);
	glVertex3f(-0.5*sideLength+xzOffset, cHeight+yOffset, -1.5*sideLength+xzOffset);
	glTexCoord2f(1,1);
	glVertex3f(-2*sideLength+xzOffset, height+yOffset, -sideLength+xzOffset);

	glEnd();

ceiling01.deactivate();

//ceiling four
ceiling01.activate();
glColor3f(0.0,1.0,0.0);

    glBegin(GL_TRIANGLES);

	glTexCoord2f(1,0);
	glVertex3f(-sideLength+xzOffset, height+yOffset, -3*sideLength+xzOffset);
	glTexCoord2f(0,1);
	glVertex3f(-0.5*sideLength+xzOffset, cHeight+yOffset, -1.5*sideLength+xzOffset);
	glTexCoord2f(1,1);
	glVertex3f(-2*sideLength+xzOffset, height+yOffset, -2*sideLength+xzOffset);

	glEnd();

ceiling01.deactivate();

//ceiling five
ceiling01.activate();
glColor3f(1.0,0.0,0.0);

    glBegin(GL_TRIANGLES);

	glTexCoord2f(1,0);
	glVertex3f(xzOffset, height+yOffset, -3*sideLength+xzOffset);
	glTexCoord2f(0,1);
	glVertex3f(-0.5*sideLength+xzOffset, cHeight+yOffset, -1.5*sideLength+xzOffset);
	glTexCoord2f(1,1);
	glVertex3f(-sideLength+xzOffset, height+yOffset, -3*sideLength+xzOffset);

	glEnd();

ceiling01.deactivate();

//ceiling six
ceiling01.activate();
glColor3f(0.0,1.0,0.0);

    glBegin(GL_TRIANGLES);

	glTexCoord2f(1,0);
	glVertex3f(sideLength+xzOffset, height+yOffset, -2*sideLength+xzOffset);
	glTexCoord2f(0,1);
	glVertex3f(-0.5*sideLength+xzOffset, cHeight+yOffset, -1.5*sideLength+xzOffset);
	glTexCoord2f(1,1);
	glVertex3f(xzOffset, height+yOffset, -3*sideLength+xzOffset);

	glEnd();

ceiling01.deactivate();

//ceiling seven
ceiling01.activate();
glColor3f(1.0,0.0,0.0);

    glBegin(GL_TRIANGLES);

	glTexCoord2f(1,0);
	glVertex3f(sideLength+xzOffset, height+yOffset, -sideLength+xzOffset);
	glTexCoord2f(0,1);
	glVertex3f(-0.5*sideLength+xzOffset, cHeight+yOffset, -1.5*sideLength+xzOffset);
	glTexCoord2f(1,1);
	glVertex3f(sideLength+xzOffset, height+yOffset, -2*sideLength+xzOffset);

	glEnd();

ceiling01.deactivate();

//ceiling eight
ceiling01.activate();
glColor3f(0.0,1.0,0.0);

    glBegin(GL_TRIANGLES);

	glTexCoord2f(1,0);
	glVertex3f(xzOffset, height+yOffset, xzOffset);
	glTexCoord2f(0,1);
	glVertex3f(-0.5*sideLength+xzOffset, cHeight+yOffset, -1.5*sideLength+xzOffset);
	glTexCoord2f(1,1);
	glVertex3f(sideLength+xzOffset, height+yOffset, -sideLength+xzOffset);

	glEnd();

ceiling01.deactivate();

}







// OTHER STUFF STARTS HERE:


//Important variables and arrays to transfer
//to the other workstations
bool init(arMasterSlaveFramework&, arSZGClient&){

  ar_setNavMatrix(ar_translationMatrix(0,0,60));

  // Setup Shared Variables that will be transferred between applications
  framework->addTransferField("worldRotation",worldMatrix.v,AR_FLOAT,16);

  /* Here are some other examples of variables that were shared in the 
  application that this used to be. 

  framework->addTransferField("reset",&reset,AR_INT,1);
  framework->addTransferField("positions",pos,AR_FLOAT,howmany);
  framework->addTransferField("increments",&numberIncrementsPerFrame,AR_INT,1);
  framework->addTransferField("idx",&idx,AR_INT,1);
  framework->addTransferField("addtrails",&addtrails,AR_INT,1);
  framework->addTransferField("lorenz",&lorenz,AR_INT,1);

  */

return true;
}

int lastButton[6];

//Common syzygy stuff
void preExchange(arMasterSlaveFramework&){
  static bool firstCall = true;
  if (!framework->getMaster())
    return;
  double timeDelta = framework->getLastFrameTime()/1000.0;

  arMatrix4 wandMatrix = framework->getMatrix(1); 

  arVector3 wandDirection = ar_vectorToNavCoords(
    ar_extractRotationMatrix(framework->getMatrix(1)) * arVector3(0,0,-1));
  if (framework->getAxis(1) > 0.5)
    wandDirection *= 10. * timeDelta;
  else if (framework->getAxis(1) < -0.5)
    wandDirection *= -10. * timeDelta;
  else
    wandDirection *= 0.;

  ar_navTranslate(wandDirection);


}

void postExchange(arMasterSlaveFramework&){


}

void drawCallback(arMasterSlaveFramework&){


  // navigation transform... unsure whether we should have the inverse
  // in here or not. In any event, would be a good idea to move over to the
  // navigation framework at some point
  arMatrix4 temp = !ar_getNavMatrix();
  glMultMatrixf(temp.v);

  // Black background at infinity
  glDisable(GL_LIGHTING);
  glColor3f(0.0,0.0,0.0);
  glutSolidCube(1000);
  glEnable(GL_LIGHTING);


  glEnable(GL_LINE_SMOOTH); 
   glEnable(GL_DEPTH_TEST);  

   //Lighting stuff
   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, whiteLight);
   glLightfv(GL_LIGHT0, GL_DIFFUSE, sourceLight);

   glEnable(GL_COLOR_MATERIAL);
   glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
  
   glShadeModel (GL_SMOOTH);

   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
   glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
  
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   glLightfv(GL_LIGHT0, GL_POSITION, light_position); 

   
  glPushMatrix();
   glMultMatrixf(worldMatrix.v);
   
   //draw!
   draw();
  glPopMatrix();
  

}

int main(int argc, char** argv){
  
  //Set the stage
  setup();

    framework = new arMasterSlaveFramework;
  if (!framework->init(argc, argv))
    return 1;
  framework->setStartCallback(init);
  
  framework->setClipPlanes(0.1, 1000) ;
  framework->setPreExchangeCallback(preExchange);
  framework->setDrawCallback(drawCallback);
  framework->setPostExchangeCallback(postExchange);
  return framework->start() ? 0 : 1;
}

