////////////////////////////////////////////////////////
//Jason Kim
//CSE 581 Lab 2
//Open GL

//
//Description:  A 3D Open GL Scene with 2 Blue Cubes, a Blue Teapot, and a Red Floor, with a Green Robot with Red Eyes made from a Cone and Cubes.
//Keys: w = wireframe, a = animate, f = forward, t = turn,  q = quit,  u = move robot head up,  h =  move robot head down
//
//
////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>

#include <GL/glut.h> 
#include <GL/gl.h>

int press_x, press_y; 
int release_x, release_y; 
float x_angle = 0.0; 
float y_angle = 0.0; 
float scale_size = 1; 

int xform_mode = 0; 

int forward = 0;
int forwardx = 0;
int forwardz = 0;
int turn = 0;
int turnK = 1;
int wireframe=0;
int headangle=0;
int anim=0;
//int init =1;

#define XFORM_NONE    0 
#define XFORM_ROTATE  1
#define XFORM_SCALE 2 


////////////////////////////////////////////// 

void animate()
{
	turn=turn+10;
	glutPostRedisplay();
	//spins robot around


}
void donothing()
{
	//donothing
}

void resetrobot()
{
	turn=0;
	glutPostRedisplay();

}
void draw_cube(float r, float g, float b)
{
  if(wireframe==0)
  {
	glColor3f(r, g, b); 
	glutSolidCube(1.0);   // draw a solid cube 
  }
  else if(wireframe==1)
  {
	  glColor3f(r,g,b);
	  glutWireCube(1.0);
  }

}

void draw_floor(float r, float g, float b)
{
  if(wireframe==0)
  {
	glScalef(12, 0.1, 12);
	glColor3f(r, g, b); 
	glutSolidCube(1.0);   // draw a floor
  }
  else if(wireframe==1)
  {
	  glScalef(12, 0.1, 12);
	  glColor3f(r,g,b);
	  glutWireCube(1.0);
  }

}

void draw_teapot(float r, float g, float b)
{
  if(wireframe==0)
  {
	glColor3f(r, g, b); 
	glutSolidTeapot(0.5); // draw a solid cube 
  }
  else if(wireframe==1)
  {
	glColor3f(r, g, b); 
	glutWireTeapot(0.5); // draw a solid cube 
  }

}


//Draw The Head of the Robot, which is a Green Cone
void draw_cone(float r, float g, float b)
{

	if(wireframe==0)
	{
		glTranslatef(1,1,2);
		glColor3f(r, g, b); 
		glutSolidCone(1,2,4,4); // draws the head
		glColor3f(0,0,0);
		glutPostRedisplay();
	}
	else if(wireframe==1)
	{
		glTranslatef(1,1,2);
		glColor3f(r, g, b); 
		glutWireCone(1,2,4,4); // draws the head
		glColor3f(0,0,0);
		glutPostRedisplay();
	}

}


//Draw the Legs of the Robot
void draw_legs(float r, float g, float b)
{
	if(wireframe==0)
	{
		glTranslatef(1,1,2);
		glTranslatef(-1,-1,0);
		glScalef(0.5, 2, 0.5);
		glColor3f(r, g, b); 
		glutSolidCube(1.0);   // left leg
		glTranslatef(4,0,0);
		glutSolidCube(1.0);   // right leg
		glutPostRedisplay();
	}
	else if(wireframe==1)
	{
		glTranslatef(1,1,2);
		glTranslatef(-1,-1,0);
		glScalef(0.5, 2, 0.5);
		glColor3f(r, g, b); 
		glutWireCube(1.0);   // left leg
		glTranslatef(4,0,0);
		glutWireCube(1.0);   // right leg
		glutPostRedisplay();
	}
}


//Draw the Eyes of the Robot which are Red cubes
void draw_eyes(float r, float g, float b)
{
	if(wireframe==0)
	{

		glTranslatef(-0.5,0,1);
		glScalef(0.1, 0.1, 0.1);
		glColor3f(r, g, b); 
		glutSolidCube(1.0);  
		glTranslatef(10,0,0);
		glutSolidCube(1.0); // draw eyes
	}
	else if(wireframe == 1)
	{

		glTranslatef(-0.5,0,1);
		glScalef(0.1, 0.1, 0.1);
		glColor3f(r, g, b); 
		glutWireCube(1.0);  
		glTranslatef(10,0,0);
		glutWireCube(1.0); // draw eyes
	}
}

//////////////////////////////////////////////////////

