/*
Solar Conquest
Copyright (C) 2006 Greg Beaman

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#define OBJ_STATE_DEAD 0
#define OBJ_STATE_PLAYER 1
#define OBJ_STATE_IDLE 2
#define OBJ_STATE_MOVING 3
#define OBJ_STATE_GUARDING 4
#define OBJ_STATE_ATTACKING 5
#define OBJ_STATE_FOLLOWING 6

#define AI_TYPE_NORMAL 0
#define AI_TYPE_ASHLEY 1
#define AI_TYPE_RODNEY 2
#define AI_TYPE_MORETTI 3
#define AI_TYPE_FOLLOWER 4

class CObject
{
private:
	Vector position;
	float angle;
	float speed;
	float strafeSpeed;
	int health;
	int state;
	int team;
	
	CObjectData* data;

public:
	int aiType;

	float fireTime;
	float engineTime;
	float smokeTime;

	int input_speed;
	int input_turn;
	int input_strafe;
	bool input_fire;
	
	CObject* turret;
	CObject* target;
	CObject* parent;
	CObject* prevObj;
	CObject* nextObj;
	
	CObject(CObjectData* objData);
	~CObject();

	void Update(float elapsedTime);
	void PhysicsUpdate(float elapsedTime);
	void Render(int cameraX, int cameraY);
	
	void SetHealth(int hp);
	void SetSpeed(float s);
	void SetState(int s);
	void SetTeam(int t);
	void SetPosition(float x, float y);
	void SetPosition(Vector pos);
	void SetAngle(float nAngle);
	
	CObjectData* GetData();
	int GetHealth();
	int GetState();
	int GetTeam();
	float GetSpeed();
	Vector GetPosition();
	float GetAngle();
};

CObject::CObject(CObjectData* objData)
{
	aiType = AI_TYPE_NORMAL;

	data = objData;
	position = CreateVector(0,0);
	angle = 0;
	
	health = data->maxHealth;
	speed = 0;
	strafeSpeed = 0;
	team = 0;
	state = OBJ_STATE_IDLE;
	
	fireTime = 0;
	engineTime = 0;
	smokeTime = 0;
	
	input_speed = 0;
	input_turn = 0;
	input_strafe = 0;
	input_fire = false;
	
	turret = NULL;
	target = NULL;
	prevObj = NULL;
	nextObj = NULL;
	parent = NULL;
}

CObject::~CObject()
{
	if (turret)
		delete turret;
}

void CObject::Update(float elapsedTime)
{
	if (state == OBJ_STATE_DEAD)
		return;

	if (fireTime > 0)
		fireTime -= elapsedTime;
	if (engineTime > 0)
		engineTime -= elapsedTime;
	if (smokeTime > 0)
		smokeTime -= elapsedTime;

	if (state == OBJ_STATE_IDLE)
	{
		input_speed = 0;
		input_fire = 0;
		input_turn = 0;
		input_strafe = 0;
	}
	else if (state == OBJ_STATE_PLAYER) {}
	else if (state == OBJ_STATE_MOVING)
	{
	}
	else if (state == OBJ_STATE_GUARDING)
	{
	}
	else if (state == OBJ_STATE_FOLLOWING)
	{
		input_fire = 0;
		input_speed = 0;
		input_turn = 0;
		input_strafe = 0;
		if (parent)
		{
			float targetAngle = ((atan2(parent->GetPosition().x-position.x,position.y-parent->GetPosition().y ) * -1) - (3.14));
			//			float targetAngle = ((fast_atan2f(target->GetPosition().x-position.x,position.y-target->GetPosition().y ) * -1) - (3.14));

			if (absf(GetNegativeAngle(GetProperAngle(angle))-GetNegativeAngle(GetProperAngle(targetAngle))) <= data->turnRate)
			{
				angle = targetAngle;
				input_turn = 0;
				float dist = Distance(position,parent->GetPosition());
				if (dist > 300)
					input_speed = 1;
				else if (dist < 10)
					input_speed = -1;
				else
					input_speed = 0;
				if (dist <= data->attackRange)
				{
					if (rand()%2 == 0)
						input_strafe = -1;
					else
						input_strafe = 1;
				}
			}
			else
			{
				if (targetAngle > angle)
					input_turn = -1;
				else
					input_turn = 1;
			}
		}
		else
			SetState(OBJ_STATE_IDLE);
	}
	else if (state == OBJ_STATE_ATTACKING)
	{
		input_fire = 0;
		input_speed = 0;
		input_turn = 0;
		input_strafe = 0;
		if (target)
		{
			float targetAngle = ((atan2(target->GetPosition().x-position.x,position.y-target->GetPosition().y ) * -1) - (3.14));
			//			float targetAngle = ((fast_atan2f(target->GetPosition().x-position.x,position.y-target->GetPosition().y ) * -1) - (3.14));

			if (absf(GetNegativeAngle(GetProperAngle(angle))-GetNegativeAngle(GetProperAngle(targetAngle))) <= data->turnRate)
			{
				angle = targetAngle;
				input_turn = 0;
				float dist = Distance(position,target->GetPosition());
				if (dist > 300)
					input_speed = 1;
				else if (dist < 10)
					input_speed = -1;
				else
					input_speed = 0;
				if (dist <= data->attackRange)
				{
					input_fire = 1;
					//Need an if statement otherwise both ships will sit still if neither strafes
					if (target->input_strafe == 0)
					{
						if (rand()%2 == 0)
							input_strafe = -1;
						else
							input_strafe = 1;
					}
					else
						input_strafe = target->input_strafe;
				}
			}
			else
			{
				if (targetAngle > angle)
					input_turn = -1;
				else
					input_turn = 1;
			}
		}
		else
			SetState(OBJ_STATE_IDLE);
	}
	
	if (turret)
		turret->Update(elapsedTime);
	if (data->type != OBJ_TYPE_TURRET)
		PhysicsUpdate(elapsedTime);
}

void CObject::PhysicsUpdate(float elapsedTime)
{
	angle -= (input_turn * data->turnRate) * elapsedTime;
	angle = CapAngle(angle);
	
	if (input_speed != 0)
		speed += (input_speed * data->acceleration) * elapsedTime;
	else
	{
		if (speed < 0)
		{
			if (speed+((data->acceleration/2)*elapsedTime) < 0)
				speed += (data->acceleration/2) * elapsedTime;
			else
				speed = 0;
		}
		else if (speed > 0)
		{
			if (speed-((data->acceleration/2)*elapsedTime) > 0)
				speed -= (data->acceleration/2) * elapsedTime;
			else
				speed = 0;
		}
	}
	
	if (input_strafe != 0)
		strafeSpeed += (input_strafe * data->acceleration) * elapsedTime;
	else
	{
		if (strafeSpeed < 0)
		{
			if (strafeSpeed+((data->acceleration/2)*elapsedTime) < 0)
				strafeSpeed += (data->acceleration/2) * elapsedTime;
			else
				strafeSpeed = 0;
		}
		else if (strafeSpeed > 0)
		{
			if (strafeSpeed-((data->acceleration/2)*elapsedTime) > 0)
				strafeSpeed -= (data->acceleration/2) * elapsedTime;
			else
				strafeSpeed = 0;
		}
		else
			strafeSpeed = 0;
	}
	
	if (speed > data->maxSpeed)
		speed = data->maxSpeed;
	if (speed < -data->maxSpeed)
		speed = -data->maxSpeed;
	if (strafeSpeed > data->strafeSpeed)
		strafeSpeed = data->strafeSpeed;
	if (strafeSpeed < -data->strafeSpeed)
		strafeSpeed = -data->strafeSpeed;
	position.x += GetSin(angle) * speed * elapsedTime;
	position.y += GetCos(angle) * speed * elapsedTime;
	
	position.x += GetSin(angle+(3.14/2)) * strafeSpeed * elapsedTime;
	position.y += GetCos(angle+(3.14/2)) * strafeSpeed * elapsedTime;
	
	//Make sure the object stays in map bounds
	if (position.x < 0)
		position.x = 0;
	if (position.y < 0)
		position.y = 0;
	if (position.x > (MAP_SIZE*TILE_SIZE))
		position.x = (MAP_SIZE*TILE_SIZE);
	if (position.y > (MAP_SIZE*TILE_SIZE))
		position.y = (MAP_SIZE*TILE_SIZE);
	
	if (health > data->maxHealth)
		health = data->maxHealth;

	if (turret)
		turret->SetPosition(AddVectors(position,data->turretOffset));
}

void CObject::Render(int cameraX, int cameraY)
{
	if (Distance(cameraX+(g_screenWidth/2),cameraY+(g_screenHeight/2),position.x,position.y) <= ((g_screenWidth)+data->radius))
	{
		if (team == 1)
			glColor4f(0.0,0.0,1.0,0.4);
		else if (team == 2)
			glColor4f(1.0,0.0,0.0,0.4);
		else
			glColor4f(1.0,1.0,1.0,0.4);
			
		if (data->model)
		{
			data->model->Render(SubtractVectors(position,CreateVector(cameraX,cameraY)),angle);
			
			if (turret)
				turret->Render(cameraX,cameraY);
			return;
		}
		
		
		if (data->type == OBJ_TYPE_FIGHTER)
		{
			glBegin(GL_TRIANGLE_STRIP);
				glVertex2f((GetSin(angle-ToRadians(135))*10)+(position.x-cameraX),(GetCos(angle-ToRadians(135))*10)+(position.y-cameraY));
				glVertex2f((GetSin(angle)*12)+(position.x-cameraX),(GetCos(angle)*12)+(position.y-cameraY));
				glVertex2f((position.x-cameraX),(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(135))*10)+(position.x-cameraX),(GetCos(angle+ToRadians(135))*10)+(position.y-cameraY));
			glEnd();
			
			glBegin(GL_LINE_STRIP);
				glVertex2f((GetSin(angle-ToRadians(135))*10)+(position.x-cameraX),(GetCos(angle-ToRadians(135))*10)+(position.y-cameraY));
				glVertex2f((GetSin(angle)*12)+(position.x-cameraX),(GetCos(angle)*12)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(135))*10)+(position.x-cameraX),(GetCos(angle+ToRadians(135))*10)+(position.y-cameraY));
				glVertex2f((position.x-cameraX),(position.y-cameraY));
				glVertex2f((GetSin(angle-ToRadians(135))*10)+(position.x-cameraX),(GetCos(angle-ToRadians(135))*10)+(position.y-cameraY));
			glEnd();
		}
		
		else if (data->type == OBJ_TYPE_BOMBER)
		{
			glBegin(GL_QUADS);
				glVertex2f((GetSin(angle-ToRadians(135))*10)+(position.x-cameraX),(GetCos(angle-ToRadians(135))*10)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(135))*10)+(position.x-cameraX),(GetCos(angle+ToRadians(135))*10)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(45))*20)+(position.x-cameraX),(GetCos(angle+ToRadians(45))*20)+(position.y-cameraY));
				glVertex2f((GetSin(angle-ToRadians(45))*20)+(position.x-cameraX),(GetCos(angle-ToRadians(45))*20)+(position.y-cameraY));
			glEnd();
			glBegin(GL_TRIANGLES);
				glVertex2f((GetSin(angle+ToRadians(15))*10)+(position.x-cameraX),(GetCos(angle+ToRadians(15))*10)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(0))*40)+(position.x-cameraX),(GetCos(angle+ToRadians(0))*40)+(position.y-cameraY));
				glVertex2f((GetSin(angle-ToRadians(15))*10)+(position.x-cameraX),(GetCos(angle-ToRadians(15))*10)+(position.y-cameraY));
			glEnd();
			glBegin(GL_LINE_STRIP);
				glVertex2f((GetSin(angle+ToRadians(135))*10)+(position.x-cameraX),(GetCos(angle+ToRadians(135))*10)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(45))*20)+(position.x-cameraX),(GetCos(angle+ToRadians(45))*20)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(15))*10)+(position.x-cameraX),(GetCos(angle+ToRadians(15))*10)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(0))*40)+(position.x-cameraX),(GetCos(angle+ToRadians(0))*40)+(position.y-cameraY));
				glVertex2f((GetSin(angle-ToRadians(15))*10)+(position.x-cameraX),(GetCos(angle-ToRadians(15))*10)+(position.y-cameraY));
				glVertex2f((GetSin(angle-ToRadians(45))*20)+(position.x-cameraX),(GetCos(angle-ToRadians(45))*20)+(position.y-cameraY));
				glVertex2f((GetSin(angle-ToRadians(135))*10)+(position.x-cameraX),(GetCos(angle-ToRadians(135))*10)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(135))*10)+(position.x-cameraX),(GetCos(angle+ToRadians(135))*10)+(position.y-cameraY));
			glEnd();
		}
		
		else if (data->type == OBJ_TYPE_REPAIRSHIP)
		{
			glBegin(GL_TRIANGLE_STRIP);
				glVertex2f((GetSin(angle-ToRadians(165))*20)+(position.x-cameraX),(GetCos(angle-ToRadians(165))*20)+(position.y-cameraY));
				glVertex2f((GetSin(angle-ToRadians(15))*20)+(position.x-cameraX),(GetCos(angle-ToRadians(15))*20)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(165))*20)+(position.x-cameraX),(GetCos(angle+ToRadians(165))*20)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(15))*20)+(position.x-cameraX),(GetCos(angle+ToRadians(15))*20)+(position.y-cameraY));
			glEnd();
			
			glBegin(GL_LINE_STRIP);
				glVertex2f((GetSin(angle-ToRadians(165))*20)+(position.x-cameraX),(GetCos(angle-ToRadians(165))*20)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(165))*20)+(position.x-cameraX),(GetCos(angle+ToRadians(165))*20)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(15))*20)+(position.x-cameraX),(GetCos(angle+ToRadians(15))*20)+(position.y-cameraY));
				glVertex2f((GetSin(angle-ToRadians(15))*20)+(position.x-cameraX),(GetCos(angle-ToRadians(15))*20)+(position.y-cameraY));
				glVertex2f((GetSin(angle-ToRadians(165))*20)+(position.x-cameraX),(GetCos(angle-ToRadians(165))*20)+(position.y-cameraY));
			glEnd();
		}
		
		else if (data->type == OBJ_TYPE_TURRET || data->type == OBJ_TYPE_IMMOBILE_TURRET || data->type == OBJ_TYPE_REPAIRTURRET)
		{
			glBegin(GL_LINE_STRIP);
				glVertex2f((GetSin(angle-ToRadians(135))*2)+(position.x-cameraX),(GetCos(angle-ToRadians(135))*2)+(position.y-cameraY));
				glVertex2f((GetSin(angle-ToRadians(45))*2)+(position.x-cameraX),(GetCos(angle-ToRadians(45))*2)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(135))*2)+(position.x-cameraX),(GetCos(angle+ToRadians(135))*2)+(position.y-cameraY));
				glVertex2f((GetSin(angle+ToRadians(45))*2)+(position.x-cameraX),(GetCos(angle+ToRadians(45))*2)+(position.y-cameraY));
				glVertex2f((GetSin(angle-ToRadians(135))*2)+(position.x-cameraX),(GetCos(angle-ToRadians(135))*2)+(position.y-cameraY));
			glEnd();
		}
/*		
		else if (data->type == OBJ_TYPE_CAPITALSHIP)
		{
			glBegin(GL_QUADS);
				for (int i=3; i <= 5; i++)
				{
					glVertex2f(-(i*5)+(position.x-cameraX),-(i*5)+(position.y-cameraY));
					glVertex2f(-(i*5)+(position.x-cameraX),(i*5)+(position.y-cameraY));
					glVertex2f((i*5)+(position.x-cameraX),(i*5)+(position.y-cameraY));
					glVertex2f((i*5)+(position.x-cameraX),-(i*5)+(position.y-cameraY));
				}
			glEnd();
		
			glBegin(GL_LINES);
				for (i=3; i <= 5; i++)
				{
					glVertex2f((-i*5)+(position.x-cameraX),-(i*5)+(position.y-cameraY));
					glVertex2f(-(i*5)+(position.x-cameraX),(i*5)+(position.y-cameraY));
					
					glVertex2f(-(i*5)+(position.x-cameraX),(i*5)+(position.y-cameraY));
					glVertex2f((i*5)+(position.x-cameraX),(i*5)+(position.y-cameraY));
					
					glVertex2f((i*5)+(position.x-cameraX),(i*5)+(position.y-cameraY));
					glVertex2f((i*5)+(position.x-cameraX),-(i*5)+(position.y-cameraY));
				
					glVertex2f((i*5)+(position.x-cameraX),-(i*5)+(position.y-cameraY));
					glVertex2f(-(i*5)+(position.x-cameraX),-(i*5)+(position.y-cameraY));
				}
			glEnd();
		
			glBegin(GL_TRIANGLES);
				glVertex2f((GetSin(-2.38907)*205.183) + (position.x-cameraX),(GetCos(-2.38907)*205.183) + (position.y-cameraY));
				glVertex2f((GetSin(-2.65004)*170) + (position.x-cameraX),(GetCos(-2.65004)*170) + (position.y-cameraY));
				glVertex2f((GetSin(-1.9741)*152.315) + (position.x-cameraX),(GetCos(-1.9741)*152.315) + (position.y-cameraY));
				
				glVertex2f((GetSin(-2.65004)*170) + (position.x-cameraX),(GetCos(-2.65004)*170) + (position.y-cameraY));
				glVertex2f((GetSin(-1.9741)*152.315) + (position.x-cameraX),(GetCos(-1.9741)*152.315) + (position.y-cameraY));
				glVertex2f((GetSin(-1.21043)*85.44) + (position.x-cameraX),(GetCos(-1.21043)*85.44) + (position.y-cameraY));
				
				glVertex2f((GetSin(-2.2127)*100) + (position.x-cameraX),(GetCos(-2.2127)*100) + (position.y-cameraY));
				glVertex2f((GetSin(-4.0673)*100) + (position.x-cameraX),(GetCos(-4.0673)*100) + (position.y-cameraY));
				glVertex2f((GetSin(-1.21043)*85.44) + (position.x-cameraX),(GetCos(-1.21043)*85.44) + (position.y-cameraY));
				
				glVertex2f((GetSin(-5.06957)*85.44) + (position.x-cameraX),(GetCos(-5.06957)*85.44) + (position.y-cameraY));
				glVertex2f((GetSin(-4.0673)*100) + (position.x-cameraX),(GetCos(-4.0673)*100) + (position.y-cameraY));
				glVertex2f((GetSin(-1.21043)*85.44) + (position.x-cameraX),(GetCos(-1.21043)*85.44) + (position.y-cameraY));
				
				glVertex2f((GetSin(-3.89093)*205.183) + (position.x-cameraX),(GetCos(-3.89093)*205.183) + (position.y-cameraY));
				glVertex2f((GetSin(-2.65004)*170) + (position.x-cameraX),(GetCos(-2.65004)*170) + (position.y-cameraY));
				glVertex2f((GetSin(-4.3059)*152.315) + (position.x-cameraX),(GetCos(-4.3059)*152.315) + (position.y-cameraY));
				
				glVertex2f((GetSin(-3.62996)*170) + (position.x-cameraX),(GetCos(-3.62996)*170) + (position.y-cameraY));
				glVertex2f((GetSin(-4.3059)*152.315) + (position.x-cameraX),(GetCos(-4.3059)*152.315) + (position.y-cameraY));
				glVertex2f((GetSin(-1.21043)*85.44) + (position.x-cameraX),(GetCos(-1.21043)*85.44) + (position.y-cameraY));
			glEnd();
			glBegin(GL_LINE_STRIP);
glVertex2f((GetSin(angle+-2.59321)*269.258) + (position.x-cameraX),(GetCos(angle-2.59321)*269.258) + (position.y-cameraY));
glVertex2f((GetSin(angle+-2.88482)*237.697) + (position.x-cameraX),(GetCos(angle-2.88482)*237.697) + (position.y-cameraY));
glVertex2f((GetSin(angle+-2.03285)*67.082) + (position.x-cameraX),(GetCos(angle-2.03285)*67.082) + (position.y-cameraY));

glVertex2f((GetSin(angle+-2.03285)*67.082) + (position.x-cameraX),(GetCos(angle-2.03285)*67.082) + (position.y-cameraY));
glVertex2f((GetSin(angle+-4.24715)*67.082) + (position.x-cameraX),(GetCos(angle-4.24715)*67.082) + (position.y-cameraY));

glVertex2f((GetSin(angle+-3.39518)*237.697) + (position.x-cameraX),(GetCos(angle-3.39518)*237.697) + (position.y-cameraY));
glVertex2f((GetSin(angle+-3.68679)*269.258) + (position.x-cameraX),(GetCos(angle-3.68679)*269.258) + (position.y-cameraY));
glVertex2f((GetSin(angle+-4.4997)*143.178) + (position.x-cameraX),(GetCos(angle-4.4997)*143.178) + (position.y-cameraY));

glVertex2f((GetSin(angle+-5.17444)*67.082) + (position.x-cameraX),(GetCos(angle-5.17444)*67.082) + (position.y-cameraY));
glVertex2f((GetSin(angle+-1.10556)*67.082) + (position.x-cameraX),(GetCos(angle-1.10556)*67.082) + (position.y-cameraY));

glVertex2f((GetSin(angle+-1.7803)*143.178) + (position.x-cameraX),(GetCos(angle-1.7803)*143.178) + (position.y-cameraY));
glVertex2f((GetSin(angle+-2.59321)*269.258) + (position.x-cameraX),(GetCos(angle-2.59321)*269.258) + (position.y-cameraY));
			glEnd();


/*			
				//Left wing
				glVertex2f((GetSin(-45)*100) + (position.x-cameraX),(GetCos(-45)*150) + (position.y-cameraY));
				glVertex2f((GetSin(-10)*60) + (position.x-cameraX),(GetCos(-45)*150) + (position.y-cameraY));
				glVertex2f(-100 + (position.x-cameraX), -30 + (position.y-cameraY));
			
				glVertex2f( -60 + (position.x-cameraX),-150 + (position.y-cameraY));
				glVertex2f(-100 + (position.x-cameraX), -30 + (position.y-cameraY));
				glVertex2f( -60 + (position.x-cameraX),  30 + (position.y-cameraY));
			
				//Midsection
				glVertex2f( -60 + (position.x-cameraX), -30 + (position.y-cameraY));
				glVertex2f(  60 + (position.x-cameraX), -30 + (position.y-cameraY));
				glVertex2f( -60 + (position.x-cameraX),  30 + (position.y-cameraY));
			
				glVertex2f(  60 + (position.x-cameraX),  30 + (position.y-cameraY));
				glVertex2f(  60 + (position.x-cameraX), -30 + (position.y-cameraY));
				glVertex2f( -60 + (position.x-cameraX),  30 + (position.y-cameraY));
			
				//Right wing
				glVertex2f( 100 + (position.x-cameraX),-150 + (position.y-cameraY));
				glVertex2f(  60 + (position.x-cameraX),-150 + (position.y-cameraY));
				glVertex2f( 100 + (position.x-cameraX), -30 + (position.y-cameraY));
			
				glVertex2f(  60 + (position.x-cameraX),-150 + (position.y-cameraY));
				glVertex2f( 100 + (position.x-cameraX), -30 + (position.y-cameraY));
				glVertex2f(  60 + (position.x-cameraX),  30 + (position.y-cameraY));
*/
/*				//Starts from top left wing point
				glVertex2f(-100 + (position.x-cameraX),-150 + (position.y-cameraY));
				glVertex2f( -60 + (position.x-cameraX),-150 + (position.y-cameraY));
				glVertex2f( -60 + (position.x-cameraX), -30 + (position.y-cameraY));
			
//				glVertex2f( -60 + (position.x-cameraX), -30 + (position.y-cameraY));
				glVertex2f(  60 + (position.x-cameraX), -30 + (position.y-cameraY));
			
				glVertex2f(  60 + (position.x-cameraX),-150 + (position.y-cameraY));
				glVertex2f( 100 + (position.x-cameraX),-150 + (position.y-cameraY));
				glVertex2f( 100 + (position.x-cameraX), -30 + (position.y-cameraY));
			
				glVertex2f(  60 + (position.x-cameraX),  30 + (position.y-cameraY));
				glVertex2f( -60 + (position.x-cameraX),  30 + (position.y-cameraY));
			
				glVertex2f(-100 + (position.x-cameraX), -30 + (position.y-cameraY));
				glVertex2f(-100 + (position.x-cameraX),-150 + (position.y-cameraY));
*/
//		}
		
		if (turret)
			turret->Render(cameraX,cameraY);
	}
}

