/*
  Sean Dobbs
  Period 4
  Missle trajectory simulation
*/

#include <iostream.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "glaux.h"
#include "GL/gl.h"
#include "GL/glu.h"
#include "GL/glut.h"

// Globals
struct Wall
{
	 int x, y, height;
};

static int dist, range, numwalls;
static Wall *walls;

// Functions
static void Init(void)
{
	glClearColor(0.0, 0.0, 0.0, 1.0);
	glShadeModel( GL_FLAT );
	glOrtho(0.0, 1000.0, 0, 90.0, -5.0, 5.0);
}

void DrawTraj()
{
	double t=0, tstep=0.01, a=32, vx, vy, x, y, closeness, wallt;
	int hit;

	glBegin(GL_POINTS);
	for(double v = 0; v<=1000; v+=.5)
	{
		 for(double theta = 0; theta <= 90; theta+=0.2)
		 {
			  x=0;
			  t=0;
			  hit=0;
			  vy=v*sin((theta * M_PI)/180.0);
			  vx=v*cos((theta * M_PI)/180.0);
			  do
			  {
				   t+=tstep;
				   y = (vy * t) - (0.5 * a * t * t);
				   x = x + (vx * tstep);
				   if(numwalls>0)
				   {
						for(int i=0; (i<numwalls)&&(!hit); i++)
						{
							 if((x<walls[i].x+5)&&(x>walls[i].x-5)&&(y>walls[i].y)&&(y<(walls[i].y+walls[i].height)))
							 {
								  vx = -(vx / 2.0);
								  hit = 1;
							 }
						}
				   }
			  }
			  while(y>0);
			  closeness = fabs(x-dist);
			  if( closeness < range)
			  {
				   glColor3f(0.0, 0.0, 1.0);
				   glVertex3f(v, theta, 0.0);
			  } else if( closeness < range*2)
			  {
				   glColor3f(0.0, 0.0, 0.8);
				   glVertex3f(v, theta, 0.0);
			  } else if( closeness < range*4)
			  {
				   glColor3f(0.0, 0.0, 0.7);
				   glVertex3f(v, theta, 0.0);
			  } else if( closeness < range*8)
			  {
				   glColor3f(0.0, 0.0, 0.6);
				   glVertex3f(v, theta, 0.0);
			  } else if( closeness < range*16)
			  {
				   glColor3f(0.0, 0.0, 0.5);
				   glVertex3f(v, theta, 0.0);
			  } 
		 }
	}
	glEnd();
}

static void display()
{
	glClear( GL_COLOR_BUFFER_BIT );
	cout<<"target distance: ";
	cin>>dist;
	cout<<"hit range: ";
	cin>>range;
	cout<<"number of walls: ";
	cin>>numwalls;
	if(numwalls > 0)
	{
		 walls = new Wall[numwalls];
		 for(int i=0; i<numwalls; i++)
		 {
			  cout<<"position (x y): ";
			  cin>>walls[i].x>>walls[i].y;
			  cout<<"height: ";
			  cin>>walls[i].height;
		 }
	}
	DrawTraj();
	glFlush();
	glutPostRedisplay();
}

static void Reshape( int width, int height )
{
	 glClear( GL_COLOR_BUFFER_BIT );
	 glViewport(0, 0, (GLint)width, (GLint)height);
	 glMatrixMode( GL_PROJECTION );
 	 glLoadIdentity();
	 glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
	glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
	glutInitWindowSize(600, 270);
	glutInitWindowPosition(50,250);
	glutCreateWindow(argv[0]);
	Init();
//  glutKeyboardFunc(keypress);
//	glutMouseFunc(mouseclick);
	glutDisplayFunc(display);
	glutReshapeFunc(Reshape);
	glutMainLoop();
	return 0;	
}
