#include <iostream>
#ifdef _WIN32
#include <windows.h>
#endif

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include "cvec2t.h"
#include "cvec3t.h"

using namespace std;

typedef CVec2T<float> Vec2f;
typedef CVec3T<float> Vec3f;

#ifndef M_PI
#define M_PI 3.1415926535897932385
#endif

namespace Params { 
  const float WorldWidth =  1;
  const float WorldHeight = 1;
  const int TimerStep = 16; // millisec
};

namespace WindowParams {
  static int WindowWidth =  600;
  static int WindowHeight = 600;
  static int MainWindow; 
};

void Reshape(int width, int height) {

  // glViewport defines part of the window we are going to use 
  WindowParams::WindowWidth = width;
  WindowParams::WindowHeight = height;
  glViewport(0,0,width,height);

  // initialize the viewing transformation (camera position) to identity; 
  // this corresponds to camera looking down negative z axis
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(0,0,1, 0.5,0.5,0, 0,1,0);	

  // specify the projection transformation (camera parameters);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  // this defines a camera with orthogonal projection that captures the 
  // part of the virtual world inside the box from 
  // -WorldWidth/2 to WorldWidth/2 in all directions
  glOrtho(
	  -Params::WorldWidth/2, Params::WorldWidth/2,
	  -Params::WorldWidth/2, Params::WorldWidth/2,	  
	  0.1, 100);
//  gluPerspective(
}

void drawsq() { 
	glRectfv(Vec2f(0,0), Vec2f(1,1));
}

void Keyboard( unsigned char key, int, int) { }


 Vec3f red(1,0,0), green(0,1,0),blue(0,0,1);



float angle = 0;

void Draw() {

  // unit vectors 
  Vec3f ex(1,0,0), ey(0,1,0),ez(0,0,1);
  Vec3f origin(0,0,0);	

  glClearColor( 0.0, 0.0,0.0,0.0);
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glDisable(GL_LIGHTING);
  glMatrixMode(GL_MODELVIEW); 
  glBegin(GL_LINES);
	glColor3fv(red);   glVertex3fv(origin); glVertex3fv(ex);	
	glColor3fv(green); glVertex3fv(origin); glVertex3fv(ey);	
	glColor3fv(blue);  glVertex3fv(origin); glVertex3fv(ez);	
  glEnd();


  glPushMatrix(); 
    
    glTranslatef(0.2, 0.3, 0);
	glRotatef(angle, 0,0,1);   
    glPushMatrix(); 
      glScalef(0.2,0.1,1);
      glColor3fv(red);
      // draw the object 
      drawsq();
    glPopMatrix(); 	

    glPushMatrix();
	  glTranslatef(0.2,0,0);
	  glRotatef(45, 0,0,1); 
      glScalef(0.2,0.1,1);
      glColor3fv(blue);
      // draw the object 
      drawsq();
    glPopMatrix(); 	

  glPopMatrix(); 	


  glutSwapBuffers();
}


void Animate(int time) { 
  // reregister itself to trigger in Timestep msec
  glutTimerFunc(Params::TimerStep,Animate,0);
  // increment the variable for variable transform
  angle	+= 1;
  // create a redraw event
  glutPostRedisplay();
}


int main(int argc, char* argv[]) {

  // initialize glut and parse command-line aguments that glut understands
  glutInit(&argc, argv);

  // initialize dislay mode: 4 color components, double buffer and depth buffer
  glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);

  glutInitWindowSize(WindowParams::WindowWidth,WindowParams::WindowHeight);


  WindowParams::MainWindow = glutCreateWindow("Transform");

  // register all callbacks

   glutDisplayFunc(Draw); 
   glutReshapeFunc(Reshape);
   glutKeyboardFunc(Keyboard);
   // register a callback to trigger in TimerStep msec
   glutTimerFunc(Params::TimerStep,Animate,0);

   // this is an infinite loop get event - dispatch event which never returns
   glutMainLoop();
   return 0;
}




