#include<GL/glut.h>
#include<math.h>
#include<iostream>
using namespace std;
// angle of rotation for the camera direction
float angle=0.0;
// actual vector representing the camera's direction
float lx=0.0f,lz=-1.0f;

static float x=0.0f,z=5.0f;

static int spin=0;
static float cy=2,ey=2;
float an=0;
float t=0;
float g=0.2;
float v=0.05;
float h = 0.5;
int isdel=0;
int iscar=0;
float td=0;
void paye(float R1,float R2,float H1,float H2){
	int N = 360;
	float Dtheta = 2 * 3.1415926 / N;
	float r1 =R1, r2=R2 ,h1=H1 ,h2=H2;
	float angle = 0.0;
	glPointSize(10.0);
	glBegin(GL_LINE_STRIP);
	glLineWidth(1000);
//	for (r1; r1 > 0; r1 -= 0.1)
//	{
	for (int i = 0; i <= N; i++)
	{
			glColor3f(0,0.5,0.5);
			float angle = i*Dtheta;
			glVertex3f(cos(angle)*r2,h2, sin(angle)*r2);
			glVertex3f(cos(angle)*r1,h1, sin(angle)*r1);
		}
//	}
glEnd();	
}
void lastic(){
	int N = 360;
	float Dtheta = 2 * 3.1415926 / N;
	float r=1, h1=0 ,h2=-0.5;
	float angle = 0.0;
	glPointSize(10.0);
	glBegin(GL_LINE_STRIP);
	glLineWidth(10000);
	for (r; r > 0; r -= 0.01)
	{
	for (int i = 0; i <= N; i++)
	{
			glColor3f(0,0,0);
			float angle = i*Dtheta;
			glVertex3f(cos(angle)*r, sin(angle)*r,h2);
			glVertex3f(cos(angle)*r, sin(angle)*r,h1);
		}
	}
glEnd();	
}
void init(void){
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}

void light(){
	
GLfloat pos[]={0.0,0.0,1.5,1.0};

glPushMatrix();
glTranslatef(8.0,8.0,-5.0);
glLightfv(GL_LIGHT0,GL_POSITION,pos);
glTranslatef(0,0,1.5);
 if(!spin) glDisable(GL_LIGHTING);
 else glEnable(GL_LIGHTING);
 glPopMatrix();
	
}

void tree1(){
	paye(0.3,0.3,2,0);
	
	glColor3f(0,0.5,0);
	glTranslatef(0.0f ,3.5f, 0.0f);
	glutSolidSphere(2.0f,20,20);	

	glColor3f(0,0.6,0);
	glTranslatef(0.0f ,1.5f, 0.0f);
	glutSolidSphere(2.0f,20,20);	
	
	glColor3f(0,0.4,0);
	glTranslatef(0.0f ,-0.75f, 0.75f);
	glutSolidSphere(2.0f,20,20);	

	glColor3f(0,0.2,0);
	glTranslatef(0.0f ,0.0f, -1.5f);
	glutSolidSphere(2.0f,20,20);	

	glColor3f(0,0.8,0);
	glTranslatef(0.75f ,0.0f, 0.0f);
	glutSolidSphere(2.0f,20,20);

	glColor3f(0,0.6,0);
	glTranslatef(-1.5f ,0.0f, 0.0f);
	glutSolidSphere(2.0f,20,20);

}

