#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <sys/time.h>
//include "alpha.h"

struct screen {

        unsigned char red;
        unsigned char green;
        unsigned char blue;
        unsigned char alpha;
};


struct screen *mainwindow=( (struct screen *) malloc(sizeof(struct screen)*5) );
struct screen *mainwindow2=( (struct screen *) malloc(sizeof(struct screen)*5) );



void OpenGLInit(void);
static void Animate(void );
static void ResizeWindow(int w, int h);
struct timespec ts;
struct timeval starttime,endtime;

double fps = 0;
double time1 = 0;
double time2 = 0;

float rgbcalcs[7];
#include "alpha.h"
int rec_center_x = 0;
int rec_center_y = 0;
int rec_width = 100;
int rec_length = 100;
int rec_rotation = 0;
int uneven = 50;
int K, J;
int X;
int Y;  
int RES;
int DEPTH = 3;


double x_coord = 0;

static void Animate(void)
{
	int i, j;
	int x1 = 0;
	int y1 = 0;
	int z1 = 10;
	//float rcalc;
	//float gcalc;
	//float bcalc;
	//float acalc;

	//glClear(GL_COLOR_BUFFER_BIT);
	//glClear(GL_DEPTH_BUFFER_BIT);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			// Clear The Screen And The Depth Buffer
	glLoadIdentity();							// Reset The Current Modelview Matrix

	x1 = 0;
	y1 = 0;
	

	z1 = 2;
	double p1, p2, p3, a1, a2;
	double t1, t2;
	int elem1, elem2;
	//glBegin(GL_POINTS);

//for(j=0; j < 2; j++) {

	for(i=0; i < RES*2; i+=X) {
		//glBegin(GL_POINTS);
		//if(i == RES) { y1 = 0;}
		for(x1=0; x1<X; x1++) {
			
			//if(mainwindow[x1+(y1*X)+(z1*RES)].red != 0 && mainwindow[x1+(y1*X)+(z1*RES)].green != 0 && 
                          //mainwindow[x1+(y1*X)+(z1*RES)].blue != 0) {
			//if(j != 2 ) {
				//if(j == 0) {
					elem1 = x1+(y1*X); 
					//elem2 = RES+x1+(y1*X);
					elem2 = elem1 + RES;
					alpha(elem1, elem2, 0);
				/*}else if(j == 1){
					elem1 = x1+(y1*X);
					//elem2 =(2*RES)+x1+(y1*X);
					elem2 = elem1 + RES;
					alpha(elem1, elem2, 1);
				}else{
					elem1 =(2*RES)+x1+(y1*X);
					elem2 =(2*RES)+x1+(y1*X);
				}*/
				
				//alpha(elem1, elem2, z1);

				/*
				t1 = mainwindow[elem1].red+mainwindow[elem1].green+
                                    mainwindow[elem1].blue;
				a2 =  (255 - mainwindow[elem1].alpha);
				
				t2 = mainwindow[elem2].red+mainwindow[elem2].green+
                                    mainwindow[elem2].blue;

				p1 = (mainwindow[elem2].red/(t2+1))*a2;
				p2 = (mainwindow[elem2].green/(t2+1))*a2;
				p3 = (mainwindow[elem2].blue/(t2+1))*a2;

				//p1 = p1 *(a2/255);
				//p2 = p2 *(a2/255);
				//p3 = p3 *(a2/255);

				rcalc = (mainwindow[elem1].red/(t1+1))*(mainwindow[elem1].alpha); 
				gcalc = (mainwindow[elem1].green/(t1+1))*(mainwindow[elem1].alpha);
				bcalc = (mainwindow[elem1].blue/(t1+1))*(mainwindow[elem1].alpha);

				rcalc = rcalc + p1;
				gcalc = gcalc + p2;
				bcalc = bcalc + p3;


				rcalc = rcalc / 255;
				gcalc = gcalc / 255;
				bcalc = bcalc / 255;
				*/

			//}
//t1 = rcalc + gcalc + bcalc;
//if(z1 == 1 ) {
			//if(z1 == 1) {
			//printf("elem1: %ld\n", elem1);
			//}
//glColor3f(rgbcalcs[0], rgbcalcs[1], rgbcalcs[2]);
//glVertex3f(x1+.5, y1+.5, 1);
//if(bcalc > .75) {
//	printf("r: %f g: %f b %f\n", rcalc, gcalc, bcalc);

//glLoadIdentity();
glBegin(GL_POINTS);
glColor3f(rgbcalcs[4], rgbcalcs[5], rgbcalcs[6]);
glVertex3f(x1+.5, y1+.5, 0);		
glEnd();

        //glLoadIdentity();
        //glOrtho (0, X, Y, 0, 0, 2);
//glLoadIdentity();
glBegin(GL_POINTS);
glColor3f(rgbcalcs[1], rgbcalcs[2], rgbcalcs[3]);
glVertex3f(x1+.5, y1+.5, 1); 
glEnd();




//}

		}
		y1++;

/*
		if(y1 == Y && x1 == X ) {
			y1 = 0;
			if(z1 > 0) {
				z1--;
			}

			//printf("here\n");
		}else{
			//if(y1 < Y) {

			y1++;

			//}else{
			//	y1 = 0;
			//}
			//z=10;
		}	
*/


		//glEnd();


	}
//	y1=0;
//}

//printf("I: %lf\n", i);
	//glEnd();

	glFlush();
	glutSwapBuffers();
	glutPostRedisplay();

	time2++;

	gettimeofday(&endtime, NULL);
	time1=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;

        if (time2 == 5)
        {
                fps = time2 / time1;
                printf("fps: %lf - %lf frames in %lf seconds\n", fps, time2, time1);
                gettimeofday(&starttime, NULL);
                time2 = 0;

	




		z1 = 1;
		K = rec_center_x;
		J = rec_center_y;

		while(J < (rec_center_y + rec_length ) ) {
			while(K < (rec_center_x + rec_width ) ) {
				elem1 = K+(X*J);
				mainwindow2[elem1].red = 0;				
				mainwindow2[elem1].green = 0;
				mainwindow2[elem1].blue = 0;
				mainwindow2[elem1].alpha = 0;
				K++;
			}
			J++;
			K = rec_center_x;
		}


		z1 = 0;
                K = rec_center_x+uneven;
                J = rec_center_y+uneven;
                 
                while(J < (rec_center_y+uneven + rec_length ) ) {
                        while(K < (rec_center_x+uneven + rec_width ) ) {
				elem1 = K+(X*J);
                                mainwindow[elem1].red = 0;
                                mainwindow[elem1].green = 0;
                                mainwindow[elem1].blue = 0;
                                mainwindow[elem1].alpha = 0;
                                K++;
                        }
                        J++;
                        K = rec_center_x+uneven;
                }
                                








		if(rec_center_x < 500) {
			rec_center_x+=25;
		} else {
			rec_center_x=0;
		}

                if(rec_center_y < 500) {
                        rec_center_y+=25;
                } else {
                        rec_center_y=0;
                }  

		if(uneven == 100) {
			uneven = 50;
		}else{
			uneven = 100;
		}





		z1 = 1;
                K = rec_center_x;
                J = rec_center_y;
                while(J < (rec_center_y + rec_length) ) {
                        while(K < (rec_center_x + rec_width) ) {
				elem1 = K+(X*J);
                                mainwindow2[elem1].red = 0;
                                mainwindow2[elem1].green = 0;
                                mainwindow2[elem1].blue = 255;
				mainwindow2[elem1].alpha = 85;
                                K++;
                        }
                        J++;
                        K = rec_center_x;
                }


		z1 = 0;
                K = rec_center_x +uneven;
                J = rec_center_y +uneven;   
                while(J < (rec_center_y+uneven + rec_length) ) {
                        while(K < (rec_center_x+uneven + rec_width) ) {
				elem1 = K+(X*J);
                                mainwindow[elem1].red = 255;
                                mainwindow[elem1].green = 0;
                                mainwindow[elem1].blue = 0;
                                mainwindow[elem1].alpha = 85;
                                K++;
                        }
                        J++;
                        K = rec_center_x+uneven;
                }


}





}

