//*****************************************************************************************
// Disclaimer, Authorship and License
/*
	This code has been written to serve as a learning tool for the course MAE 410-574, 
	Virtual Reality Applications and Research, Spring 2007.
	
	Large parts of the code has been adapted from the examples given in the OpenGL 
	Programming Guide by Woo et. al and also from Computer Graphics Using OpenGL by FS Hill
	Some parts of the code has also been adapted from various resources available through 
	out the internet.I thank all those whose code and resources I have used to write these 
	examples. You may use this code for any non-commerical purpose. Feel free to include 
	and use parts of this code for your own application, but remember that this code is not
	entirely bug free, use it at your own risk..If you plan on using the code for your any 
	academic purpose please drop me an email. I would like to attach a link to your course 
	from my home page.

	The Author of this code is Govindarajan Srimathveeravalli, Dept. of Mech and Aero Eng. ,
	University at Buffalo.
*/
//******************************************************************************************
// As done for the points, here we try to draw line strips and loops (as opposed to just lines).
// Here we demonstrate all attributes used for lines, namely, line width and line stipple. We also 
// make use of the mouse to draw the lines here. This code also demonstrates the relation between
// gluOrtho2D (Which defines the world and window through which we view it), glViewport (The scre
// en area on which the rendering is done) and mouse clicks done through glutMouseFunc. It is to
// be noted that all mouse clicks are returned in terms of relative window size (pixel value with
// origin always at top left hand corner and y increasing downwards). Hence unless we position the
// origin of our world too along the same coordiante set up we need to "map" the mouse clicks to
// our world
// Try the following
// 1. Uncomment the different codes in the init function to alter the world view. How do the mouse
//    clicks values vary accordingly ?
// 2. The line drawn using the code will get erased when the window is altered (resized etc.) How
//    do you retain the graphics rendered on the screen ?

#include <stdlib.h>
#include <math.h>
#include <glut.h>
#include <iostream>

using namespace std;

typedef struct 
{
	float x;
	float y;
	float z;
}point;


const int numPoints = 100;
unsigned int numClicks = 0;
point pointSet[ numPoints ];
unsigned int oldIndex = 0;

// pass lineType 1 for line_strip and 2 for line_loop
void drawLine( int lineType, int lineWidth )
{
	glLineWidth( lineWidth );
	
	switch( lineType )
	{
	case 1:
		{
			glBegin( GL_LINE_STRIP );
				// for number of clicks occured draw lines
				for( unsigned int i=0; i<numClicks; i++)
				{
					glVertex3f( pointSet[i].x, pointSet[i].y, pointSet[i].z );
					pointSet[i].x = 0.;
					pointSet[i].y = 0.;
					pointSet[i].z = 0.;
				}
				glEnd();

				cout << "coming here? \n";
				// reset number of clicks
				numClicks = 0;
		};

	case 2:
		{
			glBegin( GL_LINE_LOOP );
				// for number of clicks occured draw lines
				for( unsigned int i=0; i<numClicks; i++)
				{
					glVertex3f( pointSet[i].x, pointSet[i].y, pointSet[i].z );
					pointSet[i].x = 0.;
					pointSet[i].y = 0.;
					pointSet[i].z = 0.;
				}
				glEnd();

				// reset number of clicks
				numClicks = 0;
		};
	}
	
	

}

void mouseClickFunc( int button, int state, int x, int y )
{
	
	if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
	{
		pointSet[ numClicks ].x = x;
		pointSet[ numClicks ].y = y;
		pointSet[ numClicks ].z = 0.;
		numClicks++;
		cout << x << "  " << y  << "\n";
	}
	else if( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN )
	{
		drawLine( 1, 2 );
	}
}


void reshape( int w, int h)
{
	
	//glViewport( 0., 0., w, h );
	glutPostRedisplay();
}

void display( )
{
	// Clear the background before drawing
	glClear( GL_COLOR_BUFFER_BIT );

	// Coloring
	glColor3f( 1., 0., 0. );

	// draw an arbitrary square somewhere to determine the difference
	// between window - viewport and mouse click coordinates, the square
	// is always centered around (0,0) as defined in gluOrtho2D, the various
	// values of gluOrtho2D should case the apparent position of the square
	// wrt to the screen to change about.
	glBegin( GL_POLYGON );
		glVertex3f( -50., -50., 0. );
		glVertex3f( 50., -50., 0. );
		glVertex3f( 50., 50., 0. );
		glVertex3f( -50., 50., 0. );
	glEnd();

	// Ensure all drawing commands are executed
	glutSwapBuffers( );
}

void init( )
{
	// Set the background 
	glClearColor( 0., 0., 0. , 0. );

	// Setting up a rudimentary camera
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity( );

	// case 1: the world is set up with the origin at bottom left hand corner
	// the square will be plotted there.
	//gluOrtho2D( 0, 640., 0. , 480  );	

	// case 2: the world is set up with the origin at top left hand corner
	// the square will be plotted there, this is the only case where the mouse
	// clicks and window coordinates have a correct mapping
	gluOrtho2D( 0, 640., 480. , 0.  );

	// case 3: the world is set up with the origin at the center of the screen
	// the square will be plotted there.
	//gluOrtho2D( -320, 320., -240. , 240  );
}

int main(int argc, char* argv[])
{

	// Initialize a window with command line arguments
	glutInit( &argc, argv );
	// Provide window with buffering, coloring information
	glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );
	// Position and Size the window
	glutInitWindowPosition( 50, 50 );
	glutInitWindowSize( 540, 480 );
	// Create the window with the given features with a 'suitable title'
	glutCreateWindow( "Hello World" );

	// do some initialization like setting up background color, camera, projection type etc.
	init( );

	// Assign a display 'callback function'
	glutDisplayFunc( display );

	// The reshape function is called everytime the window is relocated or resized ! duh
	glutReshapeFunc( reshape );

	// adding a function to handle mouse clicks
	glutMouseFunc( mouseClickFunc );
	// Enter the graphics loop
	glutMainLoop( );

	return 0;
}