void makhroot(){
	int N = 360;
	float Dtheta = 2 * 3.1415926 / N;
	float r = 2;
	float angle = 0.0;
	glPointSize(10.0);

	glBegin(GL_LINE_STRIP);
	glLineWidth(10);

	for (int i = 0; i <= N; i++)
	{

			float angle = i*Dtheta;
			glVertex3f(cos(angle)*r,0, sin(angle)*r);
			glVertex3f(0,2,0);
		}

glEnd();
}
void tree2(){
	glPushMatrix();
	paye(0.3,0.3,2,0);
	glTranslatef(0,2,0);
	glColor3f(0,0.4,0);
	makhroot();
	glTranslatef(0,1,0);
	makhroot();
	glTranslatef(0,1,0);
	makhroot();
	glTranslatef(0,1,0);
	makhroot();
	glTranslatef(0,1,0);
	makhroot();
	glPopMatrix();
}
void draw()
{
	int N = 360;
	float Dtheta = 2 * 3.1415926 / N;
	float angle = 0.0;
	glPointSize(3);
	glBegin(GL_POINTS);
	glColor3f(0, 1, 0);
	for (int i = -90; i <= 90; i++)
	{
		float angle = i*Dtheta;
		glVertex2f(cos(angle) / 3, angle / 3);
		glVertex2f(-cos(angle) / 3, angle / 3);
	}
	for (int i = -90; i <= 90; i++)
	{
		float angle = i*Dtheta;
		glVertex2f(cos(angle) / 20, angle / 3);
	}

	for (int i = -200; i <= -170; i++)
	{
		float angle = i*Dtheta;
		glVertex2f((cos(angle)) + 0.98, (angle / 3) + 0.46);
	}
	glEnd();
	glLineWidth(3);
	glBegin(GL_LINES);
	glColor3f(0, 1, 0);
	angle = 60 * Dtheta;
	glVertex2f(cos(angle) / 3, angle / 3);
	angle = 35 * Dtheta;
	glVertex2f(cos(angle) / 25, angle / 3);
	angle = 60 * Dtheta;
	glVertex2f(-cos(angle) / 3, angle / 3);
	angle = 35 * Dtheta;
	glVertex2f(cos(angle) / 25, angle / 3);
	angle = 35 * Dtheta;
	glVertex2f(cos(angle) / 3, angle / 3);
	angle = 0 * Dtheta;
	glVertex2f(cos(angle) / 25, angle / 3);
	angle = 35 * Dtheta;
	glVertex2f(-cos(angle) / 3, angle / 3);
	angle = 0 * Dtheta;
	glVertex2f(cos(angle) / 25, angle / 3);
	angle = 5 * Dtheta;
	glVertex2f(cos(angle) / 3, angle / 3);
	angle = -35 * Dtheta;
	glVertex2f(cos(angle) / 25, angle / 3);
	angle = 5 * Dtheta;
	glVertex2f(-cos(angle) / 3, angle / 3);
	angle = -35 * Dtheta;
	glVertex2f(cos(angle) / 25, angle / 3);
	angle = -35 * Dtheta;
	glVertex2f(cos(angle) / 3, angle / 3);
	angle = -70 * Dtheta;
	glVertex2f(cos(angle) / 25, angle / 3);
	angle = -35 * Dtheta;
	glVertex2f(-cos(angle) / 3, angle / 3);
	angle = -70 * Dtheta;
	glVertex2f(cos(angle) / 25, angle / 3);
	glEnd();
}

