//
// Torbert, 11.11.2009
//
// Display strings in OpenGL.
//
// Time segments of the code.
//

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

#define LAG 1

int w=400,h=300; // initial window size
int flag=0;

time_t time_tic,time_toc;
double clock_tic,clock_toc;

void drawString(char* s)
{
	int k;
	for(k=0;k<strlen(s);k++)
		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,s[k]);
}
/*
	GLUT_BITMAP_8_BY_13
	GLUT_BITMAP_9_BY_15
	GLUT_BITMAP_TIMES_ROMAN_10
	GLUT_BITMAP_TIMES_ROMAN_24
	GLUT_BITMAP_HELVETICA_10
	GLUT_BITMAP_HELVETICA_12
	GLUT_BITMAP_HELVETICA_18
*/
void display(void)
{
   double t;
	char   b[30]; // buffer for string output
	int newtime,oldtime;

   glClear(GL_COLOR_BUFFER_BIT); // clear the screen
   glColor3f(0.0,0.0,0.0);

	oldtime=glutGet(GLUT_ELAPSED_TIME);
	for(t=0.0;t<2.0*M_PI;t+=0.01)
   { 
   	glBegin(GL_POINTS);
   	glVertex2f(w/2.0+100.0*cos(t),h/2.0+100.0*sin(t));
   	glEnd();
   	glFlush();

		newtime=-1;
		while(newtime==-1 || oldtime+LAG>newtime)
			newtime=glutGet(GLUT_ELAPSED_TIME);
		oldtime=newtime;
   }

	time_toc=time(NULL);
	clock_toc=clock();
	printf("time: %ld\n",time_toc-time_tic);
	printf("clock: %lf\n",(clock_toc-clock_tic)/CLOCKS_PER_SEC);
	printf("CLOCKS_PER_SEC: %d\n",CLOCKS_PER_SEC);

	sprintf(b,"%ld",time_toc-time_tic);
	glRasterPos2f(50,50);
	drawString(b);

   glFlush(); // single buffering, for double use glutSwapBuffers();
}
void idle(void)
{
	if(flag)
		glutPostRedisplay(); // callback
}
void dragged(int xscr,int yscr)
{
//	printf("Dragged: (%d,%d)\n",xscr,yscr);
}
void moved(int xscr,int yscr)
{
	printf("Moved: (%d,%d)\n",xscr,yscr);
}
void mouse(int button,int state,int xscr,int yscr)
{
	if(button==GLUT_LEFT_BUTTON)
		if(state==GLUT_DOWN)
		{
			flag=(flag+1)%2;
		}
}
void keyfunc(unsigned char key,int xscr,int yscr)
{
	if(key=='q')
	{
		exit(0);
	}
}
void specialfunc(int key,int xscr,int yscr)
{
	if(key==GLUT_KEY_UP)
	{
		printf("Up Arrow\n");
	}
	else if(key==GLUT_KEY_DOWN)
	{
		printf("Down Arrow\n");
	}
	else if(key==GLUT_KEY_LEFT)
	{
		printf("Left Arrow\n");
	}
	else if(key==GLUT_KEY_RIGHT)
	{
		printf("Right Arrow\n");
	}
}
void reshape(int wscr,int hscr)
{
	w=wscr; h=hscr;
   glViewport(0,0,(GLsizei)w,(GLsizei)h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
	gluOrtho2D(0,w-1,0,h-1); // vertices specified in pixel coordinates
   glMatrixMode(GL_MODELVIEW);
}
int main(int argc,char* argv[])
{  
   glutInit(&argc,argv);
   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // single buffering
   glutInitWindowSize(w,h);                     // for double use GLUT_DOUBLE
   glutInitWindowPosition(100,50);
   glutCreateWindow("OpenGL Demo");

   glClearColor(1.0,1.0,1.0,0.0);
	glShadeModel(GL_SMOOTH);

	time_tic=time(NULL);
	clock_tic=clock();

   glutDisplayFunc(display);		// register callback functions
	glutIdleFunc(idle);
   glutMouseFunc(mouse);
   glutMotionFunc(dragged);
   glutPassiveMotionFunc(moved);
	glutKeyboardFunc(keyfunc);
	glutSpecialFunc(specialfunc);
	glutReshapeFunc(reshape);

   glutMainLoop();					// here we go

   return 0;
}
// 
// Notes
// -----
// chmod 755 Lgcc
// ./Lgcc timing_demo
// ./timing_demo
// 