void CObject::SetHealth(int hp)
{
	health = hp;
	if (health < 0)
		health = 0;
	if (health > data->maxHealth)
		health = data->maxHealth;
}

void CObject::SetState(int s) { state = s; }
void CObject::SetTeam(int t) { team = t; }
void CObject::SetSpeed(float s) { speed = s; }
void CObject::SetPosition(Vector pos) {	position = pos; }
void CObject::SetPosition(float x, float y) { position = CreateVector(x,y); }
void CObject::SetAngle(float nAngle) { angle = nAngle; }

CObjectData* CObject::GetData() { return data; }
int CObject::GetHealth() { return health; }
int CObject::GetState() { return state; }
int CObject::GetTeam() { return team; }
float CObject::GetSpeed() { return speed; }
Vector CObject::GetPosition() { return position; }
float CObject::GetAngle() { return angle; }

CObject* g_firstObject = NULL;
CObject* playerObject = NULL;

//Just quickly places the object Obj at the beginning of the linked list
CObject* AddObject(CObjectData* data)
{
	if (!data)
		return NULL;
		
	CObject* newObj;
	newObj = new CObject(data);
	if (!newObj)
		return NULL;
	newObj->nextObj = g_firstObject;
	if (g_firstObject)
		g_firstObject->prevObj = newObj;
	g_firstObject = newObj;
	
	if (data->turret)
		newObj->turret = new CObject(data->turret);
	return newObj;
}