void car(){
	glColor3f(1,0,0);
	glPushMatrix();
	glTranslatef(5,1.6,-10);
	for(int i=0;i<4;i++){
		glTranslatef(2,0,0);
		glutSolidCube(2);
	}
	glPopMatrix();
	glPushMatrix();
	glTranslatef(5,1.6,-8);
	for(int i=0;i<4;i++){
		glTranslatef(2,0,0);
		glutSolidCube(2);
	}
	glPopMatrix();
	glPushMatrix();
	glTranslatef(8,3.3,-10);
	for(int i=0;i<2;i++){
		glTranslatef(2,0,0);
		glutSolidCube(2);
	}
	glPopMatrix();
	
	glPushMatrix();
	glTranslatef(8,3.3,-8);
	for(int i=0;i<2;i++){
		glTranslatef(2,0,0);
		glutSolidCube(2);
	}
	glPopMatrix();

	glBegin(GL_POLYGON);
		glVertex3f(8.0f,2.6f, -7.0f);
		glVertex3f(9.0f,2.6f, -7.0f);
		glVertex3f(9.0f,4.3f, -7.0f);
	glEnd();
	glBegin(GL_POLYGON);
		glVertex3f(8.0f,2.6f, -11.0f);
		glVertex3f(9.0f,2.6f, -11.0f);
		glVertex3f(9.0f,4.3f, -11.0f);
	glEnd();
	glBegin(GL_POLYGON);
		glVertex3f(14.0f,2.6f, -7.0f);
		glVertex3f(13.0f,2.6f, -7.0f);
		glVertex3f(13.0f,4.3f, -7.0f);
	glEnd();
	glBegin(GL_POLYGON);
		glVertex3f(14.0f,2.6f, -11.0f);
		glVertex3f(13.0f,2.6f, -11.0f);
		glVertex3f(13.0f,4.3f, -11.0f);
	glEnd();
	glPushMatrix();
		glColor3f(0,0.5,0.5);
		glTranslatef(7.5,0.9,-6.75);
		lastic();
		glTranslatef(5,0,0);
		lastic();
		glTranslatef(-5,0,-4);
		lastic();
		glTranslatef(5,0,0);
		lastic();
		glPopMatrix();
		glColor3f(1,1,0);
		glPushMatrix();
		glTranslatef(6,1.2,-7.7);
		glutSolidSphere(0.3,30,20);
		glTranslatef(0,0,-2.8);
		glutSolidSphere(0.3,30,20);
		glTranslatef(0,0.7,2.8);
		glutSolidSphere(0.3,30,20);
		glTranslatef(0,0,-2.8);
		glutSolidSphere(0.3,30,20);
		glPopMatrix();
		glColor3f(0.2,1,1);
		glBegin(GL_QUADS);
		glVertex3f(14.0,2.3,-7.0);
		glVertex3f(14.0,2.3,-11.0);
		glVertex3f(13.0,4.3,-11.0);
		glVertex3f(13.0,4.3,-7.0);
		glEnd();
		glBegin(GL_QUADS);
		glVertex3f(7.5,2.3,-7.0);
		glVertex3f(7.5,2.3,-11.0);
		glVertex3f(9.0,4.3,-11.0);
		glVertex3f(9.0,4.3,-7.0);
		glEnd();
		glBegin(GL_POLYGON);
		glVertex3f(11.5,2.6,-11.01);
		glVertex3f(11.5,4.2,-11.01);
		glVertex3f(9.2,4.2,-11.01);
		glVertex3f(8.0,2.6,-11.01);
		glEnd();
		glBegin(GL_POLYGON);
		glVertex3f(11.5,2.6,-6.99);
		glVertex3f(11.5,4.2,-6.99);
		glVertex3f(9.2,4.2,-6.99);
		glVertex3f(8.0,2.6,-6.99);
		glEnd();

}
void delcar(){
	glColor3f(1,0,0);
	glPushMatrix();
	glTranslatef(v*t-0.5*g*t*t,0.0,0.);
	 glTranslatef(h*t, v*t - (g/2.0)*t*t, 0.0);
	glTranslatef(5,1.6,-10);
	for(int i=0;i<4;i++){
		glTranslatef(2,0,0);
		glutSolidCube(2);
	}
	glPopMatrix();
	glPushMatrix();
		glTranslatef(v*t-0.5*g*t*t,0.0,0.);
	 glTranslatef(h*td, v*td - (g/2.0)*td*td, 0.0);
	glTranslatef(5,1.6,-8);
	for(int i=0;i<4;i++){
		glTranslatef(2,0,0);
		glutSolidCube(2);
	}
	glPopMatrix();
	glPushMatrix();
		glTranslatef(v*t-0.5*g*t*t,0.0,0.);
	 glTranslatef(h*td, v*td - (g/2.0)*td*td, 0.0);
	glTranslatef(8,3.3,-10);
	for(int i=0;i<2;i++){
		glTranslatef(2,0,0);
		glutSolidCube(2);
	}
	glPopMatrix();
	
	glPushMatrix();
		glTranslatef(v*t-0.5*g*t*t,0.0,0.);
	 glTranslatef(h*td, v*td - (g/2.0)*td*td, 0.0);
	glTranslatef(8,3.3,-8);
	for(int i=0;i<2;i++){
		glTranslatef(2,0,0);
		glutSolidCube(2);
	}
	glPopMatrix();
glPushMatrix();
	glTranslatef(v*t-0.5*g*t*t,0.0,0.);
	 glTranslatef(h*td, v*td - (g/2.0)*td*td, 0.0);
	glBegin(GL_POLYGON);
		glVertex3f(8.0f,2.6f, -7.0f);
		glVertex3f(9.0f,2.6f, -7.0f);
		glVertex3f(9.0f,4.3f, -7.0f);
	glEnd();
	glBegin(GL_POLYGON);
		glVertex3f(8.0f,2.6f, -11.0f);
		glVertex3f(9.0f,2.6f, -11.0f);
		glVertex3f(9.0f,4.3f, -11.0f);
	glEnd();
	glBegin(GL_POLYGON);
		glVertex3f(14.0f,2.6f, -7.0f);
		glVertex3f(13.0f,2.6f, -7.0f);
		glVertex3f(13.0f,4.3f, -7.0f);
	glEnd();
	glBegin(GL_POLYGON);
		glVertex3f(14.0f,2.6f, -11.0f);
		glVertex3f(13.0f,2.6f, -11.0f);
		glVertex3f(13.0f,4.3f, -11.0f);
	glEnd();
	glPushMatrix();
	 glTranslatef(h*t, v*t - (g/2.0)*t*t, 0.0);
		glColor3f(0,0.5,0.5);
		glTranslatef(7.5,0.9,-6.75);
		lastic();
		glTranslatef(5,0,0);
		lastic();
		glTranslatef(-5,0,-4);
		lastic();
		glTranslatef(5,0,0);
		lastic();
		glPopMatrix();
			glPopMatrix();
		glColor3f(1,1,0);
		glPushMatrix();
		glTranslatef(6,1.2,-7.7);
		glutSolidSphere(0.3,30,20);
		glTranslatef(0,0,-2.8);
		glutSolidSphere(0.3,30,20);
		glTranslatef(0,0.7,2.8);
		glutSolidSphere(0.3,30,20);
		glTranslatef(0,0,-2.8);
		glutSolidSphere(0.3,30,20);
		glPopMatrix();
		glColor3f(0.2,1,1);
		glBegin(GL_QUADS);
		glVertex3f(14.0,2.3,-7.0);
		glVertex3f(14.0,2.3,-11.0);
		glVertex3f(13.0,4.3,-11.0);
		glVertex3f(13.0,4.3,-7.0);
		glEnd();
		glBegin(GL_QUADS);
		glVertex3f(7.5,2.3,-7.0);
		glVertex3f(7.5,2.3,-11.0);
		glVertex3f(9.0,4.3,-11.0);
		glVertex3f(9.0,4.3,-7.0);
		glEnd();
		glBegin(GL_POLYGON);
		glVertex3f(11.5,2.6,-11.01);
		glVertex3f(11.5,4.2,-11.01);
		glVertex3f(9.2,4.2,-11.01);
		glVertex3f(8.0,2.6,-11.01);
		glEnd();
		glBegin(GL_POLYGON);
		glVertex3f(11.5,2.6,-6.99);
		glVertex3f(11.5,4.2,-6.99);
		glVertex3f(9.2,4.2,-6.99);
		glVertex3f(8.0,2.6,-6.99);
		glEnd();
	

}
void animate(int value){
	
	if(iscar){
		
		t+=0.5;
		glutPostRedisplay();
		glutTimerFunc(100,animate,1);
	}
}

