#include <GL/glut.h>
#include <math.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include "GadTicTacToe.h"

void displayBox(int);
void done();
void MenuFunc(GLint selectedOption);
void reset();

GadTicTacToe T;

int whoStarts = 0;
char charChoiceP1 = 'X';
char charChoiceP2 = 'O';
char anotherGameChoice;
int p1Human = 0;
int p2Human = 0;
bool p1H=true;
bool p2H=true;
bool Xwinner = false, Owinner = false;
int diffP1=0;
int diffP2=0;
float Xcolor = 0, Ocolor = 0;
bool GameDone = false;
int diff = 5;
int whoseTurn = whoStarts;

float ImageH = 400, ImageW = 400;

void init(void)
{
	reset();
	
	GLfloat none[] = {0.0,0.0,0.0,0.0};
	GLfloat light[] = {0.2,0.2,0.2,1.0};

	GLfloat lmodel_ambient[] = {0.2,0.2,0.2,0.0};
	GLfloat ambient[] = {0.6,0.6,0.6,0.0};

	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light);
	glShadeModel(GL_SMOOTH);
	
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);

	GLfloat light_position0[] = {0,0,-1};
	glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light);
	glLightfv(GL_LIGHT0, GL_SPECULAR, none);
	glEnable(GL_LIGHT0);


	glViewport(0, 0, (GLsizei) ImageW, (GLsizei) ImageH);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(100, (GLfloat) ImageW/(GLfloat) ImageH, 0.001, 100);
	gluLookAt(-.01,.01,-1,0,0,0,0,1,0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	
}

void createCylinder(GLdouble radius, GLdouble height, GLint slices, GLint stacks)
{
	GLUquadricObj* obj;
	obj = gluNewQuadric();
	glPushMatrix();
		glScalef(1.0,1.0,0.2);
		glutSolidSphere(radius, 10,10);
	glPopMatrix();	
	
	gluCylinder(obj, radius, radius, height, slices, stacks);


	glPushMatrix();
		glTranslatef(0,0,height);
		glScalef(1.0,1.0,0.2);
		glutSolidSphere(radius, 10,10);
	glPopMatrix();	
	gluDeleteQuadric(obj);

}



void display(void)
{
	if(T.getTurnCounter() == 0 && whoStarts == 1)
	{
		T.computerMove('O', diff);
		whoseTurn++;
	}

	if(T.didPlayer1Win())
	{
		Xcolor = 1;
		Xwinner = true;
		GameDone = true;
	}
	else if(T.didPlayer2Win())
	{
		Ocolor = 1;
		Owinner = true;
		GameDone = true;
	}
	else if(T.isBoardFull())
	{
		Xcolor = -.09;
		Ocolor = -1;
		GameDone = true;
	}

	GLfloat mat_specular[] = {0.0,0.0,0.0,0.0};

	glEnable(GL_COLOR_MATERIAL);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	glPushMatrix();
	glPushMatrix();

	glColor3f(1,1,1);
	glScalef(1.5,1.5,1);
	glTranslatef(0,0,.5);
//	glutSolidCube(1);

	glPopMatrix();
	glPushMatrix();


	glColor3f(1,.2,.2);
	glTranslatef(.18,0,-.5); 
	glScalef(.05,1,.05);
	glRotatef(45,0,1,0);
	glutSolidCube(1);
	glRotatef(-45,0,1,0);

	glTranslatef(-7.2,0,0); 
	glRotatef(45,0,1,0);
	glutSolidCube(1);

	
	
	
	glPopMatrix();
	glPushMatrix();

	glTranslatef(0,.18,-.5); 
	glScalef(1,.05,.05);
	glRotatef(45,1,0,0);
	glutSolidCube(1);
	glRotatef(-45,1,0,0);

	glTranslatef(0,-7.2,0); 
	glRotatef(45,1,0,0);
	glutSolidCube(1);


	glPopMatrix();
	glPushMatrix();
	

	glLoadIdentity();
	glTranslatef(.38,.38,-.5);
	displayBox(0);

	glLoadIdentity();
	glTranslatef(0,.38,-.5);
	displayBox(1);

	glLoadIdentity();
	glTranslatef(-.38,.38,-.5);
	displayBox(2);




	glLoadIdentity();
	glTranslatef(.38,0,-.5);
	displayBox(3);

	glLoadIdentity();
	glTranslatef(0,0,-.5);
	displayBox(4);

	glLoadIdentity();
	glTranslatef(-.38,0,-.5);
	displayBox(5);



	glLoadIdentity();
	glTranslatef(.38,-.38,-.5);
	displayBox(6);

	glLoadIdentity();
	glTranslatef(0,-.38,-.5);
	displayBox(7);

	glLoadIdentity();
	glTranslatef(-.38,-.38,-.5);
	displayBox(8);



	glPopMatrix();
	glPopMatrix();
	glutSwapBuffers();
}


