// OpenGL Tutorial
// Events.c

/*************************************************************************
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 -o Events  Events.c -lX11 -lMesaGL -lMesaGLU -lMesatk -lm

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gltk.h>

void expose(int width, int height) {

	printf("Got an Expose Event");
	printf(":\t width = %d height = %d\n", width, height);

	// Clear the window
	glClear(GL_COLOR_BUFFER_BIT);
}

void reshape(int width, int height) {

	printf("Got a Reshape Event");
	printf(":\t width = %d height = %d\n", width, height);

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

	// Clear the window
	glClear(GL_COLOR_BUFFER_BIT);
}

GLenum key_down(int key, GLenum state) {

	printf("Got a Key Down Event");
	printf(":\t key = %d, state = %d\n", key, state);

	if ((key == TK_ESCAPE) || (key == TK_q) || (key == TK_Q))
		tkQuit();
}

GLenum mouse_down(int x, int y, GLenum state) {

	printf("Got a Mouse Down Event");
	printf(":\t x = %d, y = %d, button = ", x, y);

	switch (state) {
		case TK_LEFTBUTTON : printf("left\n");
			break;
		case TK_RIGHTBUTTON : printf("right\n");
			break;
		case TK_MIDDLEBUTTON : printf("middle\n");
			break;
		default : printf("none\n");
			break;
	}
}

GLenum mouse_up(int x, int y, GLenum state) {

	printf("Got a Mouse Up Event");
	printf(":\t x = %d, y = %d, button = ", x, y);

	switch (state) {
		case TK_LEFTBUTTON : printf("left\n");
			break;
		case TK_RIGHTBUTTON : printf("right\n");
			break;
		case TK_MIDDLEBUTTON : printf("middle\n");
			break;
		default : printf("none\n");
			break;
	}
}

GLenum mouse_move(int x, int y, GLenum state) {

	printf("Got a Mouse Move Event");
	printf(":\t x = %d, y = %d, button = ", x, y);

	switch (state) {
		case TK_LEFTBUTTON : printf("left\n");
			break;
		case TK_RIGHTBUTTON : printf("right\n");
			break;
		case TK_MIDDLEBUTTON : printf("middle\n");
			break;
		default : printf("none\n");
			break;
	}
}

void draw(void) {

	printf("Got a Display Event\n");

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

	// Specify which primitive type is to be drawn
	glBegin(GL_POLYGON);
		// Specify verticies in quad
		glVertex2f(-0.5, -0.5);
		glVertex2f(-0.5, 0.5);
		glVertex2f(0.5, 0.5);
		glVertex2f(0.5, -0.5);
	glEnd();

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

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

	// Open a window and name it
	if (tkInitWindow("Events") == GL_FALSE) {
		tkQuit();
	}

	// Set the clear color to black
	glClearColor(0.0, 0.0, 0.0, 0.0);

	// Assign expose() to be the function called whenever
	// an expose event occurs
	tkExposeFunc(expose);

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

	// Assign key_down() to be the function called whenever
	// a key is pressed
	tkKeyDownFunc(key_down);

	// Assign mouse_down() to be the function called whenever
	// a mouse button is pressed
	tkMouseDownFunc(mouse_down);

	// Assign mouse_up() to be the function called whenever
	// a mouse button is released
	tkMouseUpFunc(mouse_up);

	// Assign mouse_move() to be the function called whenever
	// the mouse is moved
	tkMouseMoveFunc(mouse_move);

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

	// Assign idle() to be the function called whenever there 
	// are no events, NOT USED IN THIS EXAMPLE
//	tkIdleFunc(idle);

	// Pass program control to tk's event handling code
	// In other words, loop forever
	tkExec();
}
