#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <time.h>

#define WIDTH 1000
#define HEIGHT 1000
#define FALSE 0
#define TRUE 1
#define LEFT
#define TOP
#define ITERATIONS 1000000

void initalize(void);
void draw(void);
void update(void);
void animate(void);
void camera(void);
void fern();

void main(int argc, char* argv[])
{
	srand(time(NULL));

	glutInit(&argc, argv);
	initalize();
	glutMainLoop();
	
}


void animate(void){
update();
//glutPostRedisplay();	
}

void initalize(void)
{
// glvariables and initializations go here
glutInitDisplayMode(GLUT_DOUBLE |GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(WIDTH, HEIGHT);
glutInitWindowPosition(100, 100);
glutCreateWindow("chuck_d - koch curve: 1000000 iterations");
glutDisplayFunc(draw);
glutIdleFunc(animate);
glPointSize(1.0);
}

void draw(void)
{
// clearing background
	glClearColor( 0.0, 0.0, 0.0, 1.0 );


// clearing opengl states	
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

// camera
	camera();

// action! (draw here)

fern();



// swap buffers
	glutSwapBuffers();
}

void update(void)
{
// update variables here

}

void camera(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glOrtho(0, WIDTH, HEIGHT/2, -(HEIGHT/2), 1, 1);
gluPerspective(40.0, 1.0, .1, 2000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(100, 100, 600, 0, 0, 0, 0, 1, 0);
}


void fern()
{


	double a[4] = {0.3333333333, 0.1666666667, 0.1666666667, 0.3333333333};
	double b[4] = {0.0, -0.2888888889, 0.2888888889, 0.0};
	double c[4] = {0.0, 0.2888888889, -0.2888888889, 0.0};
	double d[4] = {0.3333333333, 0.1666666667, 0.1666666667, 0.3333333333};
	double e[4] = {0.0,0.3333333333,0.5,0.6666666667};
	double f[4] = {0.0, 0.0, 0.2888888889, 0.0};


	static int done=FALSE;
	int i,j,k,r;
	int ix,iy;
	double x=45.0,y,xlast=0,ylast=0;
	double xmin=1e32,xmax=-1e32,ymin=1e32,ymax=-1e32,scale,xmid,ymid;

	glColor3f(0.0, 0.5, 1.0);
	
	
	for (j=0;j<3;j++) {
		
      for (i=0;i<ITERATIONS;i++) {
        r = rand() % 100;
		 if (r < 25)
            k = 0;
         else if (r < 50)
            k = 1;
         else if (r < 75)
            k = 2;
         else
            k = 3;
         x = a[k] * xlast + b[k] * ylast + e[k];
         y = c[k] * xlast + d[k] * ylast + f[k];
         xlast = x;
         ylast = y;
         if (x < xmin) xmin = x;
         if (y < ymin) ymin = y;
         if (x > xmax) xmax = x;
         if (y > ymax) ymax = y;
         if (j > 1) {
			if ((WIDTH / (xmax - xmin)) < (HEIGHT / (ymax - ymin)))
				 scale = WIDTH / (xmax - xmin);
			 else
				 scale = HEIGHT / (ymax - ymin);
            xmid = (xmin + xmax) / 2;
            ymid = (ymin + ymax) / 2;
            ix = (x - xmid) * scale;
            iy = (y - ymid) * scale;
			
			glBegin(GL_POINTS);
			glVertex2i(ix,iy);
			glEnd();

        }
      }
   }

}
