#include <GL/glut.h>

char board[65];

char upmove=0;
// move is the global flag determining who's move it is
char move=1;

int selection=0;
int seltemp=0;

/* this is the depth (the steps of recursion)
 * the variable is set through the first param of the
 * command line.
 */

int i=0;

/* the init function initializes all of the tools
 * used to draw (color, the background color),
 * as well as setting the modes for the renderer
 */

void myinit(void);
void squares();
void display();
void main_menu(int value);
void submenu(int value);
/* if begin = 0; its not the begining
 */
void mclbk(int button, int state, int x, int y);
void render_checkers();
void draw_checker(int i);
void clear_board();
void kings();
void score();

int main(int argc, char ** argv) {
	int sub_menu=1;
	
	if(argc > 1) i=atoi(argv[1]);
	
	clear_board();
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(800, 800);
	glutInitWindowPosition(0,0);
	glutCreateWindow("Checka's");
	sub_menu = glutCreateMenu(submenu);
	glutAddMenuEntry("Show Current Score", 1);
	glutAddMenuEntry("Player 1 Resignation", 2);
	glutAddMenuEntry("Player 2 Resignation", 3);
	glutAddMenuEntry("Players Agree to a Draw", 4);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
	glutCreateMenu(main_menu);
	glutAddMenuEntry("Play a Demo Game", 1);
	glutAddMenuEntry("Play a New Game", 3);
	glutAddSubMenu("Status of Current Game", sub_menu);
	glutAddMenuEntry("Quit", 2);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
	glutMouseFunc(mclbk);
	myinit();
	glutMainLoop();
	
	/*
	while(sub_menu < 65)
	printf("%d", board[sub_menu]), sub_menu++;
	printf("\n");
	
	render_checkers();
	*/
	
	return 0;
}

void mclbk(int button, int state, int x, int y){
int row, col, i, temp;

	if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
		//exit();

		x+=100;
		col=(x/100);
		row=(y)/100;
		i=8*row + col;
		// if selection is 0, a selection has not been made
		// and if board[i]%2=move, the piece is correct.. else break
		if(selection==0) {
			if(board[i]==move || board[i]==move+2) {
				selection=i;
				seltemp=board[i];
				if(seltemp==0) selection=0, seltemp=0;
				board[selection]=5;
				display();
				}
		}
		// if aselection has been made
		else if(selection) {
			temp=i-selection;
			// if the movement is upwards and the piece is black or kinged
			// reset temp to abs of temp.. upmove set to 1
			if(temp < 0 && seltemp >= 2) { temp=-1 * temp; upmove=1; }
			// if the movement is downwards but is black, set temp to 0 to skip if statements
			else if(temp > 0 && seltemp ==2) temp=0;
			// if the move is legal..
			if(temp==7 || temp==9) {
				// if the position is unoccupied
				if(board[i]==0) {
					board[i]=seltemp;
					board[selection]=0;
					// reset global flags
					if(move==1)move=2;
					else if(move==2)move=1;
					selection=0;
					display();
					score();
				}
			}
			// If jumping a piece to the right.. 9
			else if(temp==18) {
				if(board[i]==0) {
				// if the jumped piece exists and is a dif color than yours..
					if((board[selection+9]!=0 && board[selection+9]!=move) || (upmove && board[selection-9]!=0 && board[selection-9]!=move)) {
						board[i]=seltemp;
						board[selection]=0;
					if(upmove) board[selection-9]=0;
					else board[selection+9]=0;
				// reset global flags
				if(move==1)move=2;
				else if(move==2)move=1;
				selection=0;
				score();
				display();
					}
				}
			}
			// if jumping to the left ... 7
			else if(temp==14) {
				if(board[i]==0) {
				// if the jumped piece exists and is a dif color than yours..
					if((board[selection+7]!=0 && board[selection+7]!=move) || (upmove && board[selection-7]!=0 && board[selection-7]!=move)) {
						board[i]=seltemp;
						board[selection]=0;
					if(upmove) board[selection-7]=0;
					else board[selection+7]=0;
				// reset global flags
				if(move==1)move=2;
				else if(move==2)move=1;
				selection=0;
				score();
				display();
					}
				}
			}
			else {
				board[selection]=seltemp;
				seltemp=0;
				selection=0;
				printf("Error: erroneous move");
			}
		}
	}
	upmove=0;
}


/* init function; I'm not sure what it does
 */
void myinit(void) {
	
	glClearColor(1.0, 1.0, 1.0, 0.0);
	glColor3f(0.0, 0.0, 0.0);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0.0, 800.0, 0.0, 800.0);
	glMatrixMode(GL_MODELVIEW);
	glutDisplayFunc(display);

}

/* squares; draws the checker board
 */
void squares() {
	GLfloat a, b, c, d, e, f;

	a=100.0;
	b=0.0;
	c=0.0;
	d=0.0;
	e=100.0;
	f=0.0;

	glColor3f(0.0, 0.0, 0.0);

	while(b <= 800) {
		while(a <= 800 && d <= 800) {
		glRectf(d, c, a, e);
		glRectf(c, d, e, a);
		d+=100;
		c+=100;
		a+=100;
		e+=100;
		}
	b+=200;
	d=b;
	a=100+b;
	c=0;
	e=100;
	}
}

