//******************************************************************************
//* Christopher A. Robbins                                                     *
//* Graphics:  Assignment Three                                                *
//* November 5, 2001                                                           *
//******************************************************************************
#ifndef __ASSIGNMENT3_H__
#define __ASSIGNMENT3_H__

#include <math.h>
#include "cvec3t-vc.h"
#include "transforms.h"
#include "gl/glut.h"

// Action class maintains and performs user selected actions
class action {

public:

	float X_Rotation;
	float Y_Rotation;
	float Z_Rotation;
	float RightChairX;

	int   actionSelected;
    bool  performAction;

	action();
	bool swapActionState();
	void processAction(CVec3T<float>&, const CVec3T<float>, const CVec3T<float>);
};

action::action() { 
		
	X_Rotation     = 0.0; 
    Y_Rotation     = 0.0;
	Z_Rotation     = 0.0;
	RightChairX    = 2.5;
	actionSelected = 0;
	performAction  = false;
}
	
bool action::swapActionState() {

	if(performAction == true) {
		performAction = false;
	} else {
		performAction = true;
	}
	return performAction;
}


void action::processAction(CVec3T<float> &camera, 
						   const CVec3T<float> lookat, 
						   const CVec3T<float> cameraZoom) {
		
	CVec3T<float>  newVector;

	if(performAction) {
		switch(actionSelected) {
			case 1:
				newVector = camera + cameraZoom;
				if (newVector.l2() > lookat.l2()) {
					camera = newVector; 	
				}
				break;
			case 2:
				newVector = camera - cameraZoom;
				if (newVector.l2() < 10.0) {
					camera = newVector; 	
				}
				break;
			case 3:
				camera = 
				CVec3T<float>(camera.x() * cos(.02)  + camera.z() * sin(.02),
							  camera.y(),
							-(camera.x() * sin(.02)) + camera.z() * cos(.02));
				break;
			case 4:
				if(RightChairX > 1.1) RightChairX -= 0.01;
				break;
			case 5:
				if(RightChairX < 2.6) RightChairX += 0.01;
				break;	
            case 6:
				rotate(X_Rotation, 1.0, 0.0, 0.0); // X Rotation
				break;
			case 7:
				rotate(Y_Rotation, 0.0, 1.0, 0.0); // Y Rotation
				break;
			case 8:
				rotate(Z_Rotation, 0.0, 0.0, 1.0); // Z Rotation
				break;
		}
	}
}

// Draw a Cube with dimensions x X y X z using OpenGL polygon primative
void drawCube(float x, float y, float z) {

	glBegin(GL_POLYGON); // Front Quad

		glNormal3f(0.0, 0.0,  1.0);
 
		glVertex3f(-(x/2), -(y/2),  (z/2));
		glVertex3f( (x/2), -(y/2),  (z/2));
		glVertex3f( (x/2),  (y/2),  (z/2));
		glVertex3f(-(x/2),  (y/2),  (z/2));

	glEnd();

	glBegin(GL_POLYGON); // Back Quad

		glNormal3f(0.0, 0.0, -1.0);

		glVertex3f(-(x/2),  (y/2), -(z/2));
		glVertex3f( (x/2),  (y/2), -(z/2));
		glVertex3f( (x/2), -(y/2), -(z/2));
		glVertex3f(-(x/2), -(y/2), -(z/2));

	glEnd();

	glBegin(GL_POLYGON); // Top Quad

		glNormal3f(0.0, 1.0, 0.0);

		glVertex3f(-(x/2),  (y/2),  (z/2));
		glVertex3f( (x/2),  (y/2),  (z/2));
		glVertex3f( (x/2),  (y/2), -(z/2));
		glVertex3f(-(x/2),  (y/2), -(z/2));

	glEnd();

	glBegin(GL_POLYGON); // Bottom Quad

		glNormal3f(0.0, -1.0, 0.0);

		glVertex3f(-(x/2), -(y/2),  (z/2));
		glVertex3f( (x/2), -(y/2),  (z/2));
		glVertex3f( (x/2), -(y/2), -(z/2));
		glVertex3f(-(x/2), -(y/2), -(z/2));

	glEnd();

	glBegin(GL_POLYGON); // Left Side Quad

		glNormal3f(-1.0, 0.0, 0.0);

		glVertex3f(-(x/2), -(y/2),  (z/2));
		glVertex3f(-(x/2),  (y/2),  (z/2));
		glVertex3f(-(x/2),  (y/2), -(z/2));
		glVertex3f(-(x/2), -(y/2), -(z/2));

	glEnd();

	glBegin(GL_POLYGON); // Right Side Quad

		glNormal3f(1.0, 0.0, 0.0);

		glVertex3f( (x/2), -(y/2),  (z/2));
		glVertex3f( (x/2),  (y/2),  (z/2));
		glVertex3f( (x/2),  (y/2), -(z/2));
		glVertex3f( (x/2), -(y/2), -(z/2));

	glEnd();
}

// Draw a Table using custom transform functions and drawCube()
void drawTable() {

		glPushMatrix(); //Table Top
		   translate(0.0, 1.0, 0.0);
			drawCube(3.5, 0.25, 2.0);
		glPopMatrix();

		glPushMatrix(); //Back Left Table Leg
		   translate(-1.5, 0.0, -0.75);
			drawCube(0.25, 2.0, 0.25);
		glPopMatrix();

		glPushMatrix(); //Front Left Table Leg
		   translate(-1.5, 0.0, 0.75);
			drawCube(0.25, 2.0, 0.25);
		glPopMatrix();

		glPushMatrix(); //Back Right Table Leg
		   translate(1.5, 0.0, -0.75);
			drawCube(0.25, 2.0, 0.25);
		glPopMatrix();

		glPushMatrix(); //Front Right Table Leg
		   translate(1.5, 0.0, 0.75);
			drawCube(0.25, 2.0, 0.25);
		glPopMatrix();
}

// Draw a Chair using custom transform functions and drawCube()
void drawChair() {
	
	glPushMatrix(); //Seat
		translate(0.0, 0.0625, 0.0);
		drawCube(1.0, 0.125, 1.0);
	glPopMatrix();  

	glPushMatrix();//Seat Back
		rotate(-7, 1.0, 0.0, 0.0);
		translate(0.0, 0.75, -0.4375);
		drawCube(1.0, 1.5, 0.125);
	glPopMatrix();

	glPushMatrix(); //Back Left Chair Leg
		translate(-0.4375, -0.5, -0.4375);
		drawCube(0.125, 1.0, 0.125);
	glPopMatrix();

	glPushMatrix(); //Front Left Chair Leg
		translate(-0.4375, -0.5, 0.4375);
		drawCube(0.125, 1.0, 0.125);
	glPopMatrix();
				
	glPushMatrix(); //Back Right Chair Leg
		translate(0.4375, -0.5, -0.4375);
		drawCube(0.125, 1.0, 0.125);
	glPopMatrix();
				
	glPushMatrix(); //Front Right Chair Leg
		translate(0.4375, -0.5, 0.4375);
		drawCube(0.125, 1.0, 0.125);
	glPopMatrix();
}

#endif /*  __ASSIGNMENT3_H__ */
