#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

void OpenGLInit(void);

static void Animate(void );
static void ResizeWindow(int w, int h);
void attack(int closest_enemy_type, int closest_enemy, int j);

struct info
{
	double X;
	double Y;
	int alive;
	int team;
	//int closest_enemy;
};

struct info arch[9];
struct info spear[7];
struct info sword[5];

int closest_enemy_type;
int closest_enemy;


/*
struct info2
{
        double X;
        double Y;
        int alive;
	int team;
}
struct info2 spear[7];

struct info3
{
        double X; 
        double Y; 
        int alive;
	int team; 

}
struct info3 sword[5];
*/




//[solder #] [x coord / y coord] [dead/alive]
/*
double arch[9][2][2];
double spear[7][2][2];
double sword[5][2][2];
*/
double movement1;
double movement2;
double distancea;
//double distanceb = 100.00;


void archer(double x, double y)
{
	glLoadIdentity();
	//glTranslatef ( coord1, coord2, coord3 );
		//   over  up  distance-view	
	glTranslatef ( x, y, -30.0 );
	//glRotatef( 0.0, 0.0, 0.0, -100.0 );
	glColor3f( 1.0, 1.0, 0.0 );
	glutSolidSphere( .5, 15, 15 );
}

void spearman(double x, double y)
{
        glLoadIdentity();
        //glTranslatef ( coord1, coord2, coord3 );
                //   over  up  distance-view
        glTranslatef ( x, y, -30.0 );
        //glRotatef( 0.0, 0.0, 0.0, 0.0 );
        glColor3f( 1.0, 0.0, 0.0 );
        glutSolidSphere( .5, 15, 15 );
}

void swordman(double x, double y)
{
        glLoadIdentity();
        //glTranslatef ( coord1, coord2, coord3 );
                //   over  up  distance-view
        glTranslatef ( x, y, -30.0 );
        //glRotatef( 0.0, 0.0, 0.0, 0.0 );
        glColor3f( 0.0, 0.0, 1.0 );
        glutSolidSphere( .5, 15, 15 );
}


void closest(double Xone, double Yone, int team)
{
	//distance between two points if known coordinates
	//double distancea;
	double distanceb = 100.00;

	double varx, vary;
	double Xtwo, Ytwo;
	//double movement;
	
	int i, w;
	
	if(team==2){
		w=4;
		i=0;
	}else if(team==1) {
		w=8;
		i=4;
	}

	while(i<w) {
		if(arch[i].alive < 1) {
			Xtwo = arch[i].X;
			Ytwo = arch[i].Y;
			distancea = sqrt( ((Xone - Xtwo)*(Xone - Xtwo)) + ((Yone - Ytwo)*(Yone - Ytwo)) );
			if( (distancea<distanceb) && (Xone != Xtwo) && (Yone != Ytwo)) {
				varx = Xtwo;
				vary = Ytwo;
				distanceb = distancea;
				//arch[i].closest_enemy=i;
				closest_enemy_type=1;
				closest_enemy=i;
			}
		}
		i++;
	}



        if(team==2){
                w=3;
                i=0;
        }else if(team==1) {
                w=6;
                i=3;
        }
        
        while(i<w) {
        //for(i=0; i<6; i++) {
		if(spear[i].alive < 1) {
                	Xtwo = spear[i].X;
                	Ytwo = spear[i].Y;
                	distancea = sqrt( ((Xone - Xtwo)*(Xone - Xtwo)) + ((Yone - Ytwo)*(Yone - Ytwo)) );
                	if((distancea<distanceb) && (Xone != Xtwo) && (Yone != Ytwo)) {
                        	varx = Xtwo;
                        	vary = Ytwo;
				distanceb = distancea;
				//spear[i].closest_enemy=i;
                                closest_enemy_type=2;
                                closest_enemy=i;  

                	}
		}
		i++;
        }
                
        if(team==2){
                w=2;
                i=0;
        }else if(team==1) {
                w=4;
                i=2;
        }

        while(i<w) {
        //for(i=0; i<4; i++) {
		if(sword[i].alive < 1) {
                	Xtwo = sword[i].X;
                	Ytwo = sword[i].Y;
                	distancea = sqrt( ((Xone - Xtwo)*(Xone - Xtwo)) + ((Yone - Ytwo)*(Yone - Ytwo)) );
                	if((distancea<distanceb) && (Xone != Xtwo) && (Yone != Ytwo) ) {
                        	varx = Xtwo;
                        	vary = Ytwo;
				distanceb = distancea;
                                closest_enemy_type=3;
                                closest_enemy=i;  

                	}
		}
		i++;
        }



	movement1 = varx;
	movement2 = vary;
	distancea = distanceb;

//printf("closest(x,y): %lf, %lf\n", varx, vary);


//return movement

//return;
}