void DeleteObject(CObject* obj)
{
	if (!obj)
		return;

	if (playerObject == obj)
		playerObject = NULL;

	if (obj->prevObj)
		obj->prevObj->nextObj = obj->nextObj;
	else
		g_firstObject = obj->nextObj;
	if (obj->nextObj)
		obj->nextObj->prevObj = obj->prevObj;
	
	//Clear object from map
	if (g_Map)
		g_Map->DeleteObject(obj->GetPosition().x,obj->GetPosition().y,1,obj);

	//Clear anything targeting the deleted object
	CObject* cobj = g_firstObject;
	while (cobj)
	{
		if (cobj->target == obj)
			cobj->target = NULL;
		if (cobj->parent == obj)
		{
			cobj->parent = NULL;
			cobj->aiType = AI_TYPE_NORMAL;
		}
		if (cobj->turret)
			if (cobj->turret->target == obj)
				cobj->turret->target = NULL;
		cobj = cobj->nextObj;
	}

	CProjectile* cproj = g_firstProjectile;
	while (cproj)
	{
		if (cproj->target == obj)
			cproj->target = NULL;
		cproj = cproj->nextObj;
	}

	delete obj;
}

void DeleteAllObjects()
{
	CObject* curObj;
	CObject* tmpObj;
	curObj = g_firstObject;
	while (curObj)
	{
		tmpObj = curObj->nextObj;
		delete curObj;
		curObj = tmpObj;
	}
	g_firstObject = NULL;
	playerObject = NULL;
}

