#include <GL/glut.h>
#include <vector>
#include <stdlib.h>
#include <string>

#define RED 1
#define GREEN 2
#define BLUE 3
#define WHITE 4

unsigned int currentcolor=1;
using namespace std;

struct Point{
	float x;
	float y;
	float z;
};

vector<Point> points;
int xRot = 0;

// render a string of characters given a 3D position and a string
void renderGLText(GLfloat x, GLfloat y, GLfloat z, string str)
{
	char msg[255];
	sprintf(msg, str.c_str());
	glRasterPos3f(x,y,z);
	for (int i=0; i<strlen(msg); i++)
		glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, msg[i]);
} // end gl render text


void init() {
	// set up cube
	Point p;
	points.clear();
	points.reserve(8);
	p.x = -1; p.y = -1; p.z = -1; points.push_back(p); //0
	p.x = 1; p.y = -1; p.z = -1; points.push_back(p); // 1
	p.x = 1; p.y = 1; p.z = -1; points.push_back(p);  // 2
	p.x = -1; p.y = 1; p.z = -1; points.push_back(p); // 3
	p.x = -1; p.y = 1; p.z = 1; points.push_back(p);  // 4
	p.x = -1; p.y = -1; p.z = 1; points.push_back(p); // 5
	p.x = 1; p.y = -1; p.z = 1; points.push_back(p);  // 6
	p.x = 1; p.y = 1; p.z = 1; points.push_back(p);   // 7
	// openGL initialization
	glClearColor(0,0,0,0);
	glShadeModel(GL_FLAT);
	glEnable(GL_DEPTH_TEST);
} // end init

void drawPoint(int i)
{
	if (i >= 0 && i < points.size())
		glVertex3f(points[i].x, points[i].y, points[i].z);
} // end drawpoint

void drawCube()
{
	glBegin(GL_TRIANGLE_STRIP);
		// draw front
		drawPoint(5); // bottom left front corner
		drawPoint(6); // bottom right front corner
		drawPoint(4); // top left front corner
		drawPoint(7); // top right front corner
		drawPoint(3); // top left back corner
		drawPoint(2); // top right back corner
		drawPoint(0); // bottom left back corner
		drawPoint(1); // bottom right back corner
		drawPoint(5); // loop back to front again
		drawPoint(6);
	glEnd();
} // end draw cube

void reshape(int w, int h)
{
	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	//glOrtho(-2, 2, -2, 2, -100, 100);
	glFrustum(-2,2,-2,2,1,10);
	glMatrixMode(GL_MODELVIEW);
} // end reshape

void display()
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	switch(currentcolor) {
	case RED:
		glColor3f(1,0,0);
		break;
	case GREEN:
		glColor3f(0,1,0);
		break;
	case BLUE:
		glColor3f(0,0,1);
		break;
	case WHITE:
		glColor3f(1,1,1);
		break;
	default:
		glColor3f(.5f,.5f,.5f);
	} // end switch

	glLoadIdentity();
        glTranslatef(0,0,-2.5);
	glRotatef(xRot,0,1,0);
	
	drawCube();

	glColor3f(1,1,1);
	glutWireCube(2.1);

	glFlush();
	//glutSwapBuffers();
}

void moveEvent(int x, int y)
{
	xRot += 1;
	if (xRot >= 360) xRot -= 360;
	glutPostRedisplay();
}

void processMenuEvents(int option)
{
	currentcolor = option;
}

void createGLUTMenus() {
	int menu;
	menu = glutCreateMenu(processMenuEvents);
	glutAddMenuEntry("Red",RED);
	glutAddMenuEntry("Blue",BLUE);
	glutAddMenuEntry("Green",GREEN);
	glutAddMenuEntry("White",WHITE);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	//glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH|GLUT_RGB);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_DEPTH|GLUT_RGB);
	glutInitWindowSize(500,500);
	glutInitWindowPosition(100,100);
	glutCreateWindow(argv[0]);
	
	init();
	createGLUTMenus();

	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutMotionFunc(moveEvent);
	glutMainLoop();
	return 0;
} // end main
	
	