/* display function: it draws the squares and flushes
 */

void display () {
	glClear(GL_COLOR_BUFFER_BIT);
	
	squares();
	// marks any kings as kings; this cannot be undone
	kings();
	render_checkers();
	
	glFlush();
}

void score() {

	int i, black=0, white=0, bking=0, wking=0, sel=0;
	printf(" *** Score ***\n");
	for(i=1; i<64; i++) {
		if(board[i]==1) white++;
		else if(board[i]==2) black++;
		else if(board[i]==3) white++, wking++;
		else if(board[i]==4) black++, bking++;
		else if(board[i]==5) sel=1;
		}
	if(white==0 || black == 0) {
	if(white==0 && !sel) printf("Black wins the game with %d pieces left.\n", black), clear_board();
	if(black==0 && !sel) printf("White wins the game with %d pieces left.\n", white), clear_board();
	}
	else {
	if(wking > 0 || bking > 0) {
		if(wking && bking)printf("White has %d pieces; %d of them kings.\nBlack has %d pieces; %d of them kings.\n", white, wking, black, bking);
		if(wking && !bking)printf("White has %d pieces; %d of them kings.\nBlack has %d pieces.\n", white, wking, black);
		if(!wking && bking)printf("White has %d pieces.\nBlack has %d pieces; %d of them kings.\n", white, black, bking);
		}
	else{
		printf("White has %d pieces.\nBlack has %d pieces.\n", white, black);
	}
	}

}




/*given position i, this function draws the correct checker in
 the i'th square
 */
void draw_checker(int i) {

	int row=0, col=0;
	GLfloat a, b, c, d;

/* first, find the row and col that the piece is in */
col=(i%8) * 100;

if(col==0) { col=800; row=(i/8) * 100; }
else row=(i/8+1) * 100;

/* if row = 6, col = 5; position is retarded */
/* change row to equal row from bottom */
row=900-row;

a=col-75;
b=row-75;
c=col-25;
d=row-25;

	// white piece
	if(board[i]==1) {
		glColor3f(1.0, 1.0, 1.0);
		glRectf(a, b, c, d);
	}
	// black piece
	if(board[i]==2) {
		glColor3f(0.5, 0.5, 0.5);
		glRectf(a, b, c, d);
	}
	// white king
	if(board[i]==3) {
		glColor3f(1.0, 1.0, 1.0);
		glRectf(a, b, c, d);
		glColor3f(0.0, 0.0, 0.0);
		glRectf(a+10, b+10, c-10, d-10);
	}
	// black king
	if(board[i]==4) {
		glColor3f(0.5, 0.5, 0.5);
		glRectf(a, b, c, d);
		glColor3f(1.0, 1.0, 1.0);
		glRectf(a+10, b+10, c-10, d-10);
	}
	// selection
	if(board[i]==5) {
		glColor3f(1.0, 0.0, 0.0);
		glRectf(a, b, c, d);
	}
}


/*this function resets the board to
 its origional configuration
 */
void clear_board() {
	int i=1, row=1, count=1;
	
	while(i<65) { board[i]=0; i++;}
	i=1;

	while(row <=8) {
		/* if we are on an odd row */

		if(row%2) {
		//	printf("1st loop\n");
			if(i%2==0 && row<=3) board[count]=1;
			if(i%2==0 && row>=6) board[count]=2;
		}
		/* if we are on an even row */
		if(row%2==0) {
		//	printf("2nd loop\n");
			if(i%2 && row<=3) board[count]=1;
			if(i%2 && row>=6) board[count]=2;
		}
		i++;
		/* if we are in the 8th position */
		if(i%9==0) {
		//	printf("row: %d\n", row);
			row++;
			i=1;
		}
		count++;
	}
	selection=0;
	move=1;

}

/* recurse through "board" and
 * render all of the checkers
 */

void render_checkers() {
int i=1;
	while(i < 65) {
		if(board[i] > 0) draw_checker(i);
		i++;
	}
}

void kings() {
	int i=1;
	while(i <=8){
		if(board[i]==2) board[i]=4;
		i++;
	}
	i=57;
	while(i<=64) {
		if(board[i]==1) board[i]=3;
		i++;
	}
}
/*
glutAddMenuEntry("Play a Demo Game", 1);
glutAddMenuEntry("Play a New Game", 3);
glutAddSubMenu("Status of Current Game", sub_menu);
glutAddMenuEntry("Quit", 2);
*/

void main_menu(int value) {
	if(value == 1) clear_board();
	if(value == 2) exit(0);
	if(value == 3) clear_board();
}

/*
glutAddMenuEntry("Show Current Score", 1);
glutAddMenuEntry("Player 1 Resignation", 2);
glutAddMenuEntry("Player 2 Resignation", 3);
glutAddMenuEntry("Players Agree to a Draw", 4);
*/

void submenu(int value) {
	if(value==1) score();
	if(value==2) {
		printf("Player 2 wins by resignation!\n");
		clear_board();
		}
	if(value==3) {
		printf("Player 1 wins by resignation!\n");
		clear_board();
		}
	if(value == 4){
		printf("Players agree to a draw!\n");
		clear_board();
		}
}