/*

Space craft class

*/

#include "spacecraft.h"

Spacecraft::Spacecraft(){
	
	fMass = 0.0f;
	roll = 0.0;
	pitch = 0.0;
	yaw = 0.0;
	zoom = 1;
	colorID = 0;
	for_thrust_scale = 0;
	move_mode = false;
	m_forward = false;
	m_reverse = false;
	m_left = false;
	m_right = false;
	m_up = false;
	m_down = false;
	r_right = false;
	r_left = false;
	p_up = false;
	p_down = false;
	y_right = false;
	y_left = false;
	insideShip = false;
	
	//initialize the matrix
	for (int i=0; i<4; i++) {
		for (int j=0; j<4; j++) {
			mOrientation[i][j] = 0;
			mCamera[i][j] = 0;
		}
	}
	mOrientation[0][0] = 1;
	mOrientation[1][1] = 1;
	mOrientation[2][2] = 1;
	mOrientation[3][3] = 1;
	mCamera[0][0] = 1;
	mCamera[1][1] = 1;
	mCamera[2][2] = 1;
	mCamera[3][3] = 1;

	vPosition[0] = 0.0;
	vPosition[1] = 0.0;
	vPosition[2] = 0.0;	
	
	vVelocity[0] = 0.0;
	vVelocity[1] = 0.0;
	vVelocity[2] = 0.0;
}
Spacecraft::initializeShip(int type){
	//initialize textures

	health = 100;
	colorID = type;
	char bluepanel[] = "images\\blue_panel.bmp";
	char redpanel[] = "images\\red_panel.bmp";
	switch(type){
	case 0:
		cout<<"loading blue "<<endl;
		tl.LoadBMP(g_Texture, bluepanel, 0);
		break;
	case 1:
		cout<<"loading red "<<endl;
		tl.LoadBMP(g_Texture, redpanel, 1);
		break;
	default:
		break;
	}
}
Spacecraft::renderView(int view){
	viewInverse();
	//always render laser fire that can be seen
	glPushMatrix();

	glTranslatef(vPosition[0], vPosition[1], vPosition[2]);
		glMultMatrixf((GLfloat*) mOrientation);

		glPushMatrix();
			glPushMatrix();	
				glTranslatef(laser.pos[0],laser.pos[1],laser.pos[2]);
				glColor3f(0.8,0.2,0.3);
				GLUquadricObj* turret = gluNewQuadric();
					gluSphere(turret, 0.006, 4, 4);	
				gluDeleteQuadric(turret);
				if (laser.isbeingfired) {
					laser.fire();
					laser.isbeingfired = false;
				}
			glPopMatrix();
		switch(view){
		case 1: //pilot in ship
			if (insideShip){
				display.render_hud(roll, pitch, yaw,
							   vPosition[0], vPosition[1], vPosition[2],
							   mOrientation[0][0], mOrientation[1][0], mOrientation[2][0],
							   health);
			}
			else 
				drawCraft();
			break;
		case 2:	//gunner in ship
			if (insideShip){
				display.render_hud(roll, pitch, yaw,
							   vPosition[0], vPosition[1], vPosition[2],
							   mOrientation[0][0], mOrientation[1][0], mOrientation[2][0],
							   health);   
			}
			else 
				drawCraft();
			break;
		case 3:	//outside ship
			drawCraft();
			break;
		default:
			break;
		}
		glPopMatrix();	
	glPopMatrix();	
	glDisable(GL_TEXTURE_2D);
}
Spacecraft::viewInverse(){
	float m11 = mOrientation[0][0];
	float m12 = mOrientation[0][1];
	float m13 = mOrientation[0][2];
	float m21 = mOrientation[1][0];
	float m22 = mOrientation[1][1];
	float m23 = mOrientation[1][2];
	float m31 = mOrientation[2][0];
	float m32 = mOrientation[2][1];
	float m33 = mOrientation[2][2];
	//get determinant
	float	d = m11*m22*m33 - 
				m11*m32*m23 + 
				m21*m32*m13 - 
				m21*m12*m33 + 
				m31*m12*m23 - 
				m31*m22*m13;

	if (d == 0) d = 1;
	//set the camera view
	mCamera[0][0] =	(m22*m33-m23*m32)/d;
	mCamera[0][1] =	-(m12*m33-m13*m32)/d;
	mCamera[0][2] =	(m12*m23-m13*m22)/d;
	mCamera[1][0] =	-(m21*m33-m23*m31)/d;
	mCamera[1][1] =	(m11*m33-m13*m31)/d;
	mCamera[1][2] =	-(m11*m23-m13*m21)/d;
	mCamera[2][0] =	(m21*m32-m22*m31)/d;
	mCamera[2][1] =	-(m11*m32-m12*m31)/d;
	mCamera[2][2] =	(m11*m22-m12*m21)/d;	
}
Spacecraft::drawCraft(){
	float sf = 0.05;

	glScalef(sf,sf,sf);

	//set body color and build body
	glEnable(GL_TEXTURE_2D);
	switch(colorID) {
	case 0:
		glColor3f(0.1, 0.1, 0.3);			
		glBindTexture(GL_TEXTURE_2D, g_Texture[0]);
		break;
	case 1:
		glColor3f(0.1, 0.3, 0.1);
		glBindTexture(GL_TEXTURE_2D, g_Texture[1]);
		break;
	case 2:
		glColor3f(0.3, 0.1, 0.1);
		break;
	case 3:
		glColor3f(0.3, 0.1, 0.3);
		break;
	default:
		break;
	}
	body();

	//place left wing
	glPushMatrix();
	glColor3f(0.1, 0.25, 0.1);
	glTranslatef(-6.0, 1.5, 0.35);
	glRotatef(-15, 1.0, 0.0, 0.0);
	wing();
	glPopMatrix();
	
	//place right wing
	glPushMatrix();
	glColor3f(0.25, 0.1, 0.1);
	glTranslatef(-6.0, -1.5, 0.35);
	glRotatef(15, 1.0, 0.0, 0.0);
	wing();
	glPopMatrix();

	//place rocket nozzle at rear
	glPushMatrix();
	glTranslatef(-8.25, 0, 0);
	glColor3f(0.1, 0.1, 0.1);
	rocketNozzle();
	glPopMatrix();
	

	glPushMatrix();
	//set flame color
	glColor3f(0.4, 0.2, 0.1);
	if(for_thrust_scale > 0) moveForward();
	//all other thrusters have one size
	if(m_reverse) moveReverse();
	if(m_left) moveLeft();
	if(m_right) moveRight();
	if(m_up) moveUp();
	if(m_down) moveDown();
	if(r_right) rollRight();
	if(r_left) rollLeft();
	if(p_up) pitchUp();
	if(p_down) pitchDown();
	if(y_right) yawRight();
	if(y_left) yawLeft();
	glPopMatrix();
}

