#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
//#include "structs.h"
//#include "destination.h"
//#include "drawl.h"
//#include "attack.h"

#define RESTART 2
#define PAUSED 3
#define EXIT 4

struct timespec ts;

double num1 = 0;
double num2 = 1;
double num3 = -10;
double num4 = 5;
double num5 = 15;
double num6 = 15;
int paused = 0;
int score1;
int score2;

struct soldier_struct
{
        double X; //current locations
        double Y;
        double destX; //destination locations
        double destY;
        int team; //0=team1 1=team2
        int type; //0=archer 1=spearman 2=swordman
        int alive; //0=dead 1=alive
	int closest;
};


struct soldier_struct soldier[19];

#include "init_soldiers.h"
#include "destination.h"
#include "occupied.h"
#include "move.h"
#include "scores.h"
#include "attack.h"
#include "drawl.h"
#include "grid.h"
#include "respawn.h"

void OpenGLInit(void);
static void Animate(void );
static void ResizeWindow(int w, int h);
int glutCreateMenu(void (*func)(int value));
void glutAddMenuEntry(char *name, int value);
void glutAttachMenu(int button);
void processMenuEvents(int option);
void glutDestroyWindow(int windowID);
void keyboard (unsigned char key, int x, int y);
bool ignoreRepeats = false;



void createGLUTMenus() {
                        
        int menu;
                        
        // create the menu and   
        // tell glut that "processMenuEvents" will
        // handle the events
        menu = glutCreateMenu(processMenuEvents);
                        
        //add entries to our menu
        //glutAddMenuEntry("Settings",SETTINGS);
        glutAddMenuEntry("Restart",RESTART);
        glutAddMenuEntry("Pause",PAUSED);
        glutAddMenuEntry("Exit",EXIT);
                        
        // attach the menu to the right button
        glutAttachMenu(GLUT_RIGHT_BUTTON);
}





void processMenuEvents(int option) {
                        
        switch (option) {

		case RESTART :
		init_soldiers();
		score1=0;
		score2=0;
		break;
		case PAUSED :
		
		if (paused == 1) {
			paused = 0;
		}else{
			paused = 1;
		}

		break;
		case EXIT :
		
		exit (0);
		break;
	}

}


void special (int key, int x, int y)
{
                        
  switch (key) {
    case GLUT_KEY_UP:
      break;
                                
    case GLUT_KEY_DOWN:
      break;
                         
    case GLUT_KEY_RIGHT:
                num1++;
                printf("increment num1: %lf\n", num1);

	printf("right key\n");
      break;
                        
    case GLUT_KEY_LEFT: 

                num1--;
                printf("decrement num1: %lf\n", num1);

	printf("left key\n");
      break;                    

 }
                         
}



void keyboard(unsigned char key, int x, int y)
{
        printf("in here\n");

        if (key==27)
        {
                        //27 is the ascii code for the ESC key
                exit (0); //end the program
        } else if (key==49 ){
		num1++;
                printf("increment num1: %lf\n", num1);
        } else if (key==50 ){
                num1--;
                printf("decrement num1: %lf\n", num1);
        } else if (key==51 ){
                num2++;
                printf("increment num2: %lf\n", num2);
        } else if (key==52 ){
                num2--;
                printf("decrement num2: %lf\n", num2);
        } else if (key==53 ){
                num3++;
                printf("increment num3: %lf\n", num3);
        } else if (key==54 ){
                num3--;
                printf("decrement num3: %lf\n", num3);
        } else if (key==55 ){
                num4++;
                printf("increment num4: %lf\n", num4);
        } else if (key==56 ){
                num4--;
                printf("decrement num4: %lf\n", num4);
        } else if (key==57 ){
                num5++;
                printf("increment num5: %lf\n", num5);
        } else if (key==58 ){
                num5--;
                printf("decrement num5: %lf\n", num5);
        } else if (key==59 ){
                num6++;
                printf("increment num6: %lf\n", num6);
        } else if (key==60 ){
                num6--;
                printf("decrement num6: %lf\n", num6);
	}
}   



