//Trail Luo Li
//3d spheres and 3texture

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

//Universal Constants
  const MAX=100;
  static double
     red=1.0, green=1.0, blue=1.0;
  double
   xx=400,yy=200,zz=650;
 float t,tstep,a;
 float v,vx,vy,theta,dist,range;
 float forcex,forcey, fstren;
//


static void Init()
{
 GLfloat mat_specular[]= {1.0, 1.0, 1.0, 1.0 };
 GLfloat mat_shininess[]= {90.0}; 
 GLfloat light_position[]= { 1.0, 5.0, 1.0, 0.0 };

 glClearColor(0.3, 0.3, 0.3, 0.0);
 glShadeModel(GL_SMOOTH);
 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
 glColorMaterial(GL_FRONT,GL_DIFFUSE);
 
 glEnable(GL_COLOR_MATERIAL);
 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);
 glEnable(GL_DEPTH_TEST);
}

static void Reshape(int width, int height)
{
 glViewport(0,0,GLint(width),GLint(height));
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 gluPerspective(60.0, (GLfloat)width/(GLfloat)height, 1.0, 1000.0);
 gluLookAt(xx, yy, zz,  xx, yy, -1.0, 0.0, 1.0, 0.0);

 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
}

void forcealt1(float x, float y)
{
  forcex=700;
  forcey=300;
  fstren=100;

 	  glPushMatrix();
 	  glTranslatef(forcex, forcey, 0.0);
 	  glColor3f(0.2, 0.2, 0.9);
 	  glutSolidSphere(10, 20, 20);
	  glPopMatrix();
 	  
	    
  float xdif,ydif,radius;
  xdif=forcex-x;
  ydif=forcey-y;
  radius=(sqrt( (xdif*xdif) + (ydif*ydif) ) );
  float  tempf;
  tempf= (fstren/radius);
  //sin(arctan (x/y) ) = sin (x/radius)
  float  tsin= (fabs) (sin(ydif/radius));
  float  tcos= (fabs) (cos(xdif/radius));
	if (radius<(fstren*2))
	 {
  	  glBegin(GL_LINES);
// 	  glColor3f((ydif/radius), (xdif/radius), 1.0);
// 	  glColor3f(1.0, (xdif/radius), 0.2);
	 
 	  glVertex3f(x,y,0);
 	  glVertex3f(forcex,forcey,0);
	  glEnd();
 	 }

  if ((xdif>0) && (ydif>0)) { vx+= tempf*(tcos); vy+= tempf*(tsin);}
  if ((xdif<0) && (ydif>0)) { vx+= (-1)*tempf*(tcos); vy+= tempf*(tsin);}
  if ((xdif>0) && (ydif<0)) { vx+= tempf*(tcos); vy+= (-1)*tempf*(tsin);}
  if ((xdif<0) && (ydif<0)) { vx+= (-1)*tempf*(tcos); vy+= (-1)*tempf*(tsin);}
}

void forcealt3(float x, float y)
{
  forcex=20;
  forcey=550;
  fstren=40;

 	  glPushMatrix();
 	  glTranslatef(forcex, forcey, 0.0);
 	  glColor3f(0.2, 0.2, 0.9);
 	  glutSolidSphere(10, 20, 20);
	  glPopMatrix();
 	  
	    
  float xdif,ydif,radius;
  xdif=forcex-x;
  ydif=forcey-y;
  radius=(sqrt( (xdif*xdif) + (ydif*ydif) ) );
  float  tempf;
  tempf= (fstren/radius);
  //sin(arctan (x/y) ) = sin (x/radius)
  float  tsin= (fabs) (sin(ydif/radius));
  float  tcos= (fabs) (cos(xdif/radius));
	if (radius<(fstren*2))
	 {
  	  glBegin(GL_LINES);
// 	  glColor3f((ydif/radius), (xdif/radius), 1.0);
// 	  glColor3f(1.0, (xdif/radius), 0.2);
	 
 	  glVertex3f(x,y,0);
 	  glVertex3f(forcex,forcey,0);
	  glEnd();
 	 }

  if ((xdif>0) && (ydif>0)) { vx+= tempf*(tcos); vy+= tempf*(tsin);}
  if ((xdif<0) && (ydif>0)) { vx+= (-1)*tempf*(tcos); vy+= tempf*(tsin);}
  if ((xdif>0) && (ydif<0)) { vx+= tempf*(tcos); vy+= (-1)*tempf*(tsin);}
  if ((xdif<0) && (ydif<0)) { vx+= (-1)*tempf*(tcos); vy+= (-1)*tempf*(tsin);}
}