Spacecraft::body(){
	//push and pop required in here
	//because we are scaling the body
	//to make its shape
	glPushMatrix();
	GLUquadricObj* body = gluNewQuadric();
		gluQuadricTexture(body, GL_TRUE);
		//gluQuadricDrawStyle(body, GLU_LINE);
		glScalef(8.0, 3.0, 1.0);
		gluSphere(body, 1, 36, 18);	
	gluDeleteQuadric(body);
	glPopMatrix();
	glDisable(GL_TEXTURE_2D);
}

Spacecraft::wing(){
	//set wing angle
	glRotatef(-6, 0, 1, 0);
	glBegin(GL_POLYGON);
		glVertex3f(0.0, 0.1, 0.0);
		glVertex3f(0.5, 0.1, 1.0);
		glVertex3f(2.0, 0.1, 1.0);
		glVertex3f(4.0, 0.1, 0.0);
	glEnd();

	glBegin(GL_POLYGON);
		glVertex3f(0.0, -0.1, 0.0);
		glVertex3f(4.0, -0.1, 0.0);
		glVertex3f(2.0, -0.1, 1.0);
		glVertex3f(0.5, -0.1, 1.0);
	glEnd();

	glBegin(GL_POLYGON);
		glVertex3f(0.0,  0.1, 0.0);
		glVertex3f(0.0, -0.1, 0.0);
		glVertex3f(0.5, -0.1, 1.0);
		glVertex3f(0.5,  0.1, 1.0);
	glEnd();

	glBegin(GL_POLYGON);
		glVertex3f(0.5,  0.1, 1.0);
		glVertex3f(0.5, -0.1, 1.0);
		glVertex3f(2.0, -0.1, 1.0);
		glVertex3f(2.0,  0.1, 1.0);
	glEnd();

	glBegin(GL_POLYGON);
		glVertex3f(2.0, -0.1, 1.0);
		glVertex3f(4.0, -0.1, 0.0);
		glVertex3f(4.0,  0.1, 0.0);
		glVertex3f(2.0,  0.1, 1.0);
	glEnd();

}