//This has a bit of variance in it if accurate = false so everyone doesn't swarm on one target
CObject* FindClosestEnemy(CObject* obj, bool accurate = false, float maxDist = -1)
{
	CObject* curObj = g_firstObject;
	CObject* closestObj = NULL;
	while (curObj)
	{
		if (curObj != obj && curObj->GetTeam() != obj->GetTeam())
		{
			float dist1 = Distance(obj->GetPosition(),curObj->GetPosition());
			if (dist1 <= maxDist || maxDist <= -1)
			{
				if (!closestObj)
					closestObj = curObj;
				else
				{
					float dist2 = Distance(obj->GetPosition(),closestObj->GetPosition());
					if (dist1 < dist2)
					{
						if (accurate)
							closestObj = curObj;
						else if ((rand()%2) == 0)
						{
							closestObj = curObj;
						}
					}
				}
			}
		}
		curObj = curObj->nextObj;
	}

	return closestObj;
}

CObject* FindClosestAlly(CObject* obj, bool accurate = true)
{
	CObject* curObj = g_firstObject;
	CObject* closestObj = NULL;
	while (curObj)
	{
		if (curObj != obj && curObj->GetTeam() == obj->GetTeam() && curObj->GetData()->type != OBJ_TYPE_REPAIRSHIP)
		{
			if (!closestObj)
				closestObj = curObj;
			else
			{
				if (Distance(obj->GetPosition(),curObj->GetPosition()) < Distance(obj->GetPosition(),closestObj->GetPosition()))
				{
					if (accurate)
						closestObj = curObj;
					else if ((rand()%2) == 0)
						closestObj = curObj;
				}
			}
		}
		curObj = curObj->nextObj;
	}
	return closestObj;
}