void attack(int closest_enemy_type, int closest_enemy, int j)
{
	double randnum1;
	double randnum2;

        /* initialize random seed: */
        srand ( time(NULL) );
	randnum1 = rand() %  15;


	if(closest_enemy_type == 1) {
		//randnum2= rand() %  15;
		randnum2= 0;
		if(randnum1>=randnum2) {
			arch[closest_enemy].alive=1;
		}

	}else if(closest_enemy_type == 2) {
		randnum2= rand() % 25;
                if(randnum1>=randnum2) {
                        spear[closest_enemy].alive=1;
                }

		
	}else if(closest_enemy_type == 3) {
		randnum2= rand() % 50;
                if(randnum1>=randnum2) {
                        sword[closest_enemy].alive=1;
                }

		
	}

/*	if(randnum2>randnum1) {

	        arch[j].alive=1;
        }
*/


}


static void Animate(void)
{
	int i, X, Y, team;
	double Xone, Yone;
	X=5;
	Y=-3;
	for(i=0; i<8; i++) {
		if(i==4) {
			X=-5;
			Y=-3;
		}
		arch[i].alive=0;
		arch[i].X=X;
		arch[i].Y=Y;
		Y+=2;
		//printf("archx: %lf archy: %lf\n", arch[i][0], arch[i][1]);
	}

        X=10;
        Y=-2;
        for(i=0; i<6; i++) {
                if(i==3) {
                        X=-10; 
                        Y=-2;
                }
		spear[i].alive=0;
                spear[i].X=X;
                spear[i].Y=Y;
                Y+=2;
        }

        X=15;
        Y=-1;
        for(i=0; i<4; i++) {
                if(i==2) {
                        X=-15; 
                        Y=-1;
                }
        	sword[i].alive=0;
                sword[i].X=X;
                sword[i].Y=Y;
                Y+=2;
        }


	int j, k, l;
team = 1;

	while (1==1) {

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		//determine which is closest and head 1 toward it

                for(j=0; j<4; j++){
			//team = 1;
			if(arch[j].alive < 1) {
				Xone=arch[j].X;
				Yone=arch[j].Y;
				closest(Xone, Yone, team);
			
				if(distancea>11.5){			
					//printf("distancea: %lf\n", distancea);
					if(movement1<arch[j].X ) {
						arch[j].X=arch[j].X-.25;
					}else if(movement1>arch[j].X) {
						arch[j].X=arch[j].X+.25;
					}


                        		if(movement2<arch[j].Y) {
                                		arch[j].Y=arch[j].Y-.25;
                        		}else if(movement2>arch[j].Y) {
                                		arch[j].Y=arch[j].Y+.25;
                        		}

					//If soldier comes within range of enemy initiate attack
				
					/*	if(distancea<=11.5) {
						//if(closest_enemy_type == 1){
							//attack(closest_enemy_type, closest_enemy, j);
						//attack();

						}*/




				} 
				if(distancea<=11.5) {
                                        //if(closest_enemy_type == 1){
                                                attack(closest_enemy_type, closest_enemy, j);
                                        //attack();
                                        
                                }



				//don't plot if soldier is dead
				//			if(arch[j].alive != 1) {
                        	//archer(arch[j].X, arch[j].Y);

			}

                }


		
		for(j=0; j<4; j++){
			//printf("alive: %lf\n", arch[j].alive);

			if(arch[j].alive < 1) {
				archer(arch[j].X, arch[j].Y);
			}
		}

                for(k=0; k<6; k++){
			if(spear[j].alive < 1) {
                        	spearman(spear[k].X, spear[k].Y);
			}
                }

                for(l=0; l<4; l++){
			if(sword[j].alive < 1) {
                        	swordman(sword[l].X, sword[l].Y);
			}
                }



		//glPushMatrix(); glPopMatrix();
		glFlush();
		glutSwapBuffers();
		glutPostRedisplay();
		sleep(1);

	}
}

void OpenGLInit(void)
{
    glShadeModel( GL_FLAT );
    glClearColor( 0.0, 0.0, 0.0, 0.0 );
    glClearDepth( 1.0 );
    glEnable( GL_DEPTH_TEST );
}


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( 60.0, aspectRatio, 1.0, 30.0 );
    
        // Select the Modelview matrix
    glMatrixMode( GL_MODELVIEW );
}


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

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

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

        // Callback for graphics image redrawing
    glutDisplayFunc( Animate );
        
        // Start the main loop.  glutMainLoop never returns.
        glutMainLoop(  );

   exit(1);
}

