//#include "Png_Funcs.h"
#include "OpenGL.h"

#define RESTART 2
#define PAUSED 3
#define EXIT 4

//struct image_attr *im_p;
GLuint Image_Texture;
double Eye_X = 0;
double Eye_Y = 0;
double Eye_Z = -4;
char scorestring[32];
//char ignoreRepeats = ;
//struct timespec ts;
struct timeval starttime,endtime;

static void processMenuEvents(int option);
static void special(int key, int x, int y);
static void Frames(double fps);
static void BindTexture(GLuint texture);

static void createGLUTMenus(void){
	int menu;
	menu = glutCreateMenu(processMenuEvents);

    glutAddMenuEntry("Pause",PAUSED);
    glutAddMenuEntry("Exit",EXIT);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
}

static void processMenuEvents(int option) {
	switch(option){
		case RESTART :
			printf("not implemented !\n");
			break;
		case PAUSED :
			printf("not implemented !\n");
			break;
		case EXIT :
			printf("Cleaning up Memory and Exiting Program !!\n");
			No_Exit = 0;
			pthread_exit(NULL);
			break;

	}
}

static void special(int key, int x, int y){
	switch(key){
		case GLUT_KEY_UP:
			Eye_Y-=.1;
			break;
		case GLUT_KEY_DOWN:
			Eye_Y+=.1;
			break;
		case GLUT_KEY_RIGHT:
			Eye_X+=.1;
			//printf("increment num1: %lf\n", num1);
			break;
		case GLUT_KEY_LEFT: 
			Eye_X-=.1;
			//printf: %lf\n", num1);
			break;
		case GLUT_KEY_PAGE_UP:
			Eye_Z+=.1;
			break;
		case GLUT_KEY_PAGE_DOWN:
			Eye_Z-=.1;
			break;
	}
}

static void Frames(double fps){
	//scorestring[strlen(scorestring)-1]='\0';
	(void)memset(scorestring, '\0', 32);
	//if(fps > 10)
	//	return;
	//	printf("Error!\n");
	int empty = 0;
	empty = sprintf(scorestring, "%.02lf", fps);
	//printf("%.02lf\n", fps);
	int i = 0;
	//GLint params;
	glPushMatrix();
	glLoadIdentity();
	//glColor3f(1.0, 1.0, 1.0);
	//glGetIntegerv(GL_CURRENT_RASTER_POSITION, &params);
	//printf("%d\n", params);
	glRasterPos3i(3, 8, -15);
	//glRasterPos3f((GLfloat)0.0, (GLfloat)0.0, (GLfloat)0.0);
	//glRasterPos3f((GLfloat)-0.75, (GLfloat)1.1, (GLfloat)0.0);
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'F');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'P');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'S');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'(');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'c');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'a');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'p');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'1');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'0');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,')');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,':');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	//scorestring[strlen(scorestring)-1]='\0';
	//empty = sprintf(scorestring, "%.02lf", fps);
	for(i = 0; scorestring[i] != '\0'; i++){
		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, scorestring[i]);
	}
	/*
	//ia->cur_sealevel
	glLoadIdentity();
	glColor3f(1.0, 1.0, 1.0);
	glRasterPos3f(3, 6, -15);
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,'');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,' ');
	*/

	glPopMatrix();
}



//GLuint LoadTexture(void){
    //static struct timespec ts;
    //ts.tv_sec = 0;
    //ts.tv_nsec = 100000;
	//static int loaded = 0;
	//GLuint texture;

	//glDeleteTextures( 1, &texture );
	//glGenTextures( 1, &Image_Texture );

	//glBindTexture( GL_TEXTURE_2D, Image_Texture );

	//glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
	//glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
//	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
//	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
//	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	//while(Image_Locked){
	//	nanosleep (&ts, NULL);
	//}
	//Image_Locked = 1;
	//if(loaded)
	//	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ia->width, ia->height, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)ia->image);
	//else
//	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ia->width, ia->height, 0, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)ia->image);
	//Image_Locked = 0;
	//loaded = 1;
//	return 1;
//}

//static void FreeTexture( GLuint texture ){
//	glDeleteTextures( 1, &texture );
//}

static void BindTexture(GLuint texture){
	//glDeleteTextures( 1, &texture );
	//glGenTextures( 1, &Image_Texture );
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)ia->image);
	glBindTexture( GL_TEXTURE_2D, Image_Texture );
	glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

	//glRotatef( 180, 0.0f, 0.0f, 1.0f );
	//float aspect = im_p->width / im_p->height;
	//float aspect2 = im_p->height / im_p->width;
//	float y = 1;
	//float y = (aspect>1)? x/aspect: x*aspect;
