#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include "c:/Libraries/Utils/HSV.h"

// Defining the Data Structure
struct Vertex_Type{
    double coordinates[2];
    void setCoordinates(double x, double y) {
    	  coordinates[0] = x; coordinates[1] = y;
    }
};	

Vertex_Type vertices[4];

HSV hsv = HSV(25.0, 1.0, 0.85);

void init() {   
   // Set the Vertices
   vertices[0].setCoordinates(0.0, 0.5);
   vertices[1].setCoordinates(0.5, 1.0);
   vertices[2].setCoordinates(1.0, 0.5);
   vertices[3].setCoordinates(0.5, 0.0);


   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluOrtho2D(0.0, 1.0, 0.0, 1.0);
   
   glClearColor(1.0, 1.0, 0.85, 1.0);
}
   
void drawSquare(Vertex_Type vertices[], HSV hsv, int count) {	
    if (count > 0) {
       glColor3fv(hsv.getRGB());
          
       // Constructing the Geometry
       glBegin(GL_POLYGON);
          for (unsigned i=0; i<4; i++)
              glVertex2dv(vertices[i].coordinates);
       glEnd();
       
       HSV newHSV = HSV(hsv.getHue(), hsv.getSaturation()-0.1, hsv.getValue());
       
       // Computing the Coordinates of a New Set of Vertices
       Vertex_Type newVertices[4];
       for (unsigned i=1; i<4; i++) {
       	  double x =   0.5*(vertices[i].coordinates[0] - vertices[i-1].coordinates[0])
                         + vertices[i-1].coordinates[0];
       	  double y =   0.5*(vertices[i].coordinates[1] - vertices[i-1].coordinates[1])
                         + vertices[i-1].point[1];
          newVertices[i].setCoordinates(x, y);
       }   
       double x =   0.5*(vertices[0].coordinates[0] - vertices[3].coordinates[0]) 
                  + vertices[3].coordinates[0];
  	 double y =   0.5*(vertices[0].coordinates[1] - vertices[3].coordinates[1])
                  + vertices[3].coordinates[1];
       newVertices[0].setCoordinates(x, y);

       drawSquare(newVertices, newHSV, count-1);    
    }
}
   
void display() {
    glClear(GL_COLOR_BUFFER_BIT);
    
    drawSquare(vertices, hsv, 8);    
    glFlush();
}

int main(int argc, char **argv) {
    glutInit(&argc, argv);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(500, 500);
    glutCreateWindow("Cascading Squares");

    glutDisplayFunc(display);
    
    init();

    glutMainLoop();
    return 0;
}