void forcealt2(float x, float y)
{
  forcex=300;
  forcey=10;
  fstren=-150;

 	  glPushMatrix();
 	  glTranslatef(forcex, forcey, 0.0);
 	  glColor3f(0.2, 0.2, 0.9);
 	  glutSolidSphere(10, 20, 20);
	  glPopMatrix();
 	  
	    
  float xdif,ydif,radius;
  xdif=forcex-x;
  ydif=forcey-y;
  radius=(sqrt( (xdif*xdif) + (ydif*ydif) ) );
  float  tempf;
  tempf= (fstren/radius);
  //sin(arctan (x/y) ) = sin (x/radius)
  float  tsin= (fabs) (sin(ydif/radius));
  float  tcos= (fabs) (cos(xdif/radius));
	if (radius<((fabs)(fstren*2)))
	 {
  	  glBegin(GL_LINES);
// 	  glColor3f((ydif/radius), (xdif/radius), 1.0);
// 	  glColor3f(1.0, (xdif/radius), 0.2);
	 
 	  glVertex3f(x,y,0);
 	  glVertex3f(forcex,forcey,0);
	  glEnd();
 	 }

  if ((xdif>0) && (ydif>0)) { vx+= tempf*(tcos); vy+= tempf*(tsin);}
  if ((xdif<0) && (ydif>0)) { vx+= (-1)*tempf*(tcos); vy+= tempf*(tsin);}
  if ((xdif>0) && (ydif<0)) { vx+= tempf*(tcos); vy+= (-1)*tempf*(tsin);}
  if ((xdif<0) && (ydif<0)) { vx+= (-1)*tempf*(tcos); vy+= (-1)*tempf*(tsin);}
}

static void display(void)
{
 t=0; tstep=.1; a=32; 
 theta=60; 
 dist=600; 
 range=20;

 theta= ( (theta/180)*(M_PI) );
 vx=(fabs)(v*cos(theta));
 vy=(fabs)(v*sin(theta));
 cout<<" vx-"<<vx<<" vy-"<<vy<<" time-"<<t<<" angel-"<<theta<<" step-"<<tstep<<" accel-"<<a<<endl;

 char temp1;
 float x=0;
 float y=0;
 float temp;
  	do
 	 {

 	  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	  //The Target
 	  glPushMatrix();
 	  glTranslatef(dist, 0, 0.0);
 	  glColor3f(0.1, 0.8, 0.2);
          glutWireTorus(10, .2, 10, 50);
	  glPopMatrix();

	  t+=tstep;
	  x=vx*t;
	  y=vy*t-(.5*a*(t*t));

  	  forcealt1(x,y);
  	  forcealt2(x,y);
	  forcealt3(x,y);
 	  glPushMatrix();
 	  glTranslatef(x, y, 0.0);
 	  glColor3f(0.8, 0.2, 0.3);
 	  glutSolidSphere(20, 20, 20);
	  glPopMatrix();
          
	  glFlush();
          glutSwapBuffers();
	  glLoadIdentity();
   	  glutPostRedisplay();
          
	 }
	while (y>0);

	 temp= x-dist;
	 temp= (fabs)(temp);
	 if (temp<range)
		 {
	         cout<<"HIT"<<endl;
		 } 
		  else 
		 {
	          cout<<"Miss"<<endl;
		 } 
}

void predisplay(void) 
{
//  theta=60; 
//  dist=600; 
//  range=20;
 float temp,temp2,intval;
 cout<<"Enter initial-";
 cin>>temp;
 cout<<"Enter final-";
 cin>>temp2;
 cout<<"Enter interval-";
 cin>>intval;
 for (v=temp; v<temp2; v+=intval) { cout<<"v-"<<v<<endl; display();}

}
void main(int argc, char** argv)
{
/* cout<<"Enter Velocity-";
 cin>>v;
 cout<<"Enter Angle-";
 cin>>theta;
 cout<<"Enter Distance to Targe-";
 cin>>dist;
 cout<<"Enter Range-";
 cin>>range; 
*/
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
 glEnable(GL_DEPTH_TEST);

 glutInitWindowSize(550, 300);
 glutInitWindowPosition(100,100);
 if (glutCreateWindow("Projectile Motion")==GL_FALSE) auxQuit();
 Init();
 glutDisplayFunc(predisplay);
 glutReshapeFunc(Reshape);
 glutMainLoop();
}