void display()
{
  glEnable(GL_DEPTH_TEST); 
  glClearColor(0,0,0,1); 
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
  
  glMatrixMode(GL_PROJECTION); 
  glLoadIdentity(); 
  gluPerspective(60, 1, .1, 100); 

  glMatrixMode(GL_MODELVIEW); 
  glLoadIdentity(); 
  gluLookAt(0,2,15,0,0,0,0,3,0); 

  glRotatef(x_angle, 0, 1,0); 
  glRotatef(y_angle, 1,0,0); 
  glScalef(scale_size, scale_size, scale_size); 
	


  //initialize scene

  //create scene

  glPushMatrix();
  draw_cube(0,0,1);
  draw_floor(1,0,0);
  glPopMatrix();
  glPushMatrix();
  glTranslatef(3,0,0);
  draw_cube(0,0,1);
  glPopMatrix();
  glTranslatef(0,1,0);
  draw_teapot(0,0,1);
  glPopMatrix();



	//Object Motion
	glTranslatef(forwardx,0,forwardz);
    glRotatef(turn,0,1,0);

	//create object,  Green 2 legged Robot with a Cone for a head and Red eyes
	glPushMatrix();
	//3 Levels of Heirarchy
	glRotatef(headangle,1,0,0);
	draw_cone(0,1,0);//Head
	draw_eyes(1,0,0);//Eyes
	glPopMatrix();
	glPushMatrix();
	draw_legs(0,1,0);//Legs
	
	
	glPopMatrix();
	//create Object

  glutSwapBuffers(); 
}

///////////////////////////////////////////////////////////

void mymouse(int button, int state, int x, int y)
{
  if (state == GLUT_DOWN) {
    press_x = x; press_y = y; 
    if (button == GLUT_LEFT_BUTTON)
      xform_mode = XFORM_ROTATE; 
	 else if (button == GLUT_RIGHT_BUTTON) 
      xform_mode = XFORM_SCALE; 
  }
  else if (state == GLUT_UP) {
	  xform_mode = XFORM_NONE; 
  }
}

/////////////////////////////////////////////////////////

void mymotion(int x, int y)
{
    if (xform_mode==XFORM_ROTATE) {
      x_angle += (x - press_x)/5.0; 
      if (x_angle > 180) x_angle -= 360; 
      else if (x_angle <-180) x_angle += 360; 
      press_x = x; 
	   
      y_angle += (y - press_y)/5.0; 
      if (y_angle > 180) y_angle -= 360; 
      else if (y_angle <-180) y_angle += 360; 
      press_y = y; 
    }
	else if (xform_mode == XFORM_SCALE){
      float old_size = scale_size;
      scale_size *= (1+ (y - press_y)/60.0); 
      if (scale_size <0) scale_size = old_size; 
      press_y = y; 
    }
	glutPostRedisplay(); 
}

///////////////////////////////////////////////////////////////

void mykey(unsigned char key, int x, int y)
{
        switch(key) {
		case 'q': exit(1);
			break; 

			//Move Forward 
		case 'f':
			{
				if(turnK==1)
				{
					forwardz++;
				}
				if(turnK==2)
				{
					
					forwardx++;
				}
				if(turnK==3)
				{
					
					forwardz--;
				}
				if(turnK==4)
				{
				
					forwardx--;
				}
				//forward
			}
			break;

			//Turn 90 degrees to the left
		case 't':
			{
				turn=turn+90;
				if(turnK==1)
				{
				
					//forwardx=0;
					turnK=2;
				}
				else if(turnK==2)
				{
					
					//forwardz=0;
					turnK=3;
				}
				else if(turnK==3)
				{
					
					//forwardx=0;
					turnK=4;
				}
				else if(turnK==4)
				{
					
					//forwardx=0;
					turnK=1;
				}


			}
			break;

			//Toggles Animation.  Makes Robot Spin in a circle
		case 'a':
			{
				//animate
				if(anim==0)
				{
					glutIdleFunc(animate);
					anim=1;
				}
				else
				{

					//toggles Animation off and resets Robot to Start Position.
					anim=0;
					glutIdleFunc(donothing);
					resetrobot();
					
				}


			}
			break;
	
		//Part 3 Keys to move the moveable parts of Robot.  Moves the Cone Head up and Down with u for down and h for up
		case 'u':
			{
				if(headangle < 30)
					headangle=headangle+10;
				//Move Head Down
			}
			break;

	
		case 'h':
			{
				if(headangle >-30)
					headangle=headangle-10;
				//Move Head Up
			}
			break;

			//Toggle WireFrame Mode
		case 'w':
			{
				if(wireframe==0)//wireframe mode
					wireframe=1;
				else
					wireframe=0;
			}
			break;
		}

		
}
///////////////////////////////////////////////////////////////

int main(int argc, char** argv) 
{
  glutInit(&argc, argv); 
  glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH); 
  glutInitWindowSize(600,600); 
  
  glutCreateWindow("Jason Kim CSE581 Lab2"); 
  glutDisplayFunc(display); 
  glutMouseFunc(mymouse); 
  glutMotionFunc(mymotion);
  glutKeyboardFunc(mykey); 
  glutMainLoop(); 
}