CObject* FindClosestWoundedAlly(CObject* obj, bool accurate = true)
{
	CObject* curObj = g_firstObject;
	CObject* closestObj = NULL;
	while (curObj)
	{
//		if (curObj->GetTeam() == obj->GetTeam() && curObj->GetData()->type != OBJ_TYPE_REPAIRSHIP && curObj->GetHealth() < curObj->GetData()->maxHealth)
		if (curObj->GetTeam() == obj->GetTeam() && curObj->GetHealth() < curObj->GetData()->maxHealth)
		{
			if (!closestObj)
				closestObj = curObj;
			else
			{
				if (Distance(obj->GetPosition(),curObj->GetPosition()) < Distance(obj->GetPosition(),closestObj->GetPosition()))
				{
					if (accurate)
						closestObj = curObj;
					else if ((rand()%2) == 0)
						closestObj = curObj;
				}
			}
		}
		curObj = curObj->nextObj;
	}
	return closestObj;
}

void FireFromObject(CObject* obj)
{
	if (!obj)
		return;

	obj->fireTime = obj->GetData()->projectile->fireDelay;
	if (obj->GetData()->type == OBJ_TYPE_FIGHTER)
	{
		CProjectile* proj;
		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle()-ToRadians(15))*15)+obj->GetPosition().x,(GetCos(obj->GetAngle()-ToRadians(15))*15)+obj->GetPosition().y);
		}
		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle()-ToRadians(-15))*15)+obj->GetPosition().x,(GetCos(obj->GetAngle()-ToRadians(-15))*15)+obj->GetPosition().y);
		}
	}
	else if (obj->GetData()->type == OBJ_TYPE_ADV_FIGHTER)
	{
		CProjectile* proj;
		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle()-ToRadians(12))*18)+obj->GetPosition().x,(GetCos(obj->GetAngle()-ToRadians(12))*18)+obj->GetPosition().y);
		}
		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle()-ToRadians(-12))*18)+obj->GetPosition().x,(GetCos(obj->GetAngle()-ToRadians(-12))*18)+obj->GetPosition().y);
		}
	}
	else if (obj->GetData()->type == OBJ_TYPE_ADV_BOMBER)
	{
		CProjectile* proj;
		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle()-ToRadians(45))*25)+obj->GetPosition().x,(GetCos(obj->GetAngle()-ToRadians(45))*25)+obj->GetPosition().y);
		}
		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle()-ToRadians(-45))*25)+obj->GetPosition().x,(GetCos(obj->GetAngle()-ToRadians(-45))*25)+obj->GetPosition().y);
		}

		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle()-ToRadians(15))*25)+obj->GetPosition().x,(GetCos(obj->GetAngle()-ToRadians(15))*25)+obj->GetPosition().y);
		}
		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle()-ToRadians(-15))*25)+obj->GetPosition().x,(GetCos(obj->GetAngle()-ToRadians(-15))*25)+obj->GetPosition().y);
		}
	}
	else if (obj->GetData()->type == OBJ_TYPE_BOMBER)
	{
		CProjectile* proj;
		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle()-ToRadians(20))*32)+obj->GetPosition().x,(GetCos(obj->GetAngle()-ToRadians(20))*32)+obj->GetPosition().y);
		}
		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle()-ToRadians(-20))*32)+obj->GetPosition().x,(GetCos(obj->GetAngle()-ToRadians(-20))*32)+obj->GetPosition().y);
		}
	}
	else if (obj->GetData()->type == OBJ_TYPE_REPAIRSHIP)
	{
		CProjectile* proj;
		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle())*32)+obj->GetPosition().x,(GetCos(obj->GetAngle())*32)+obj->GetPosition().y);
		}