void display(void) {
init();
light();

	glClearColor(0.8, 0.8, 1.0, 1);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
	glLoadIdentity();

	gluLookAt(	x, ey, z,
			x+lx, cy,  z+lz,
			0.0f, 1.0f,  0.0f);

        
	glColor3f(0, 1, 0);
	glBegin(GL_QUADS);
		glVertex3f(-100.0f, 0.0f, -100.0f);
		glVertex3f(-100.0f, 0.0f,  100.0f);
		glVertex3f( 100.0f, 0.0f,  100.0f);
		glVertex3f( 100.0f, 0.0f, -100.0f);
	glEnd();
glPushMatrix();	

glTranslatef(0,0,-8);
glTranslatef(v*t-0.5*g*t*t,0.0,0.);
 
car();	

glPopMatrix();
if(isdel==1) delcar();
glPushMatrix();
glTranslatef(-15,0,-8);	
tree1();
glPopMatrix();
glPushMatrix();
glTranslatef(-19,0,-13);

tree2();
glPopMatrix();	

	glutSwapBuffers();
}



void resize(int w, int h)
{
if (h == 0)
h = 1;
float ratio = w * 1.0 / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(50.0f, ratio, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}

void key1(int key,int xx,int yy){
	
	float f=0.1;
	switch(key){
		case GLUT_KEY_LEFT:
			angle-=0.01;
			lx=sin(5*angle);
			lz=-cos(5*angle);
			break;
			case GLUT_KEY_RIGHT:
				angle+=0.01;
				lx=sin(5*angle);
				lz=-cos(5*angle);
				break;
				case GLUT_KEY_UP:
					x+=5*lx*f;
					z+=5*lz*f;
					break;
					case GLUT_KEY_DOWN:
						x-=5*lx*f;
						z-=5*lz*f;
						break;
						
	}
	glutPostRedisplay();
}

void key2(unsigned char key,int x,int y){
	
	switch(key){
		case ' ':
			if(spin) spin=0;
			else spin=1;
			glutPostRedisplay();
			break;
			case 'w':
			cy+=0.1;
			glutPostRedisplay();
			break;
			case 's':
			cy-=0.1;
			glutPostRedisplay();
			break;	
				case 'a':
			an+=0.5;
			glutPostRedisplay();
			break;
			case 'v':
				if(iscar) iscar=0;
				else{
					iscar=1;
					animate(1);
				}
				break;
					case 'r':
			t=0.0;
		//	car();
			glutPostRedisplay();
				break;
						case 'm':
							td=t;
			isdel=1;
		
			glutPostRedisplay();
				break;
	}
	  
	   
}
int main(int argc, char **argv) {
	
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH|GLUT_RGBA);
	glutInitWindowPosition(720,80);
	glutInitWindowSize(500,500);
	glutCreateWindow("final");
	
	glutDisplayFunc(display);
	glutReshapeFunc(resize);
	glutSpecialFunc(key1);
//	glutIdleFunc(display);
glutKeyboardFunc(key2);
	glutMainLoop();
	return 0;
	}