Spacecraft::rocketNozzle(){
	GLUquadric* nozzle = gluNewQuadric();
	GLUquadric* nozzle_cap = gluNewQuadric();
		gluQuadricDrawStyle(nozzle, GLU_FILL);
		gluQuadricDrawStyle(nozzle_cap, GLU_FILL);
		glRotatef(90, 0, 1, 0);
		gluCylinder(nozzle, 0.5, 0, 2, 10, 5);
		glRotatef(180, 0, 1, 0);
		gluDisk(nozzle_cap, 0, 0.5, 10, 5);
	gluDeleteQuadric(nozzle);
	gluDeleteQuadric(nozzle_cap);
}

Spacecraft::flame(){
	GLUquadric* section1 = gluNewQuadric();
	GLUquadric* section2 = gluNewQuadric();
	GLUquadric* section3 = gluNewQuadric();
	GLUquadric* section4 = gluNewQuadric();
	GLUquadric* section5 = gluNewQuadric();

		gluQuadricDrawStyle(section1, GLU_FILL);
		//glRotatef(180, 0, 1, 0);
		gluCylinder(section1, 0.4, 0.55, .5, 10, 5);
		glTranslatef(0, 0, 0.5);
		gluQuadricDrawStyle(section2, GLU_FILL);
		gluCylinder(section1, 0.55, 0.55, 0.5, 10, 5);
		glTranslatef(0, 0, 0.5);
		gluQuadricDrawStyle(section3, GLU_FILL);
		gluCylinder(section1, 0.55, 0.45, 0.5, 10, 5);
		glTranslatef(0, 0, 0.5);
		gluQuadricDrawStyle(section4, GLU_FILL);
		gluCylinder(section1, 0.45, 0.3, 0.5, 10, 5);
		glTranslatef(0, 0, 0.5);
		gluQuadricDrawStyle(section5, GLU_FILL);
		gluCylinder(section1, 0.3, 0.0, 2, 10, 5);

	gluDeleteQuadric(section1);
	gluDeleteQuadric(section2);
	gluDeleteQuadric(section3);
	gluDeleteQuadric(section4);
	gluDeleteQuadric(section5);
}

Spacecraft::moveForward(){	
	//flame for tailpipe
	glPushMatrix();
	glTranslatef(-8.3, 0, 0);
	glRotatef(-90, 0, 1, 0);
	glScalef(for_thrust_scale,for_thrust_scale,for_thrust_scale);
	flame();
	glPopMatrix();
}