/*		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle()-ToRadians(-20))*32)+obj->GetPosition().x,(GetCos(obj->GetAngle()-ToRadians(-20))*32)+obj->GetPosition().y);
		}*/
	}
	else if (obj->GetData()->type == OBJ_TYPE_TURRET || obj->GetData()->type == OBJ_TYPE_IMMOBILE_TURRET || obj->GetData()->type == OBJ_TYPE_REPAIRTURRET)
	{
		CProjectile* proj;
		proj = AddProjectile(obj->GetData()->projectile);
		if (proj)
		{
			proj->SetTeam(obj->GetTeam());
			proj->SetAngle(obj->GetAngle());
			proj->SetPosition((GetSin(obj->GetAngle())*15)+obj->GetPosition().x,(GetCos(obj->GetAngle())*15)+obj->GetPosition().y);

			if (proj->GetData()->lockonProjectile)
				proj->target = obj->target;
		}
	}

	if (g_soundList && obj->GetData()->projectile)
	{
		if (obj->GetData()->projectile->sound)
		{
			if (Distance(CreateVector(cameraPos.x+(g_screenWidth/2),cameraPos.y+(g_screenHeight/2)),obj->GetPosition()) <= g_screenWidth*1.5)
				g_soundList->PlaySound(obj->GetData()->projectile->sound);
		}
	}
}