static void Animate(void)
{
	int count1;
	int ocupied_int;
	int count2;
	double count3=-3.0;
	double tmpX;
	double tmpY;
	//char scorestring[(sizeof(int)*2)+50];
	
	//init_soldiers();

//	while(1==1) {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		grid();


               //glFlush();
               //glutSwapBuffers();
               //glutPostRedisplay();

		sleep(1);

		//drawl(count1);
int stillalive1 = 0;
int stillalive2 = 0;
for(count2=0; count2<18; count2++) {
	if (soldier[count2].alive != 0 && soldier[count2].team == 0) {
		stillalive1++;
	}
        if (soldier[count2].alive != 0 && soldier[count2].team == 1) {
                stillalive2++;
        }

}
//printf("%d soldiers on team1 alive\n", stillalive1);
//printf("%d soldiers on team2 alive\n", stillalive2);


		for(count1 = 0; count1 < 18 && paused != 1; count1++) {
			if(soldier[count1].alive != 0) {

				//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
				//grid();
				//drawl(count1);
               			//glFlush();
               			//glutSwapBuffers();
               			//glutPostRedisplay();


				//sleep(1);
				destination(count1);

				//move
				move(count1);
				//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
				//grid();
				//drawl(count1);
                                //glFlush();
                                //glutSwapBuffers();
                                //glutPostRedisplay();


				//drawl(count1);
				
				//sleep(1);
				//attack if bordering
				//attack(count1);
				
//				sleep(1);

				//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
				//grid();
		
				scores();
				respawn();
				drawl(count1);
		
                                glFlush();
                                glutSwapBuffers();
                                glutPostRedisplay();
				
				attack(count1);
				//sleep(1);

/*
				//ocupied = ocupied(count1);
				if(soldier[count1].X != soldier[count1].destX) {
					tmpX=soldier[count1].X;
					tmpY=soldier[count1].Y;
					if(soldier[count1].destX > soldier[count1].X) {
						if(soldier[count1].destX <= (soldier[count1].X + 1)) {
							//if(ocupied != 1){
							soldier[count1].X = soldier[count1].destX;
							//}
						}else{
							//if(ocupied != 1){
							soldier[count1].X++;
							//}
						}
					}else if(soldier[count1].destX < soldier[count1].X) {
						if(soldier[count1].destX >= (soldier[count1].X - 1)) {

							soldier[count1].X = soldier[count1].destX;

						}else{
							soldier[count1].X--;
						}
					}
				}

				if(soldier[count1].Y != soldier[count1].destY) {

					if(soldier[count1].destY > soldier[count1].Y) {
                                        	if(soldier[count1].destY < (soldier[count1].Y +1)) {
                                                	soldier[count1].Y = soldier[count1].destY;
                                        	}else{
							soldier[count1].Y++;
						} 	
					}else if(soldier[count1].destY < soldier[count1].Y) {
                                        	if(soldier[count1].destY > (soldier[count1].Y -1)) {
                                                	soldier[count1].Y = soldier[count1].destY;
                                        	}else{  
							soldier[count1].Y--;
						}
					}
				}

				ocupied_int = ocupied(count1);
				
				if(ocupied_int == 1) {
					//soldier[count1].X = tmpX; 
					soldier[count1].Y = tmpY;
				}
			
				//drawl(count1);


				//if(soldier[count1].X == soldier[count1].destX && soldier[count1].Y == soldier[count1].destY ) {
				
				attack(count1);
				
				//}
		                glFlush();
		                glutSwapBuffers();
                		glutPostRedisplay();
                		//sleep(1);


*/
			}
		}

                                //drawl(count1);
                                //attack(count1);
//                                glFlush();
//                                glutSwapBuffers();
//                                glutPostRedisplay();
                                //sleep(1);




//	sleep(1);
//	}


}




void OpenGLInit(void)
{
    glShadeModel( GL_FLAT );
    glClearColor( 0.0, 0.0, 0.0, 0.0 );
    glClearDepth( 1.0 );
    glEnable( GL_DEPTH_TEST );
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}


static void ResizeWindow(int w, int h)
{   
    float aspectRatio;
        h = (h == 0) ? 1 : h;
        w = (w == 0) ? 1 : w;
        glViewport( 0, 0, w, h );       // View port uses whole window
        aspectRatio = (float)w/(float)h;

        // Set up the projection view matrix (not very well!)
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
//    gluPerspective( 200.0, aspectRatio, 1.0, 100.0 );

gluPerspective(45.0f,(GLfloat)w/(GLfloat)h,0.1f,1000.0f);
    
        // Select the Modelview matrix
    glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
}


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

        glutInit(&argc,argv);
	init_soldiers();
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );

        // Create and position the graphics window
    glutInitWindowPosition( 0, 0 );
    glutInitWindowSize( 1000, 1000 );
    glutCreateWindow( "fightgl test" );
    
        // Initialize OpenGL.
    OpenGLInit();
    glutReshapeFunc( ResizeWindow );

        // Callback for graphics image redrawing
    glutDisplayFunc( Animate );
        

glutIgnoreKeyRepeat(ignoreRepeats);
glutSpecialFunc(special);
glutKeyboardFunc (keyboard);

	createGLUTMenus();

        // Start the main loop.  glutMainLoop never returns.
        glutMainLoop(  );


   exit(1);
}