void displayBox(int a)
{
	char C = T.getBox(a);
	if(C != ' ')
	{
		if(C == 'X')
		{
			
			glColor3f(0, Xcolor+.1, 0);
		
			if(Xwinner)
				glColor3f(1,0,0);
			glPushMatrix();
			glRotatef(45,0,0,1);
			glScalef(.05,.3,.02);
			createCylinder(1,1,100,100);

			glPopMatrix();
			glRotatef(-45,0,0,1);
			glScalef(.05,.3,.02);
			createCylinder(1,1,100,100);

		}

		else if(C == 'O')
		{
			glColor3f(0, 0, Ocolor+3);
			if(Owinner)
				glColor3f(3,0,0);
			glutSolidTorus(.02,.09,100,100);
		}
	}

}

void reset()
{
	T.init(charChoiceP1, charChoiceP2, p1H, p2H, diffP1, diffP2);
	Xcolor = 0;
	Ocolor = 0;
	GameDone = false;
	Xwinner = false;
	Owinner = false;
	whoseTurn = whoStarts;
}


void mouse(int button, int state, int x, int y)
{
	int index;
	switch(button)
	{
		case GLUT_LEFT_BUTTON:
			if(state != GLUT_DOWN)
			{

				if(GameDone)
				{
					reset();
					glutPostRedisplay();
					break;
				}

				if(x < ImageW/3)
				{
					if(y < ImageH/3)
						index = 0;
					else if(y < ImageH*2/3)
						index = 3;
					else 
						index = 6;
				}
				else if(x < ImageW*2/3)
				{
					if(y < ImageH/3)
						index = 1;
					else if(y < ImageH*2/3)
						index = 4;
					else 
						index = 7;
				}
				else 
				{
					if(y < ImageH/3)
						index = 2;
					else if(y < ImageH*2/3)
						index = 5;
					else 
						index = 8;
				}


				if(whoseTurn%2 == 0)
				{	
					if(T.player1TakeATurn(index))
						whoseTurn++;
					else break;
				}


				if(!GameDone)
					T.computerMove('O', diff);
				
				whoseTurn++;
				glutPostRedisplay();
			}
			break;
		default: break;
	}
}


int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(ImageH, ImageW);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("Visual TicTacToe  V1.1  by JiT");
	init();
	glutDisplayFunc(display);
	glutMouseFunc(mouse);

	GLint difficulty = glutCreateMenu(MenuFunc);
		glutAddMenuEntry("Super Easy",1);
		glutAddMenuEntry("Easy",2);
		glutAddMenuEntry("Medium",3);
		glutAddMenuEntry("Hard",4);
		glutAddMenuEntry("Impossible",5);

	GLint firstMove = glutCreateMenu(MenuFunc);
		glutAddMenuEntry("Me",6);
		glutAddMenuEntry("Him",7);

	glutCreateMenu(MenuFunc);
		glutAddSubMenu("Difficulty" , difficulty);
		glutAddSubMenu("First Move" , firstMove);

	glutAttachMenu(GLUT_RIGHT_BUTTON);

	glutMainLoop();
	return 0;
}




void MenuFunc(GLint selectedOption)
{
	switch(selectedOption)
	{
	case 1:	
	case 2: 
	case 3:
	case 4: 
		diff = selectedOption;
		break;
	case 5: diff = 0;
		break;

	case 6:	whoStarts = 0; break;
	case 7:	whoStarts = 1; break;
	}
}