// OpenGL Tutorial
// primitives.c - TJ VERSION
// http://www.eecs.tulane.edu/www/Terry/OpenGL/Introduction.html
/*************************************************************************
This example extends Hello_World.c to accept and handle events.  The
user should try produce each of the following events: key press, mouse
movement, mouse button press, mouse button release, reshape window, and
expose window.
*************************************************************************/

// gcc primitives.c -lm -L/usr/lib -lGLU  -lGL -lglut  -L/usr/X11R6/lib -lX11 -lXext -lXi -lXmu

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

void init() {

	// Clear the window
	glClear(GL_COLOR_BUFFER_BIT);
}

void reshape(int width, int height) {

	// Set the new viewport size
	glViewport(0, 0, (GLint)width, (GLint)height);

	// Choose the projection matrix to be the matrix 
	// manipulated by the following calls
	glMatrixMode(GL_PROJECTION);

	// Set the projection matrix to be the identity matrix
	glLoadIdentity();

	// Define the dimensions of the Orthographic Viewing Volume
	glOrtho(-8.0, 8.0, -8.0, 8.0, -8.0, 8.0);

	// Choose the modelview matrix to be the matrix
	// manipulated by further calls
	glMatrixMode(GL_MODELVIEW);

	// Clear the window
	glClear(GL_COLOR_BUFFER_BIT);
}

void keypressed(unsigned char key, int x, int y) {

	if (key == (unsigned char) 27)
		exit(0);
}

void draw(void) {

	// Set the drawing color
	glColor3f(1.0, 1.0, 1.0);

	// Set the modelview matrix to be the identity matrix
	glLoadIdentity();
	// Translate the object
	glTranslatef(-5.0, 5.0, 0.0);

	// Draw the verticies connected according to the GL_LINES primitive
	glBegin(GL_LINES);

		// Vertex 1
		glVertex2f(-1.0, 1.0);

		// Vertex 2
		glVertex2f(2.0, 2.0);

		// Vertex 3
		glVertex2f(0.0, 0.0);

		// Vertex 4
		glVertex2f(1.0, -1.0);

		// Vertex 5
		glVertex2f(-2.0, -2.0);

	glEnd();

	glLoadIdentity();
	glTranslatef(0.0, 5.0, 0.0);

	glBegin(GL_LINE_STRIP);
		glVertex2f(-1.0, 1.0);
		glVertex2f(2.0, 2.0);
		glVertex2f(0.0, 0.0);
		glVertex2f(1.0, -1.0);
		glVertex2f(-2.0, -2.0);
	glEnd();

	glLoadIdentity();
	glTranslatef(5.0, 5.0, 0.0);

	glBegin(GL_LINE_LOOP);
		glVertex2f(-1.0, 1.0);
		glVertex2f(2.0, 2.0);
		glVertex2f(0.0, 0.0);
		glVertex2f(1.0, -1.0);
		glVertex2f(-2.0, -2.0);
	glEnd();

	glLoadIdentity();
	glTranslatef(-5.0, 0.0, 0.0);

	glBegin(GL_POLYGON);
		glVertex2f(-1.0, 1.0);
		glVertex2f(2.0, 2.0);
		glVertex2f(0.0, 0.0);
		glVertex2f(1.0, -1.0);
		glVertex2f(-2.0, -2.0);
	glEnd();

	glLoadIdentity();
	glTranslatef(0.0, 0.0, 0.0);

	glBegin(GL_QUADS);
		glVertex2f(-1.0, 1.0);
		glVertex2f(2.0, 2.0);
		glVertex2f(0.0, 0.0);
		glVertex2f(1.0, -1.0);
		glVertex2f(-2.0, -2.0);
	glEnd();

	glLoadIdentity();
	glTranslatef(5.0, 0.0, 0.0);

	glBegin(GL_QUAD_STRIP);
		glVertex2f(-1.0, 1.0);
		glVertex2f(2.0, 2.0);
		glVertex2f(0.0, 0.0);
		glVertex2f(1.0, -1.0);
		glVertex2f(-2.0, -2.0);
	glEnd();

	glLoadIdentity();
	glTranslatef(-5.0, -5.0, 0.0);

	glBegin(GL_TRIANGLES);
		glVertex2f(-1.0, 1.0);
		glVertex2f(2.0, 2.0);
		glVertex2f(0.0, 0.0);
		glVertex2f(1.0, -1.0);
		glVertex2f(-2.0, -2.0);
	glEnd();

	glLoadIdentity();
	glTranslatef(0.0, -5.0, 0.0);

	glBegin(GL_TRIANGLE_STRIP);
		glVertex2f(-1.0, 1.0);
		glVertex2f(2.0, 2.0);
		glVertex2f(0.0, 0.0);
		glVertex2f(1.0, -1.0);
		glVertex2f(-2.0, -2.0);
	glEnd();

	glLoadIdentity();
	glTranslatef(5.0, -5.0, 0.0);

	glBegin(GL_TRIANGLE_FAN);
		glVertex2f(-1.0, 1.0);
		glVertex2f(2.0, 2.0);
		glVertex2f(0.0, 0.0);
		glVertex2f(1.0, -1.0);
		glVertex2f(-2.0, -2.0);
	glEnd();

	// Flush the buffer to force drawing of all objects thus far
	glFlush();
}

int main(int argc, char **argv) {

	// Set top left corner of window to be at location (20, 20)
	// Set the window size to be 500x500 pixels
	// Open a window and name it
	// Open a window, name it "Events"
	glutInit(&argc, argv);  
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
	glutInitWindowSize(500, 500); 
	glutInitWindowPosition(20,20); 
	glutCreateWindow("Primitives");	
	
	// Set the clear color to black
	glClearColor(0.0, 0.0, 0.0, 0.0);

	init();

	// Assign reshape() to be the function called whenever 
	// a reshape event occurs
	glutReshapeFunc(reshape);

	// Assign keypressed() to be the function called whenever
	// a key is pressed
	glutKeyboardFunc(keypressed);

	// Assign draw() to be the function called whenever a display
	// event occurs, generally after a resize or expose event
	glutDisplayFunc(draw);

	// Pass program control to GLUT's event handling code
	// In other words, loop forever
	glutMainLoop();

	return 0;
}