//#include <windows.h>   // use as needed for your system
#include <stdlib.h>
#include <fstream.h>
#include <GLUT/glut.h>
//<<<<<<<<<<<<<<<<<<<<<<< myInit >>>>>>>>>>>>>>>>>>>>
 void myInit(void)
 {
    glClearColor(1.0,1.0,1.0,0.0);       // set white background color
    glColor3f(0.0f, 0.0f, 0.0f);          // set the drawing color 
 	glPointSize(4.0);		       // a ‘dot’ is 4 by 4 pixels
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity();
	gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
//<<<<<<<<<<<<<<<<<<<<<<<< myDisplay >>>>>>>>>>>>>>>>>
void myDisplay(void)
{
	glClear(GL_COLOR_BUFFER_BIT);     // clear the screen 
	glBegin(GL_LINE_LOOP);
		glVertex2i(100, 50);         // draw three points
		glVertex2i(100, 130);
		glVertex2i(150, 130);
	glEnd();	
	glFlush();		                 // send all output to display 
}
//<<<<<<<<<<<<<<<<<<<<<<<< random >>>>>>>>>>>>>>>>>
int random(int m) {
  return rand()%m;
}
//<<<<<<<<<<<<<<<<<<<<<<<< Utility class  >>>>>>>>>>>>>>>>>
class GLintPoint {
  public :
    GLint x,y;
};
//<<<<<<<<<<<<<<<<<<<<<<<< drawDot  >>>>>>>>>>>>>>>>>
void drawDot( GLint x, GLint y) {
	glBegin(GL_POINTS);
		glVertex2i(x,y);
	glEnd();
}
//<<<<<<<<<<<<<<<<<<<<<<<< drawPolyLine  >>>>>>>>>>>>>>>>>
void drawPolyLineFile(char * fileName)
{
	fstream inStream;
	inStream.open(fileName, fstream::in);	// open the file
	if(inStream.fail())
		return;
	glClear(GL_COLOR_BUFFER_BIT);      // clear the screen 
	GLint numpolys, numLines, x ,y;
	inStream >> numpolys;		           // read the number of polylines
	for(int j = 0; j < numpolys; j++)  // read each polyline
	{
		inStream >> numLines;
		glBegin(GL_LINE_STRIP);	     // draw the next polyline
		for (int i = 0; i < numLines; i++)
		{
			inStream >> x >> y;        // read the next x, y pair
			glVertex2i(x, y);
		}
		glEnd();
	}
	glFlush();
	inStream.close();
}
//<<<<<<<<<<<<<<<<<<<<<<<< myDisplay >>>>>>>>>>>>>>>>>
void myDisplayPoly(void)
{
  drawPolyLineFile( "dino.dat" );

}
//<<<<<<<<<<<<<<<<<<<<<<<< Sierpinski >>>>>>>>>>>>>>>>>
void Sierpinski(void) 
{
	GLintPoint T[3]= {{10,10},{300,30},{200, 300}};
	
	int index = random(3);         // 0, 1, or 2 equally likely 
	GLintPoint point = T[index]; 	 // initial point 
	glClear(GL_COLOR_BUFFER_BIT);     // clear the screen

	drawDot(point.x, point.y);     // draw initial point 

	for(int i = 0; i < 10000; i++)  // draw 1000 dots
	{
		 index = random(3); 	
		 point.x = (point.x + T[index].x) / 2;
		 point.y = (point.y + T[index].y) / 2;
        glColor3f( random(255)/255.0, random(255)/255.0, random(255)/255.0 );
		 drawDot(point.x,point.y);  
	} 
	glFlush(); 	
}
//<<<<<<<<<<<<<<<<<<<<<<<< doMyMenuActions >>>>>>>>>>>>>>>>>
void doMyMenuActions(int Choice) {
  switch(Choice) {
    case 1: glutDisplayFunc( Sierpinski ); break;
    case 2: glutDisplayFunc( myDisplayPoly ); break;
    }
  glutPostRedisplay();
}
//<<<<<<<<<<<<<<<<<<<<<<<< initMenus >>>>>>>>>>>>>>>>>
void initMenus(void) {
  glutCreateMenu(doMyMenuActions);
  glutAddMenuEntry("Sierpinski",1);
  glutAddMenuEntry("Dino", 2);
  glutAttachMenu(GLUT_RIGHT_BUTTON);
}
//<<<<<<<<<<<<<<<<<<<<<<<< main >>>>>>>>>>>>>>>>>>>>>>
int main(int argc, char** argv)
{
	glutInit(&argc, argv);          // initialize the toolkit
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
	glutInitWindowSize(640,480);     // set window size
	glutInitWindowPosition(100, 150); // set window position on screen
	glutCreateWindow("Menu example"); // open the screen window
        initMenus();
	glutDisplayFunc( Sierpinski );     // register redraw function
	myInit();                   
	glutMainLoop(); 		     // go into a perpetual loop
        return 0;
}
