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


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;

//int topx = 500; 
//int topy = 500;
//int lowx = 600;
//int lowy = 600;

int rec_center_x = 0;
int rec_center_y = 0;
int rec_width = 100;
int rec_length = 100;
int rec_rotation = 0;
int K, J;
int X;
int Y;  
int RES;



struct screen {

	//short unsigned int red;
	//short unsigned int green;
	//short unsigned int blue;
	unsigned char red;
	unsigned char green;
	unsigned char blue;
	unsigned char alpha;	
};

//struct screen mainwindow[3];
//for(i=0; i < 3145728; i++) {


//struct screen *mainwindow;

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




/*Allocating memory*/

//if((buffer=(struct screen *) malloc(sizeof(screen)*5))==NULL)
//{
//printf("Malloc failed\n");
//exit(1);
//} 





static void Animate(void)
{
	int i;
	int x1 = 0;
	int y1 = 0;
	//int J = 0;
	//int K = 0;
	
        //h = (h == 0) ? 1 : h;
        //w = (w == 0) ? 1 : w;
	//int h = 1536;
	//int w = 2048;
	//2048x1536
	//double fps = 0;
	//double time1 = 0; 
	//double time2 = 0;
	//x1: 2048 y1: 1472
	//x1: 2048 y1: 1504
	//h: 1513 w: 2048

	glClear(GL_COLOR_BUFFER_BIT);
	//glColor3f(255, 255, 255);
	//glColor3f(255, 0, 0);
	//glBegin(GL_POINTS);
	//glVertex2f(2048, 1536);
	//glEnd();

	x1 = 0;
	y1 = 0;
	//h: 1536 w: 2048
	//printf("h: %d w: %d\n", glutGet(GLUT_SCREEN_HEIGHT), glutGet(GLUT_SCREEN_WIDTH));
	//glutGet(GLUT_WINDOW_WIDTH)


//int rec_center_x = 500;
//int rec_center_y = 500;
//int rec_width = 100;
//int rec_length = 100;

//int red = 0;
//int green = 0;
//int blue = 0;


//glColor3f(255, 0, 0);
	for(i=0; i < RES; i+=X) {
		//mainwindow[i].red = 255;
		//mainwindow[i].green = 255;
		//mainwindow[i].blue = 255;
		
		/*
		if(red < 127) {
			red++;
		} else if (green < 127) {
			green++;
		} else if (blue < 127) {
			blue++;
		} else {
			red = 0;
			green = 0;
			blue = 0;
		}

		glColor3f(red, green, blue);
		*/

		//glColor3f( mainwindow[i].red, mainwindow[i].green, mainwindow[i].blue );


		/*
		if(x1 > topx && y1 > topy && x1 < lowx && y1 < lowy ) {
			glColor3f(255, 0, 0);
		//}else if(x1 > 1500 && y1 > 1000) {

			//printf("x1: %d y1: %d\n", x1, y1);
			//glColor3f(mainwindow[i].red, mainwindow[i].green, mainwindow[i].blue);

		}else{
			glColor3f(mainwindow[i].red, mainwindow[i].green, mainwindow[i].blue);
			//glColor3f(255, 255, 255);

		}

		*/
		//glColor3f(255, 0, 0);
		glBegin(GL_POINTS);
		


		//glVertex2f(x1, y1);

		
		for(x1=0; x1<X; x1++) {
			glColor4f( mainwindow[x1+(y1*X)].red, mainwindow[x1+(y1*X)].green, mainwindow[x1+(y1*X)].blue, 
                            mainwindow[x1+(y1*X)].alpha );
 			//glColor3f( mainwindow[x1+(y1*X)].red, mainwindow[x1+(y1*X)].green, mainwindow[x1+(y1*X)].blue );
			glVertex2f(x1, y1);

		}
		y1++;		

/*

		for(J=0; J < 32; J++) {
			for(K=0; K < 32; K++) {
				
				glColor3f( mainwindow[i+J+K].red, mainwindow[i+J+K].green, mainwindow[i+J+K].blue );
				glVertex2f(x1+J, y1+K);
				

			}
			//if(J==31 && y1 != 31) {
			//	y1++;
			//	x1 = 0;
			//}
		}
*/

                //for(J=0; J < 32; J++) {
                //        glVertex2f(x1+J, y1);  
                //}


		glEnd();

/*		if(x1 < X-32) {
		 	x1+=32;
		} else if (x1 == X-32) {
			x1 = 0;
			y1+=32;
		}
		*/

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

//printf("x1: %d y1: %d\n", x1, y1);
	time2++;

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

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

	}
		//rotate square


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

		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;
                }  




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





        



	//sleep(1);

}

void OpenGLInit(void)
{
	glShadeModel( GL_FLAT );
	glClearColor( 0.0, 0.0, 0.0, 0.0 );
	//glClearDepth( 1.0 );
	glClear(GL_COLOR_BUFFER_BIT);
	glDisable( GL_DEPTH_TEST );
}       
        

static void ResizeWindow(int w, int h)
{  
	float aspectRatio;
        h = (h == 0) ? 1 : h;
        w = (w == 0) ? 1 : w;
//printf("h: %d w: %d\n", h, w);
        glViewport( 0, 0, w, h );       // View port uses whole window
        aspectRatio = (float)w/(float)h;

        // Set up the projection view matrix (not very well!)
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	//gluPerspective( 200.0, aspectRatio, 1.0, 100.0 );
	glOrtho (0, w, h, 0, 0, 1);
	//glMatrixMode (GL_MODELVIEW)

        // Select the Modelview matrix
	glMatrixMode( GL_MODELVIEW );
}




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

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


	/*
	int X;
	int Y;
	int RES;
	*/

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

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

//lsrender.cpp:191: error: incompatible types in assignment of 'void*' to 'screen [3145728]'
//lsrender.cpp:190: error: incompatible types in assignment of 'screen*' to 'screen [3145728]'
//lsrender.cpp:190: error: no matching function for call to 'screen::screen(void*)'
//ptr=realloc(ptr,newsize);
//lsrender.cpp:194: error: no matching function for call to 'screen::screen(void*)'
//lsrender.cpp:195: error: no matching function for call to 'screen::screen(void*)'
//mainwindow = realloc(mainwindow, sizeof(screen)*RES); 
//lsrender.cpp:198: error: incompatible types in assignment of 'void*' to 'screen [3]'
//lsrender.cpp:195: error: incompatible types in assignment of 'void*' to 'screen [3]'
//lsrender.cpp:215: error: invalid conversion from 'void*' to 'screen*'

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










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

		/*if(i > 1024 && i < 2048) {
                	mainwindow[i].red = 127;
                	mainwindow[i].green = 0;
                	mainwindow[i].blue = 0;
		}else{*/
                        mainwindow[i].red = 0;
                        mainwindow[i].green = 0;
                        mainwindow[i].blue = 255;
			mainwindow[i].alpha = 1;
		//}
	}


printf("test %d\n", mainwindow[0].alpha);


	//3145728
	//printf("test\n");
	//glutInit(&argc,argv);
	//glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	//glutInitWindowPosition( 0, 0 );
	glutInitWindowSize( X, Y );
	glutCreateWindow( "lsrender test" );






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



	return 0;
}
