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

struct screen {

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

struct screen **Display_Buffer;
struct screen **depth1;
struct screen **depth2;


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 K, J;
int X;
int Y;  
int RES;
int DEPTH = 3;
//float rgbcalcs[8]= { 0 } ;
//float rgbcalcs[8];
#include "alpha.h"
//#include "ls_shapes.h"



static void Animate(void)
{

	glClear(GL_COLOR_BUFFER_BIT);
	glLoadIdentity();

	//long unsigned int i;
	//long unsigned int counter1, counter2, counter3;


alpha();
/*	glBegin(GL_POINTS);

	for(counter1=0; counter1 < X; counter1++) {
		for(counter2=0; counter2 < Y; counter2++) {
			glColor3f( depth2[counter1][counter2].red, depth2[counter1][counter2].green, depth2[counter1][counter2].blue);
			glVertex2f(counter1, counter2);
                        //glColor3f( depth1[counter1][counter2].red, depth1[counter1][counter2].green, depth1[counter1][counter2].blue);
                        //glVertex2f(counter1, counter2);


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

	}





}


void OpenGLInit(void)           
{       
        glShadeModel( GL_FLAT );
        glClearColor( 0.0, 0.0, 0.0, 0.0 );
        glClear(GL_COLOR_BUFFER_BIT);
        glDisable( GL_DEPTH_TEST );

	//glClearDepth(100.0f);							// Depth Buffer Setup
	//glEnable(GL_DEPTH_BUFFER_BIT);
	//glEnable(GL_DEPTH_TEST);						// Enables Depth Testing
	//glEnable(GL_DEPTH_TEST);
	//glDepthMask(GL_TRUE);
	//glEnable(GL_TEXTURE_3D);

	//glDepthFunc(GL_LEQUAL);							// The Type Of Depth Test To Do

}
        
        
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 = (float)w/(float)h;

        glMatrixMode( GL_PROJECTION );
        glLoadIdentity();
	//glOrtho(0,w,0,h,-100,100);
        glOrtho (0, w, h, 0, 0, 1);
        glMatrixMode( GL_MODELVIEW );
	
}       




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;
	long unsigned int j, counter1, counter2 ,counter3;

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


	Display_Buffer = ( struct screen **)malloc(X* sizeof(struct screen *) );
	for( j=0; j<X; j++) {
		Display_Buffer[j] = ( struct screen *)malloc(Y* sizeof(struct screen **) );
	}
	printf("Display_Buffer initialized! \n");

        depth1 = ( struct screen **)malloc(X* sizeof(struct screen *) );
        for( j=0; j<X; j++) {
                depth1[j] = ( struct screen *)malloc(Y* sizeof(struct screen **) );
        }
        printf("depth1 initialized! \n");

        depth2 = ( struct screen **)malloc(X* sizeof(struct screen *) );
        for( j=0; j<X; j++) {
                depth2[j] = ( struct screen *)malloc(Y* sizeof(struct screen **) );
        }
        printf("depth2 initialized! \n");

	//populate depth1/depth2 with 0's
        for(counter1=0; counter1 < X; counter1++) {  
                for(counter2=0; counter2 < Y; counter2++) {
                        depth1[counter1][counter2].red = 0;
			depth2[counter1][counter2].red = 0;
			depth1[counter1][counter2].green = 0;
			depth2[counter1][counter2].green = 0;
			depth1[counter1][counter2].blue = 0;
			depth2[counter1][counter2].blue = 0;
			depth1[counter1][counter2].alpha = 0;
			depth2[counter1][counter2].alpha = 0;
                }
        }



	//draw red square in depth1 and blue in depth2
	for(counter1=500; counter1 < 1000; counter1++) {
		for(counter2=500; counter2 < 1000; counter2++) {
			depth1[counter1][counter2].red = 255;
			depth1[counter1][counter2].alpha = 75;
			//depth2[counter1+100][counter2+100].blue = 150;
			//depth2[counter1+100][counter2+100].alpha = 85;
		}
	}


        for(counter1=200; counter1 < 700; counter1++) {
                for(counter2=200; counter2 < 700; counter2++) {
                        depth2[counter1][counter2].red = 255;
                        depth2[counter1][counter2].alpha = 75;
                        //depth2[counter1+100][counter2+100].blue = 150;
                        //depth2[counter1+100][counter2+100].alpha = 85;
                }
        }




	printf("squares populated into depth buffers\n");

//	exit (1);


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


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



	return 0;
}