Spacecraft::moveReverse(){
	glPushMatrix();
	glTranslatef(8,0,0);
	glRotatef(180, 0, 1, 0);	
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
	m_reverse = false;
	glutPostRedisplay();
}
Spacecraft::moveLeft(){
	rocket_right_foreward();
	rocket_right_aft();
	m_left = false;
	glutPostRedisplay();
}
Spacecraft::moveRight(){
	rocket_left_foreward();
	rocket_left_aft();
	m_right = false;
	glutPostRedisplay();
}
Spacecraft::moveUp(){
	rocket_bottom_foreward();
	rocket_bottom_aft();
	m_up = false;
	glutPostRedisplay();
}
Spacecraft::moveDown(){
	rocket_top_foreward();
	rocket_top_aft();
	m_down = false;
	glutPostRedisplay();
}
Spacecraft::rollRight(){
	rocket_top_right();
	rocket_bottom_left();
	r_right = false;
	glutPostRedisplay();
}
Spacecraft::rollLeft(){
	//roll the craft to the left

	//take care of the display
	rocket_top_left();
	rocket_bottom_right();
	r_left = false;
	glutPostRedisplay();
}
Spacecraft::pitchUp(){
	rocket_bottom_foreward();
	rocket_top_aft();
	p_up = false;
	glutPostRedisplay();
}
Spacecraft::pitchDown(){
	rocket_top_foreward();
	rocket_bottom_aft();
	p_down = false;
	glutPostRedisplay();
}
Spacecraft::yawRight(){
	rocket_left_foreward();
	rocket_right_aft();
	y_right = false;
	glutPostRedisplay();
}
Spacecraft::yawLeft(){
	rocket_right_foreward();
	rocket_left_aft();
	y_left = false;
	glutPostRedisplay();
}
Spacecraft::rocket_left_foreward(){
	glPushMatrix();
	glTranslatef(7, 1.35, 0);
	glRotatef(-90, 1, 0, 0);	
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
}
Spacecraft::rocket_left_aft(){
	glPushMatrix();
	glTranslatef(-7, 1.35, 0);
	glRotatef(-90, 1, 0, 0);	
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
}
Spacecraft::rocket_right_foreward(){
	glPushMatrix();
	glTranslatef(7, -1.35, 0);
	glRotatef(90, 1, 0, 0);	
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
}
Spacecraft::rocket_right_aft(){
	glPushMatrix();
	glTranslatef(-7, -1.35, 0);
	glRotatef(90, 1, 0, 0);	
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
}
Spacecraft::rocket_top_foreward(){
	glPushMatrix();
	glTranslatef(7.0, 0.0, 0.45);
	//no rotation needed
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
}
Spacecraft::rocket_top_aft(){
	glPushMatrix();
	glTranslatef(-7.0, 0.0, 0.45);
	//no rotation needed
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
}
Spacecraft::rocket_top_left(){
	glPushMatrix();
	glTranslatef(0.0, 2.5, 0.65);
	//no rotation needed	
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
}
Spacecraft::rocket_top_right(){
	glPushMatrix();
	glTranslatef(0.0, -2.5, 0.65);
	//no rotation needed
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
}
Spacecraft::rocket_bottom_foreward(){
	glPushMatrix();
	glTranslatef(7.0, 0.0, -0.45);
	glRotatef(180, 1, 0, 0);	
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
}
Spacecraft::rocket_bottom_aft(){
	glPushMatrix();
	glTranslatef(-7.0, 0.0, -0.45);
	glRotatef(180, 1, 0, 0);		
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
}
Spacecraft::rocket_bottom_right(){
	glPushMatrix();
	glTranslatef(0.0, -2.5, -0.65);
	glRotatef(180, 1, 0, 0);	
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
}

Spacecraft::rocket_bottom_left(){
	glPushMatrix();
	glTranslatef(0.0, 2.5, -0.65);
	glRotatef(180, 1, 0, 0);	
	glScalef(0.2, 0.2, 0.2);
	flame();
	glPopMatrix();
}