//	float x = y*aspect;
	float x = 1;
	float y = 1;
	//glScalef(aspect1, aspect2, 1);
/*
    glBegin (GL_QUADS);
    glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0); //with 
    glTexCoord2d(1.0,0.0); glVertex2d(+1.0,-1.0); //so that
    glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0);
    glTexCoord2d(0.0,1.0); glVertex2d(-1.0,+1.0);
    glEnd();
	

*/
    glBegin (GL_QUADS);
    glTexCoord2d(0.0,y); glVertex2d(x,-1.0*y);
    glTexCoord2d(0.0,0.0); glVertex2d(x,y);
    glTexCoord2d(x,0.0); glVertex2d(-1.0*x,y);
    glTexCoord2d(x,y); glVertex2d(-1.0*x,-1.0*y);
    glEnd();


	//This is how texture coordinates are arranged
	//
	//  0,1   ---   1,1
	//       |     |
	//       |     |
	//       |     |
	//  0,0   ---   1,0


}

static void display(void){
	static struct timespec ts;
    ts.tv_sec = 0; 
    ts.tv_nsec = 100000000; //1/10th of a second
	//uint32_t skip = 25;
	static double time1 = 2;
	static double frame_c = 0;
	static double fps = 0;
    glClearColor (0.0,0.0,0.0,1.0);
    //glClear (GL_COLOR_BUFFER_BIT);
	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
	//glClearColor (0.0,0.0,0.0,1.0);
    glEnable( GL_TEXTURE_2D );
	//GLuint texture;
	//texture = LoadTexture( im_p );
	gluLookAt ( Eye_X, Eye_Y, Eye_Z,  Eye_X, Eye_Y, 0.0, 0.0, 0.1, 0.0);
	//gluLookAt( , Eye_Y, Eye_Z, Look_X, Look_Y, 20, 0, .1, 0);

	//while(Image_Locked){
	//	sleep(
	//}
	//nanosleep (&ts, NULL);

	//Drawl_Image();

	//might as well make these one func
	//(void)LoadTexture();
	BindTexture(Image_Texture);


	frame_c++; //frame counter
	if(time1 > 1){
		gettimeofday(&endtime, NULL);
		time1=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
		fps = frame_c / time1;
		gettimeofday(&starttime, NULL);
		frame_c = 0;
	}else{
		gettimeofday(&endtime, NULL);
		time1=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
	}
	Frames(fps);

	//glutSwapBuffers();
	glFlush();
    glutSwapBuffers();
	//sleep(1);
	glutPostRedisplay();
	nanosleep (&ts, NULL);
	
	


	//FreeTexture( Image_Texture );

	//sleep(1);
	//FreeTexture(texture);

}


static void reshape(int w, int h){
	GLfloat aspect = (GLfloat)WIDTH / (GLfloat)HEIGHT;
	//GLsizei width;
	//GLzisei height; 
	

    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
	gluPerspective (60, (GLfloat)w / (GLfloat)h/aspect, 0.0 , 100.0);
    //gluPerspective (60, (GLfloat)im_p->width / (GLfloat)im_p->height, 1.0, 100.0);
    glMatrixMode (GL_MODELVIEW);

}



void *Run_GL(void *bla){
	//im_p = im;

	//int bla1;
	//char **bla2 = NULL;
    //glutInit (&bla1, bla2);

    //query_ext(); 
    glutInitDisplayMode (GLUT_DOUBLE| GLUT_RGB | GLUT_DEPTH);
	//	glutInitDisplayMode (GLUT_DOUBLE);

	//printf("w: %zu h: %zu\n", a->width, ia->height);
    //glutInitWindowSize((int)im->width/4, (int)im->height/4);
	glutInitWindowSize(GLWIDTH, GLHEIGHT); 

   glutInitWindowPosition (0, 0);
    glutCreateWindow ("A basic OpenGL Window");
    glutDisplayFunc (display);
    //glutIdleFunc (display);
    glutReshapeFunc (reshape);
    //glutMotionFunc(mouse_active);
    //glutPassiveMotionFunc(mouse_passive); 
    //query_ext();
	glutIgnoreKeyRepeat(0); 
    glutSpecialFunc(special);
	//(void)LoadTexture( im_p );

	//sleep(4);
	glGenTextures( 1, &Image_Texture );
	//(void)LoadTexture();
	//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ia->width, ia->height, 0, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)ia->image); 
	//gettimeofday(&starttime, NULL); 
	createGLUTMenus();
	glutMainLoop ();
	//FreeTexture( Image_Texture ); 
   //return 0;
	pthread_exit(NULL);
}