void OpenGLInit(void)
{
	glShadeModel(GL_SMOOTH);
	//glShadeModel( GL_FLAT );
	glClearColor( 0.0, 0.0, 0.0, 0.0 );
	//glClear(GL_COLOR_BUFFER_BIT);
	glClearDepth(5.0f);							// Depth Buffer Setup
	glEnable(GL_DEPTH_TEST);						// Enables Depth Testing
	glDepthFunc(GL_LEQUAL);							// The Type Of Depth Test To Do

	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);			// Really Nice Perspective Calculations

	//glClear(GL_DEPTH_BUFFER_BIT);
	//glDisable( GL_DEPTH_TEST );
	//glClearDepth( 3.0 );
	//glEnable( GL_DEPTH_TEST );
	//return 0;								// Initialization Went OK

}       
        

static void ResizeWindow(int w, int h)
{  
	float aspectRatio;
        h = (h == 0) ? 1 : h;
        w = (w == 0) ? 1 : w;
        glViewport( 0, 0, w, h );       // View port uses whole window
        aspectRatio = (GLfloat)w/(GLfloat)h;

	glMatrixMode( GL_PROJECTION );
	//glLoadIdentity();
	//glOrtho (0, w, h, 0, -5, 5);
	//gluPerspective( 70.0, aspectRatio, 1.0, 1.0 );
gluPerspective(45.0f,aspectRatio,-1.0f,10.0f);


	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
}




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

        glutInit(&argc,argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
        glutInitWindowPosition( 0, 0 );

	Y = glutGet(GLUT_SCREEN_HEIGHT); 
	X = glutGet(GLUT_SCREEN_WIDTH);
	RES = X*Y;
	

	printf("res: %d x: %d y: %d\n", RES, X, Y);

	if( (mainwindow = (screen *)realloc(mainwindow, sizeof(screen)*RES*3) ) ==NULL )
	{
		printf("Reallocation failed\n");
		exit(1);
	} 

        if( (mainwindow2 = (screen *)realloc(mainwindow2, sizeof(screen)*RES*3) ) ==NULL )
        {
                printf("Reallocation failed\n");
                exit(1);
        }









	long int i;
	for(i=0; i < RES; i++) {

                        mainwindow[i].red = 0;
                        mainwindow[i].green = 0;
                        mainwindow[i].blue = 0;
			mainwindow[i].alpha = 0;

                        mainwindow2[i].red = 0;  
                        mainwindow2[i].green = 0;
                        mainwindow2[i].blue = 0; 
                        mainwindow2[i].alpha = 0;

	}



	printf("res*depth %d\n", RES*DEPTH);

	//mainwindow[9437183].red = 255;
	//mainwindow[9437183].green = 255;
	//printf("red: %d\n", mainwindow[9437183].red);

//9437184

	glutInitWindowSize( X, Y );
	glutCreateWindow( "lsrender test" );


	OpenGLInit();
	glutReshapeFunc( ResizeWindow );
	glutDisplayFunc( Animate );
	glutMainLoop(  );



	return 0;
}
