//================================================================

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

#include "RobotsBattleGr.h"





static t_start_program startup_routine;

void drawString (char *s) {
	unsigned int i;
	for (i = 0; i < strlen(s); i++)
		glutBitmapCharacter (GLUT_BITMAP_HELVETICA_12, s[i]);
}




/*
* Build display list for the schematic robot (a triangle)
*
* NOTE: Assume the robot is triangle of 1 meter each edge.
*/
void createRobotsDL(void) {
	
	glNewList(ROBOTS_DL, GL_COMPILE);
	glBegin(GL_POLYGON);
	glVertex2i(-8, -8);
	glVertex2i(8, -8);
	glVertex2i(0, 16);
	glEnd();
	glEndList();
}



/*
* Build display list for the laser beam(a triangle)
*/
void createLaserBeamDL(void) {
	glNewList(LASER_BEAM_DL, GL_COMPILE);
	glBegin(GL_LINES);
	glVertex2i(0,0);
	glVertex2i(0,LASER_BEAM_LENGTH);
	glEnd();
	glEndList();
}

void glAppInit(){
	createRobotsDL();
	createLaserBeamDL();
}


/*******************************************************************************\
*
*      G L U T     C A L L B A C K    F U N C T I O N S 
*
\*******************************************************************************/
/* Function for Reshaping the Main Window:
*   The system of coordinated is 2D, ranging from XMIN to XMAX in x,
*   and from -0.75 to 0.75 in y. The y coordinate will be associated with
*   the real part of the wavefunction, and since |Psi(x)| <= 1.0  then
*   assuming [-0.75 to 0.75] range is reasonable
*/
void reshape( int w, int h ){
	
	float ar;
	
	/* correct the viewport */
	glViewport(0,0,w,h);
	
	/* define new world coordinates according to new asspect ratio */
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();	/* clear world coords */
	ar = ((float) w)/h;
	if(ar > 1.0)
		glOrtho(0.0,RING_WIDTH*ar,0.0,RING_HEIGHT,10.0,-10.0);
	else
		glOrtho(0.0,RING_WIDTH,0.0,RING_HEIGHT/ar, 100.0, -100.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();	/* clear modeling transformations */
}


void Animate( int value ){
	startup_routine();//Main Game Loop Function For Update Scene
	
	/*OpenGL Related*/
	glutPostRedisplay();
	glutTimerFunc(CPU_TICK_PER_SECOND,Animate,0);  //Each 100ms we get a call.
}


void renderRobots(Robot* robots){
    int i;
    for (i = 0; i < NUMBER_OF_ROBOTS; i++) {
        glColor3ubv(ROBOTS_COLORS[i]);
        glPushMatrix();
        glTranslated(robots[i].x, robots[i].y, 0);
        glRotated(-robots[i].direction, 0, 0, 1);
        glCallList(ROBOTS_DL);
        glPopMatrix(); 
    }
	
    
}

void renderLaserBeams(Robot* robots){
    int i;
    for (i = 0; i < 2; i++) {
		if(robots[i].laserBeam.isVisible){
			glColor3ubv(ROBOTS_COLORS[i]);
			glPushMatrix();
			glTranslated(robots[i].laserBeam.x, robots[i].laserBeam.y, 0);
			glRotated(-robots[i].laserBeam.direction, 0, 0, 1);
			glCallList(LASER_BEAM_DL);
			glPopMatrix(); 
		}
    }
	
	
}

void renderRingHUD(Robot* robots){
	
	char buffer[50];
	glColor3ubv(ROBOTS_COLORS[0]);
	glPushMatrix();
	glRasterPos2f(10,5);
	sprintf(buffer,"%s Life: %d",robots[0].name, robots[0].hitPoints);
	drawString(buffer);
	
	glColor3ubv(ROBOTS_COLORS[1]);
	glRasterPos2f(RING_WIDTH-50-strlen(buffer),5);
	sprintf(buffer,"%s Life: %d",robots[1].name, robots[1].hitPoints);
	drawString(buffer);
	glPopMatrix(); 
	
}


void Render(RenderSceneState state){
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the screen
	glMatrixMode (GL_MODELVIEW);
    glLoadIdentity ();
	renderRobots(state.robots);
	renderLaserBeams(state.robots);
	renderRingHUD(state.robots);
	glFlush();
	glutSwapBuffers();
	
}


void empty_cb(){
}



void robotsBattleGrInit(t_start_program start){
	
	int argc=1;
    char *argv[]={""};
	startup_routine = start;
	
	glutInit(&argc, argv);
	glutInitWindowSize( 500, 500 );  // To see the graphics magnified
	glutInitWindowPosition( 0, 0 );
	glutCreateWindow("Robots Battle Field");
	
	//glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	
	
	glViewport(0, 0, RING_WIDTH, RING_HEIGHT);
	glShadeModel(GL_FLAT);
	glOrtho( 0.0, RING_WIDTH, 0.0, RING_HEIGHT, 0.0, 0.0 );
	
	glClearColor(0.0, 0.0, 0.0, 0.0);
    glAppInit();
	glutTimerFunc(CPU_TICK_PER_SECOND, Animate, 0);
	glutDisplayFunc(empty_cb);
	glutReshapeFunc(reshape);
	
	glutMainLoop();
}




