/*
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.
*/

void ActionScreen_Cleanup()
{
	DeleteAllObjects();
	DeleteAllFactories();
	DeleteAllProjectiles();
	
	if (g_particles)
		g_particles->DeleteAllParticles();
	if (g_Map)
		g_Map->ResetMap();

	if (g_curMenuScreen == g_respawnScreen)
		g_curMenuScreen = NULL;
}

void UpdateActionScreen()
{
#ifdef STATISTICS_MODE
	Uint32 timeSpent;
	int timeDiff;
#endif
	if (!input_view_lastFrame && input_view)
	{
		view_mode++;
		if (view_mode > VIEW_MODE_COUNT)
			view_mode = 0;
		input_view_lastFrame = true;
	}
	else if (!input_view)
		input_view_lastFrame = false;

	if (g_respawnTime > 0)
	{
		g_respawnTime -= elapsedTime;
		if (g_respawnTime <= 0)
		{
/*
			g_curMenuScreen = g_respawnScreen;
			if (g_curMenuScreen)
				g_curMenuScreen->menuResult = 0;
*/
			CObject* obj = AddObject(FindObjectData(4));
			if (obj)
			{
				obj->SetState(OBJ_STATE_PLAYER);
				obj->SetPosition(g_respawnPoint);
				obj->SetTeam(1);
				playerObject = obj;
			}
		}
	}

	//If a menu is open, see if it's one of our menus
	if (g_curMenuScreen)
	{
		int menuResult = g_curMenuScreen->menuResult;
		if (menuResult != 0) //See if we have to do something with the menu
		{
			if (g_curMenuScreen == g_respawnScreen)
			{
				CObject* obj;
				obj = AddObject(FindObjectData(g_curMenuScreen->menuResult));
				if (obj)
				{
					obj->SetState(OBJ_STATE_PLAYER);
					obj->SetPosition(g_respawnPoint);
					obj->SetTeam(1);
					playerObject = obj;
				}
	
				g_curMenuScreen->menuResult = 0;
				g_curMenuScreen = NULL;
			}
			else if (g_curMenuScreen == g_victoryScreen)
			{
				g_curMenuScreen->menuResult = 0;
				g_curMenuScreen = NULL;

				if (menuResult == 1)
				{
					//Goto main menu
					ActionScreen_Cleanup();
					input_speed = input_turn = input_strafe = 0;
					input_fire = false;
					
					g_curMenuScreen = g_mainMenuScreen;
					g_curScreen = GAME_SCREEN_MENU;
				}
				else if (menuResult == 2)
				{
					ActionScreen_Cleanup();
					input_speed = input_turn = input_strafe = 0;
					input_fire = false;

					//Goto skirmish or next level
					if (g_level <= 0)
					{
						g_curMenuScreen = g_skirmishScreen;
						g_curScreen = GAME_SCREEN_MENU;
					}
					else if (g_level >= 5)
					{
						g_curMenuScreen = g_mainMenuScreen;
						g_curScreen = GAME_SCREEN_MENU;
					}
					else
					{
						g_curMenuScreen = g_introScreen;
						g_curScreen = GAME_SCREEN_MENU;
						g_introState = 5;
						g_level++;
						LoadBreifing(g_level);
					}
				}
			}
			else if (g_curMenuScreen == g_defeatScreen)
			{
				g_curMenuScreen->menuResult = 0;
				g_curMenuScreen = NULL;

				if (menuResult == 1)
				{
					//Goto main menu
					ActionScreen_Cleanup();
					input_speed = input_turn = input_strafe = 0;
					input_fire = false;
					
					g_curMenuScreen = g_mainMenuScreen;
					g_curScreen = GAME_SCREEN_MENU;
				}
				else if (menuResult == 2)
				{
					//Restart level
					ActionScreen_Cleanup();
					input_speed = input_turn = input_strafe = 0;
					input_fire = false;

					if (g_level > 0)
						LoadLevel(g_level);
					else
						ActionScreen_Start();
				}
			}
		}
	}
	
#ifdef STATISTICS_MODE
	{
	for (int i=0; i < NUM_TEAMS; i++)
		ObjectCount[i] = 0;
	}
#endif
	int capShipCount[NUM_TEAMS];
	{
	for (int i=0; i < NUM_TEAMS; i++)
		capShipCount[i] = 0;
	}
		

#ifdef ENABLE_PROFILING
	if (g_profile)
		g_profile->StartTimer(PROFILER_OBJ_UPDATES);
#endif

	CObject* obj = g_firstObject;
	while (obj)
	{
#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StartTimer(PROFILER_OBJ_UPDATE);
#endif
#ifdef STATISTICS_MODE
		if (obj->GetTeam() > 0 && obj->GetTeam() < NUM_TEAMS)
			ObjectCount[obj->GetTeam()]++;
#endif
		g_Map->DeleteObject(obj->GetPosition().x,obj->GetPosition().y,1,obj);
		
		//Player update
		if (obj->GetState() == OBJ_STATE_PLAYER && !paused)
		{
			obj->input_speed = input_speed;
			obj->input_strafe = input_strafe;
			obj->input_turn = input_turn;
			obj->input_fire = input_fire;
			
			int targX, targY;
			SDL_GetMouseState(&targX,&targY);
			Vector cameraPos = CreateVector(g_screenWidth/2,g_screenHeight/2);
			cameraPos = SubtractVectors(playerObject->GetPosition(),cameraPos);
			obj->SetAngle((atan2((targX+cameraPos.x)-obj->GetPosition().x,obj->GetPosition().y-(targY+cameraPos.y)) * -1) - (3.14));
		}
		
		//Physics/AI update
		if (obj->GetState() != OBJ_STATE_PLAYER)
		{
#ifdef ENABLE_PROFILING
			if (g_profile)
				g_profile->StartTimer(PROFILER_AIMIND_UPDATE);
#endif
			CalculateAIMove(obj);
#ifdef ENABLE_PROFILING
			if (g_profile)
				g_profile->StopTimer(PROFILER_AIMIND_UPDATE);
#endif
		}
		obj->Update(elapsedTime);
		
		//Smoke update
//#ifndef LIGHT_VERSION
		if (obj->GetHealth() <= obj->GetData()->maxHealth/2 && obj->smokeTime <= 0)
		{
			obj->smokeTime = obj->GetHealth() * 0.01;
			float radius = obj->GetData()->width/2;
			//Don't bother with making the smoke if it won't be in sight
			if (Distance(CreateVector(cameraPos.x+(g_screenWidth/2),cameraPos.y+(g_screenHeight/2)),obj->GetPosition()) <= ((g_screenWidth)+radius))
			{
				CParticleNode* particle = g_particles->AddParticle();
				if (particle)
				{
					particle->position = obj->GetPosition();
					particle->radius = radius;
					particle->speed = 50;
					particle->angle = obj->GetAngle() + 3.14;
					particle->lifeTime = 1.0;
					particle->colorR = 0.5;
					particle->colorG = 0.5;
					particle->colorB = 0.5;
					particle->colorA = 0.5;
				}
			}
		}
//#endif
		
		//Fire state update
		if (obj->input_fire && obj->fireTime <= 0 && obj->GetData()->projectile)
			FireFromObject(obj);
		if (obj->turret)
			if (obj->turret->input_fire && obj->turret->fireTime <= 0 && obj->turret->GetData()->projectile)
				FireFromObject(obj->turret);
		
		//Move on
		if (obj->GetHealth() <= 0)
		{
			//Make debris
			if (obj->GetData()->type == OBJ_TYPE_CAPITALSHIP)
			{
				if (obj->GetTeam() == 1)
				{
					MakeCapitalShipExplosion(obj->GetPosition(),200, 0,0.5,1.0,1.0);
					if (obj->GetData()->id == 200)
						AddMessage("-WARNING- Carrier lost",1);
					else if (obj->GetData()->id == 201)
						AddMessage("-WARNING- Destroyer lost",1);
					else if (obj->GetData()->id == 202)
						AddMessage("-WARNING- Turret Station lost",1);
					else if (obj->GetData()->id == 203)
						AddMessage("-WARNING- Space Station lost",1);
					else
						AddMessage("-WARNING- Capital ship lost",1);
				}
				else if (obj->GetTeam() == 2)
				{
					MakeCapitalShipExplosion(obj->GetPosition(),200, 1.0,0.5,0,1.0);
					if (obj->GetData()->id == 200)
						AddMessage("Enemy carrier eliminated",1);
					else if (obj->GetData()->id == 201)
						AddMessage("Enemy destroyer eliminated",1);
					else if (obj->GetData()->id == 202)
						AddMessage("Enemy turret station eliminated",1);
					else if (obj->GetData()->id == 203)
						AddMessage("Enemy Space Station eliminated",1);
					else
						AddMessage("Enemy capital ship eliminated",1);
				}
				else
					MakeCapitalShipExplosion(obj->GetPosition(),200, 1,1,1,1.0);
			}
			else
			{
				if (obj->GetTeam() == 1)
					MakeParticleExplosion(obj->GetPosition(),64, 0,0,1,1.0);
				else if (obj->GetTeam() == 2)
					MakeParticleExplosion(obj->GetPosition(),64, 1,0,0,1.0);
				else
					MakeParticleExplosion(obj->GetPosition(),64, 1,1,1,1.0);

				//If it's a character, find their factory so they can respawn
				if (obj->aiType == AI_TYPE_ASHLEY || obj->aiType == AI_TYPE_RODNEY)
				{
					CFactory* cfact = g_firstFactory;
					while (cfact)
					{
						if (cfact->aiType == obj->aiType)
						{
							cfact->spawnTime = 2.0;
							cfact = NULL; //There should only be 1 factory for each character, so we can save time and skip
							//the rest.
						}
						else
							cfact = cfact->nextObj;
					}
				}
			}
			
			//Clear any factories belonging to this object
			CFactory* cfact = g_firstFactory;
			while (cfact)
			{
				if (cfact->parent == obj)
				{
					if (cfact->aiType == AI_TYPE_ASHLEY)
						AddMessage("Ashley: Carrier's gone, I'm out.", 1);
					else if (cfact->aiType == AI_TYPE_RODNEY)
						AddMessage("Rodney: Good luck, buddy.", 1);
					CFactory* temp = cfact->nextObj;
					MakeParticleExplosion(cfact->position,70, 0,1,1,1.0);
					DeleteFactory(cfact);
					cfact = temp;
				}
				else
					cfact = cfact->nextObj;
			}
			
			if (obj == playerObject)
			{
				g_respawnTime = 2.0; //3
				playerObject = NULL;
			}
			
			//Delete
			CObject* nObj = obj->nextObj;
			DeleteObject(obj);
			obj = nObj;
		}
		else
		{
			if (obj->GetData()->type == OBJ_TYPE_CAPITALSHIP)
				capShipCount[obj->GetTeam()]++;
			g_Map->AddObject(obj->GetPosition().x,obj->GetPosition().y,1,obj);
			obj = obj->nextObj;
		}
#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StopTimer(PROFILER_OBJ_UPDATE);
#endif
	}
#ifdef ENABLE_PROFILING
	if (g_profile)
		g_profile->StopTimer(PROFILER_OBJ_UPDATES);
#endif

#ifdef ENABLE_PROFILING
	if (g_profile)
		g_profile->StartTimer(PROFILER_FACTORY_UPDATES);
#endif
	CFactory* curFact = g_firstFactory;
	while (curFact)
	{
		//If this factory has a parent for the object it spawns, there is no need to update it, it will update when parent respawns
		if (!curFact->aiParent)
		{
#ifdef ENABLE_PROFILING
			if (g_profile)
				g_profile->StartTimer(PROFILER_FACTORY_UPDATE);
#endif
			curFact->Update(elapsedTime);
			if (curFact->spawnTime <= 0)
			{
				CObject* obj = AddObject(FindObjectData(curFact->obj));
				if (obj)
				{
					obj->SetPosition(curFact->position);
					obj->SetTeam(curFact->team);
					obj->aiType = curFact->aiType;
					if (obj->turret)
						obj->turret->SetTeam(curFact->team);
				}
				//If not a normal AI, it probably has underlings, so let's go find them
				if (curFact->aiType != AI_TYPE_NORMAL)
				{
					CObject* hero = obj;
					CFactory* cfact = g_firstFactory;
					while (cfact)
					{
						if (cfact->aiParent == curFact)
						{
							obj = AddObject(FindObjectData(cfact->obj));
							if (obj)
							{
								obj->SetPosition(cfact->position);
								obj->SetTeam(cfact->team);
								obj->aiType = cfact->aiType;
								obj->parent = hero;
								if (obj->turret)
									obj->turret->SetTeam(cfact->team);
							}
						}
						cfact = cfact->nextObj;
					}
					curFact->spawnTime = 99999.0;
				}
				else
					curFact->spawnTime = 15.0;
			}
#ifdef ENABLE_PROFILING
			if (g_profile)
				g_profile->StopTimer(PROFILER_FACTORY_UPDATE);
#endif
		}
		curFact = curFact->nextObj;
	}
#ifdef ENABLE_PROFILING
	if (g_profile)
		g_profile->StopTimer(PROFILER_FACTORY_UPDATES);
#endif


	if (capShipCount[1] == 0 && !g_curMenuScreen)
	{
		g_curMenuScreen = g_defeatScreen;
		if (g_curMenuScreen)
			g_curMenuScreen->menuResult = 0;
	}
	else if (capShipCount[2] == 0 && !g_curMenuScreen)
	{
		g_curMenuScreen = g_victoryScreen;
		if (g_curMenuScreen)
			g_curMenuScreen->menuResult = 0;
	}
} 

void DrawActionScreen()
{
	if (g_numBackgrounds < 1 && starsLoaded)
		glCallList(stars);
	
	
//	CTextureListNode* cNode;
	if (input_mapView)
	{
		//Set camera position
		if (playerObject)
		{
			cameraPos.x = playerObject->GetPosition().x - g_screenWidth*TILE_SIZE*0.5;
			cameraPos.y = playerObject->GetPosition().y - g_screenHeight*TILE_SIZE*0.5;
		}

		glPointSize(2);
		glBegin(GL_POINTS);
		CObject* obj = g_firstObject;
		while (obj)
		{
			if (obj->GetTeam() == 1)
				glColor4f(0,0,1,1);
			else if (obj->GetTeam() == 2)
				glColor4f(1,0,0,1);
			else
				glColor4f(1,1,1,1);
			glVertex2f((obj->GetPosition().x-cameraPos.x)/TILE_SIZE,(obj->GetPosition().y-cameraPos.y)/TILE_SIZE);

			obj = obj->nextObj;
		}

		glColor4f(1,1,0,1);
		CProjectile* proj;
		proj = g_firstProjectile;
		while (proj)
		{
			if (proj->target)
			{
				CObject* target = (CObject*)proj->target;
				float targetAngle = ((atan2(target->GetPosition().x-proj->GetPosition().x,proj->GetPosition().y-target->GetPosition().y ) * -1) - (3.14));
	
				if (absf(GetNegativeAngle(GetProperAngle(proj->GetAngle()))-GetNegativeAngle(GetProperAngle(targetAngle))) <= proj->GetData()->turnRate)
				{
					proj->SetAngle(targetAngle);
					input_turn = 0;
				}
				else
				{
					if (targetAngle > proj->GetAngle())
						input_turn = -1;
					else
						input_turn = 1;
				}
			}
			else
				input_turn = 0;
			proj->Update(elapsedTime);
				
			bool killit = false;
			if (proj->lifeTime <= 0)
				killit = true;
			{
			for (int x=(proj->GetPosition().x/TILE_SIZE)-1; x <= (proj->GetPosition().x/TILE_SIZE)+1; x++)
			{
				for (int y=(proj->GetPosition().y/TILE_SIZE)-1; y <= (proj->GetPosition().y/TILE_SIZE)+1; y++)
				{
					CObjectList* list = g_Map->GetObjectList(x,y);
					CObjectListNode* cNode = NULL;
					if (list)
						cNode = list->firstNode;
					while (cNode)
					{
						obj = (CObject*)cNode->obj;
						if (obj)
						{
							if (PointInBoxCenter(obj->GetPosition(),obj->GetData()->width,obj->GetData()->height,proj->GetPosition()))
							{
								if (obj->GetTeam() != proj->GetTeam() || proj->GetData()->damage <= 0)
								{
									obj->SetHealth(obj->GetHealth() - proj->GetData()->damage);
	/*#ifndef LIGHT_VERSION
									if (proj->GetData()->type == PROJECTILE_TYPE_BULLET)
									{
										CParticleNode* particle = g_particles->AddParticle();
										if (particle)
										{
											particle->position = proj->GetPosition();
											particle->radius = 2;
											particle->angle = proj->GetAngle() + 3.1 + ((rand()%100)*0.01);
											particle->speed = 800.0;
											particle->lifeTime = 0.2;
											particle->colorR = proj->GetData()->colorR;
											particle->colorG = proj->GetData()->colorG;
											particle->colorB = proj->GetData()->colorB;
											particle->colorA = 0.5;
										}
									
										particle = g_particles->AddParticle();
										if (particle)
										{
											particle->position = proj->GetPosition();
											particle->radius = 2;
											particle->angle = proj->GetAngle() + 3.1 - ((rand()%100)*0.01);
											particle->speed = 800.0;
											particle->lifeTime = 0.2;
											particle->colorR = proj->GetData()->colorR;
											particle->colorG = proj->GetData()->colorG;
											particle->colorB = proj->GetData()->colorB;
											particle->colorA = 0.5;
										}
									}
	#endif*/
								}
								killit = true;
							}
						}
						cNode = cNode->nextNode;
					}
				}
			}
			}
			if (killit)
			{
				if (proj->GetData()->type == PROJECTILE_TYPE_ROCKET || proj->GetData()->type == PROJECTILE_TYPE_SMALLROCKET)
					MakeParticleExplosion(proj->GetPosition(),64, 1.0,0.5,0,1.0);
				else if (proj->GetData()->type == PROJECTILE_TYPE_FLAK)
					MakeParticleExplosion(proj->GetPosition(),64, 0.5,0.5,0.5,1.0);
				
				CProjectile* cProj = proj->nextObj;
				DeleteProjectile(proj);
				proj = cProj;
			}
			else
			{
				if (proj->GetData()->type == PROJECTILE_TYPE_ROCKET)
				{
					//Smoke update
					if (proj->smokeTime <= 0)
					{
	//#ifdef LIGHT_VERSION
	//					proj->smokeTime = 0.5;
	//#else
						proj->smokeTime = 0.05;
	//					proj->smokeTime = 0.01;
	//#endif
						if (Distance(CreateVector(cameraPos.x+(g_screenWidth/2),cameraPos.y+(g_screenHeight/2)),proj->GetPosition()) <= ((g_screenWidth)+4))
						{
							CParticleNode* particle = g_particles->AddParticle();
							if (particle)
							{
								particle->position = proj->GetPosition();
								particle->radius = 4;
								particle->speed = 50;
								particle->angle = proj->GetAngle() + 3.14;
								particle->lifeTime = 1.0;
								particle->colorR = 0.5;
								particle->colorG = 0.5;
								particle->colorB = 0.5;
								particle->colorA = 0.5;
							}
						}
					}
				}
				glVertex2f((proj->GetPosition().x-cameraPos.x)/TILE_SIZE,(proj->GetPosition().y-cameraPos.y)/TILE_SIZE);
				proj = proj->nextObj;
			}
		}
	#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StopTimer(PROFILER_PROJ_RENDERS);
	#endif
	
	#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StartTimer(PROFILER_FACTORY_RENDERS);
	#endif
		CFactory* fact;
		fact = g_firstFactory;
		while (fact)
		{
			if (fact->team == 1)
				glColor4f(0,0,1,1);
			else if (fact->team == 2)
				glColor4f(1,0,0,1);
			else
				glColor4f(1,1,1,1);

			glVertex2f((fact->position.x-cameraPos.x)/TILE_SIZE,(fact->position.y-cameraPos.y)/TILE_SIZE);
	
			fact = fact->nextObj;
		}
	#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StopTimer(PROFILER_FACTORY_RENDERS);
	#endif

		glEnd();
		glPointSize(1);

		//Draw HUD & text
		if (g_MainFont)
		{
			char text[MAX_STRING_SIZE];
			if (playerObject)
			{
				bool up = true;
				float space = 20;
				int points = (playerObject->GetData()->maxHealth/10) - ((playerObject->GetData()->maxHealth/10)-(playerObject->GetHealth()/10));
				int maxHP = playerObject->GetData()->maxHealth;
				
				glColor4f(0,0.0,1.0,0.5);
				glBegin(GL_QUADS);
					glVertex2f(0,0);
					glVertex2f(6,0);
					glVertex2f(6,15);
					glVertex2f(0,15);
					
					glVertex2f(6,0);
					glVertex2f(6+maxHP*2,0);
					glVertex2f(6+maxHP*2,5);
					glVertex2f(6,5);
				
					glVertex2f(6+maxHP*2,0);
					glVertex2f(12+maxHP*2,0);
					glVertex2f(12+maxHP*2,15);
					glVertex2f(6+maxHP*2,15);
				
					glVertex2f(6,10);
					glVertex2f(6+maxHP*2,10);
					glVertex2f(6+maxHP*2,15);
					glVertex2f(6,15);
				glEnd();
				
				glBegin(GL_LINES);
					glVertex2f(0,0);
					glVertex2f(0,15);
					glVertex2f(0,15);
					glVertex2f(12+maxHP*2,15);
					glVertex2f(12+maxHP*2,15);
					glVertex2f(12+maxHP*2,0);
					glVertex2f(12+maxHP*2,0);
					glVertex2f(0,0);
				
					glVertex2f(6,5);
					glVertex2f(6,10);
					
					glVertex2f(6,10);
					glVertex2f(6+maxHP*2,10);
					
					glVertex2f(6+maxHP*2,10);
					glVertex2f(6+maxHP*2,5);
				
					glVertex2f(6+maxHP*2,5);
					glVertex2f(6,5);
				glEnd();
				
				{
				for (int i=0; i < 3; i++)
				{
					glColor4f(0,1.0-(i*0.2),0,(i*0.4));
					glBegin(GL_LINES);
						glVertex2f(6,8-i); //6,16
						glVertex2f(6+playerObject->GetHealth()*2,8-i);
						glVertex2f(6,8+i);
						glVertex2f(6+playerObject->GetHealth()*2,8+i);
					glEnd();
				}
				}
	
				g_MainFont->Enable();
				
				//Quickly label characeters
				obj = g_firstObject;
				while (obj)
				{
					float x = (obj->GetPosition().x-obj->GetData()->radius-cameraPos.x)/TILE_SIZE;
					float y = (obj->GetPosition().y-obj->GetData()->radius-cameraPos.y)/TILE_SIZE -FONT_SIZE_Y;
					if (obj->aiType == AI_TYPE_ASHLEY)
						g_MainFont->RenderText(x-((FONT_SIZE_X+1)*3),y,1,1,"ashley");
					else if (obj->aiType == AI_TYPE_RODNEY)
						g_MainFont->RenderText(x-((FONT_SIZE_X+1)*3),y,1,1,"rodney");
					obj = obj->nextObj;
				}
				for (int i=0; i < NUM_MESSAGES; i++)
					g_MainFont->RenderText(0,g_screenHeight-(FONT_SIZE_Y+2)*(i+1),1,1,Messages[i].text); //size=16
	
	#ifdef STATISTICS_MODE
				sprintf(text, "Allies: %d\nEnemies: %d\nTotal: %d", ObjectCount[1],ObjectCount[2], ObjectCount[1] + ObjectCount[2]);
				g_MainFont->RenderText(RADAR_RADIUS*2 + 2, 17,1,1,text); //size=16
	#endif
				g_MainFont->Disable();
			}
		}
	}
	else
	{
		//Set camera position
		if (playerObject)
			cameraPos = SubtractVectors(playerObject->GetPosition(),CreateVector(g_screenWidth/2,g_screenHeight/2));

	#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StartTimer(PROFILER_OBJ_RENDERS);
	#endif
		//Draw game objects
		CObject* obj;
		obj = g_firstObject;
		while (obj)
		{
			obj->Render(cameraPos.x,cameraPos.y);
			obj = obj->nextObj;
		}
	#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StopTimer(PROFILER_OBJ_RENDERS);
	#endif
		
	#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StartTimer(PROFILER_PROJ_RENDERS);
	#endif
		CProjectile* proj;
		proj = g_firstProjectile;
		while (proj)
		{
			if (proj->target)
			{
				CObject* target = (CObject*)proj->target;
				float targetAngle = ((atan2(target->GetPosition().x-proj->GetPosition().x,proj->GetPosition().y-target->GetPosition().y ) * -1) - (3.14));
	
				if (absf(GetNegativeAngle(GetProperAngle(proj->GetAngle()))-GetNegativeAngle(GetProperAngle(targetAngle))) <= proj->GetData()->turnRate)
				{
					proj->SetAngle(targetAngle);
					input_turn = 0;
				}
				else
				{
					if (targetAngle > proj->GetAngle())
						input_turn = -1;
					else
						input_turn = 1;
				}
			}
			else
				input_turn = 0;
			proj->Update(elapsedTime);
				
			bool killit = false;
			if (proj->lifeTime <= 0)
				killit = true;
			{
			for (int x=(proj->GetPosition().x/TILE_SIZE)-1; x <= (proj->GetPosition().x/TILE_SIZE)+1; x++)
			{
				for (int y=(proj->GetPosition().y/TILE_SIZE)-1; y <= (proj->GetPosition().y/TILE_SIZE)+1; y++)
				{
					CObjectList* list = g_Map->GetObjectList(x,y);
					CObjectListNode* cNode = NULL;
					if (list)
						cNode = list->firstNode;
					while (cNode)
					{
						obj = (CObject*)cNode->obj;
						if (obj)
						{
							if (PointInBoxCenter(obj->GetPosition(),obj->GetData()->width,obj->GetData()->height,proj->GetPosition()))
							{
								if (obj->GetTeam() != proj->GetTeam() || proj->GetData()->damage <= 0)
								{
									obj->SetHealth(obj->GetHealth() - proj->GetData()->damage);
	/*#ifndef LIGHT_VERSION
									if (proj->GetData()->type == PROJECTILE_TYPE_BULLET)
									{
										CParticleNode* particle = g_particles->AddParticle();
										if (particle)
										{
											particle->position = proj->GetPosition();
											particle->radius = 2;
											particle->angle = proj->GetAngle() + 3.1 + ((rand()%100)*0.01);
											particle->speed = 800.0;
											particle->lifeTime = 0.2;
											particle->colorR = proj->GetData()->colorR;
											particle->colorG = proj->GetData()->colorG;
											particle->colorB = proj->GetData()->colorB;
											particle->colorA = 0.5;
										}
									
										particle = g_particles->AddParticle();
										if (particle)
										{
											particle->position = proj->GetPosition();
											particle->radius = 2;
											particle->angle = proj->GetAngle() + 3.1 - ((rand()%100)*0.01);
											particle->speed = 800.0;
											particle->lifeTime = 0.2;
											particle->colorR = proj->GetData()->colorR;
											particle->colorG = proj->GetData()->colorG;
											particle->colorB = proj->GetData()->colorB;
											particle->colorA = 0.5;
										}
									}
	#endif*/
								}
								killit = true;
							}
						}
						cNode = cNode->nextNode;
					}
				}
			}
			}
			if (killit)
			{
				if (proj->GetData()->type == PROJECTILE_TYPE_ROCKET || proj->GetData()->type == PROJECTILE_TYPE_SMALLROCKET)
					MakeParticleExplosion(proj->GetPosition(),64, 1.0,0.5,0,1.0);
				else if (proj->GetData()->type == PROJECTILE_TYPE_FLAK)
					MakeParticleExplosion(proj->GetPosition(),64, 0.5,0.5,0.5,1.0);
				
				CProjectile* cProj = proj->nextObj;
				DeleteProjectile(proj);
				proj = cProj;
			}
			else
			{
				if (proj->GetData()->type == PROJECTILE_TYPE_ROCKET)
				{
					//Smoke update
					if (proj->smokeTime <= 0)
					{
	//#ifdef LIGHT_VERSION
	//					proj->smokeTime = 0.5;
	//#else
						proj->smokeTime = 0.05;
	//					proj->smokeTime = 0.01;
	//#endif
						if (Distance(CreateVector(cameraPos.x+(g_screenWidth/2),cameraPos.y+(g_screenHeight/2)),proj->GetPosition()) <= ((g_screenWidth)+4))
						{
							CParticleNode* particle = g_particles->AddParticle();
							if (particle)
							{
								particle->position = proj->GetPosition();
								particle->radius = 4;
								particle->speed = 50;
								particle->angle = proj->GetAngle() + 3.14;
								particle->lifeTime = 1.0;
								particle->colorR = 0.5;
								particle->colorG = 0.5;
								particle->colorB = 0.5;
								particle->colorA = 0.5;
							}
						}
					}
				}
				proj->Render(cameraPos.x,cameraPos.y);
				proj = proj->nextObj;
			}
		}
	#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StopTimer(PROFILER_PROJ_RENDERS);
	#endif
	
	#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StartTimer(PROFILER_FACTORY_RENDERS);
	#endif
		CFactory* fact;
		fact = g_firstFactory;
		while (fact)
		{
			fact->Render(cameraPos.x,cameraPos.y);
			fact = fact->nextObj;
		}
	#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StopTimer(PROFILER_FACTORY_RENDERS);
	#endif
		
	#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StartTimer(PROFILER_PARTICLE_UPDATES);
	#endif
	//	glBlendFunc(GL_ONE,GL_ONE); //Additive blending for particles
	
		//Untextured particles first
		g_particles->Render(cameraPos.x,cameraPos.y,elapsedTime,false);
		//Textured particles next
		g_particles->Render(cameraPos.x,cameraPos.y,elapsedTime,true);
	#ifdef ENABLE_PROFILING
		if (g_profile)
			g_profile->StartTimer(PROFILER_PARTICLE_UPDATES);
	#endif
	
	//	glBlendFunc(GL_SRC_ALPHA,GL_ONE);
	
		//Draw RADAR
		float x,y,radarX,radarY;
		radarX = (RADAR_RADIUS);
		radarY = 16+RADAR_RADIUS;
		if (playerObject)
		{
	/*		glDisable(GL_BLEND);
			glBegin(GL_QUADS);
				glColor4f(0,0,0,1);
				glVertex2f(0,g_screenHeight-RADAR_RADIUS*2);
				glVertex2f(RADAR_RADIUS*2,g_screenHeight-RADAR_RADIUS*2);
				glVertex2f(RADAR_RADIUS*2,g_screenHeight);
				glVertex2f(0,g_screenHeight);
			glEnd();
			glEnable(GL_BLEND);*/
	
			if (radarLoaded)
				glCallList(radar);
			glPointSize(2);
			glBegin(GL_POINTS);
				obj = g_firstObject;
				while (obj)
				{
					if (obj->GetState() == OBJ_STATE_PLAYER)
						glColor4f(1,1,0,0.8);
					else if (obj->GetTeam() == 1)
						glColor4f(0,0,1,0.8);
					else if (obj->GetTeam() == 2)
						glColor4f(1,0,0,0.8);
		/*			if (obj->GetState() == OBJ_STATE_PLAYER)
					{
						x = radarX;
						y = radarY;
						glVertex2f(x,y);
					}
					else
		*/			{
		//				x = ((obj->GetPosition().x/16) - (cameraPos.x));// + RADAR_RADIUS/2;
		//				y = ((obj->GetPosition().y/16) - (cameraPos.y));// + (g_screenHeight-(RADAR_RADIUS*1.5));
		//				Currently used calcs:
		//				x = (obj->GetPosition().x/16) - (cameraPos.x/16) + RADAR_RADIUS/1.37;
		//				y = (obj->GetPosition().y/16) - (cameraPos.y/16) + (g_screenHeight-(RADAR_RADIUS*1.2));
						x = ((obj->GetPosition().x - playerObject->GetPosition().x)/16) + (RADAR_RADIUS);
						y = ((obj->GetPosition().y - playerObject->GetPosition().y)/16) + (16+RADAR_RADIUS);
						
						if (Distance(x,y,radarX,radarY) < RADAR_RADIUS)
							glVertex2f(x,y);
					}
					
					obj = obj->nextObj;
				}
			glEnd();
			glPointSize(1);
		}
		
		//Draw HUD & text
		if (g_MainFont)
		{
			char text[MAX_STRING_SIZE];
			if (playerObject)
			{
				bool up = true;
				float space = 20;
				int points = (playerObject->GetData()->maxHealth/10) - ((playerObject->GetData()->maxHealth/10)-(playerObject->GetHealth()/10));
				int maxHP = playerObject->GetData()->maxHealth;
				
				glColor4f(0,0.0,1.0,0.5);
				glBegin(GL_QUADS);
					glVertex2f(0,0);
					glVertex2f(6,0);
					glVertex2f(6,15);
					glVertex2f(0,15);
					
					glVertex2f(6,0);
					glVertex2f(6+maxHP*2,0);
					glVertex2f(6+maxHP*2,5);
					glVertex2f(6,5);
				
					glVertex2f(6+maxHP*2,0);
					glVertex2f(12+maxHP*2,0);
					glVertex2f(12+maxHP*2,15);
					glVertex2f(6+maxHP*2,15);
				
					glVertex2f(6,10);
					glVertex2f(6+maxHP*2,10);
					glVertex2f(6+maxHP*2,15);
					glVertex2f(6,15);
				glEnd();
				
				glBegin(GL_LINES);
					glVertex2f(0,0);
					glVertex2f(0,15);
					glVertex2f(0,15);
					glVertex2f(12+maxHP*2,15);
					glVertex2f(12+maxHP*2,15);
					glVertex2f(12+maxHP*2,0);
					glVertex2f(12+maxHP*2,0);
					glVertex2f(0,0);
				
					glVertex2f(6,5);
					glVertex2f(6,10);
					
					glVertex2f(6,10);
					glVertex2f(6+maxHP*2,10);
					
					glVertex2f(6+maxHP*2,10);
					glVertex2f(6+maxHP*2,5);
				
					glVertex2f(6+maxHP*2,5);
					glVertex2f(6,5);
				glEnd();
				
				{
				for (int i=0; i < 3; i++)
				{
					glColor4f(0,1.0-(i*0.2),0,(i*0.4));
					glBegin(GL_LINES);
						glVertex2f(6,8-i); //6,16
						glVertex2f(6+playerObject->GetHealth()*2,8-i);
						glVertex2f(6,8+i);
						glVertex2f(6+playerObject->GetHealth()*2,8+i);
					glEnd();
				}
				}
	
				g_MainFont->Enable();
				
				//Quickly label characeters
				obj = g_firstObject;
				while (obj)
				{
					float x = obj->GetPosition().x-obj->GetData()->radius-cameraPos.x;
					float y = obj->GetPosition().y-obj->GetData()->radius-FONT_SIZE_Y-cameraPos.y;
					if (obj->aiType == AI_TYPE_ASHLEY)
						g_MainFont->RenderText(x-((FONT_SIZE_X+1)*3),y,1,1,"ashley");
					else if (obj->aiType == AI_TYPE_RODNEY)
						g_MainFont->RenderText(x-((FONT_SIZE_X+1)*3),y,1,1,"rodney");
					obj = obj->nextObj;
				}
				for (int i=0; i < NUM_MESSAGES; i++)
					g_MainFont->RenderText(0,g_screenHeight-(FONT_SIZE_Y+2)*(i+1),1,1,Messages[i].text); //size=16
	
	#ifdef STATISTICS_MODE
				sprintf(text, "Allies: %d\nEnemies: %d\nTotal: %d", ObjectCount[1],ObjectCount[2], ObjectCount[1] + ObjectCount[2]);
				g_MainFont->RenderText(RADAR_RADIUS*2 + 2, 17,1,1,text); //size=16
	#endif
				g_MainFont->Disable();
			}
		}
	}
	
	if (g_numBackgrounds > 0)
	{
		glColor4f(1,1,1,1);
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D,g_curBackground->GetTextureId());
		glBegin(GL_TRIANGLE_STRIP);
			glTexCoord2f(0,0); glVertex2f(0,0);
			glTexCoord2f(1,0); glVertex2f(g_screenWidth,0);
			glTexCoord2f(0,1); glVertex2f(0,g_screenHeight);
			glTexCoord2f(1,1); glVertex2f(g_screenWidth,g_screenHeight);
		glEnd();
		glDisable(GL_TEXTURE_2D);
	}
}