#include "stdafx.h"
#include "CellWarsGameManager.h"

#include "Background.h"
#include "CellWarsMTManager.h"
#include "Util\MathUtil.h"
#include "Infrastructure\Camera.h"
#include "StartScreen.h"
#include "EndScreen.h"
#include "HelpScreen.h"

#include "Macrophage.h"
#include "Cell.h"
#include "Bacterium.h"

#include <algorithm>

ScreenOverlay::ScreenOverlay(){}

void ScreenOverlay::Start(){}

void ScreenOverlay::Stop(){}

void ScreenOverlay::Update(float dt) {}
void ScreenOverlay::Render() {}

CellWarsGameManager* CellWarsGameManager::s_CellWarsGameManager = NULL;

const float CellWarsGameManager::TIME_BETWEEN_MACROPHAGE_WAVES = 30;
const float CellWarsGameManager::MIN_TIME_BETWEEN_MACROPHAGE_WAVES = 1;
const float CellWarsGameManager::TIME_BETWEEN_MACROPHAGE_WAVES_DECREASE_FACTOR = 0.10f;
const float CellWarsGameManager::MACROPHAGE_WAVE_INCREASE_FACTOR = 0.34f;
const float CellWarsGameManager::TIME_BETWEEN_CELLS = 10;
const int CellWarsGameManager::MAX_NUM_MACROPHAGES = 100;
const int CellWarsGameManager::MAX_NUM_CELLS = 20;
const int CellWarsGameManager::MAX_NUM_BACTERIA = 50;
const int CellWarsGameManager::NUM_STARTING_BACTERIA = 3;
const float CellWarsGameManager::FADE_IN_OUT_TIME = 1;

const float CellWarsGameManager::SURVIVAL_TIME = 5 * 60;
const float CellWarsGameManager::INVASION_TIME = 5;

CellWarsGameManager::CellWarsGameManager() : 
currentGameState(GameStates::SplashScreen), macrophages(new std::list<Macrophage*>()),
	bacteria(new std::list<Bacterium*>()), cells(new std::list<Cell*>()),
	replications(0), upgrades(0), killedMacrophages(0), killedCells(0), playTime(0),
	multiTouchManager(new CellWarsMTManager()), startScreen(NULL), endScreen(NULL), helpScreen(NULL), 
	numMacrophageWaves(0), timeSinceLastMacrophages(0), mtDrawing(new MultitouchDrawing(multiTouchManager)),
	splashScreen(new Actor()), fadeScreen(new Actor()), background(new Background()), mainVolume(0.5f), 
	backgroundMusicSample(NULL), backgroundMusicSound(NULL), replicateSound(NULL), upgradeSound(NULL), 
	bacteriaInvasion(new ParticleActor()), numSpawnedBacteria(0), 
	numSpawnedCells(0), numCellWaves(0), timeSinceLastCell(0), numSpawnedMacrophages(0), timeSinceMusicFadeOutStart(0), 
	leftSide(new Actor()), rightSide(new Actor()), timeSinceInvasionStarted(0), timeSinceLastDestroyedMacrophage(0),
	timeSinceStartup(0), timeSinceLastInput(0), gotInputThisFrame(false)
{
	initAssets();

	Vector2 screenSizeInAngelCoords(theCamera.GetWorldMaxVertex() - theCamera.GetWorldMinVertex());

	fadeScreen->SetColor(1,1,1,1);
	fadeScreen->SetSprite("Resources/Images/fadescreen.png");
	fadeScreen->SetSize(screenSizeInAngelCoords);
	theWorld.Add(fadeScreen, LayerEnum::ScreenOverlay);

	splashScreen->SetName("splashScreen");
	splashScreen->SetColor(1,1,1,0);
	splashScreen->ChangeAlphaTo(1, FADE_IN_OUT_TIME * 3, true, "splashScreenFadeInComplete");
	splashScreen->SetSprite("Resources/Images/titleScreen.png");
	splashScreen->SetSize(screenSizeInAngelCoords);
	theWorld.Add(splashScreen, LayerEnum::SplashScreen);

	theWorld.Add(mtDrawing, LayerEnum::DebugDrawing);
	
	leftSide->SetColor(1, 1, 1, 1);
	leftSide->SetSprite("Resources/Images/left_side.png");
	leftSide->SetSize(screenSizeInAngelCoords.X * 0.02f, 0);
	leftSide->SetPosition(theCamera.GetWorldMinVertex().X + leftSide->GetSize().X * 0.5f, 0);
	theWorld.Add(leftSide, LayerEnum::TimeBars);
	
	rightSide->SetColor(1, 1, 1, 1);
	rightSide->SetSprite("Resources/Images/right_side.png");
	rightSide->SetSize(screenSizeInAngelCoords.X * 0.02f, 0);
	rightSide->SetPosition(theCamera.GetWorldMaxVertex().X - rightSide->GetSize().X * 0.5f, 0);
	theWorld.Add(rightSide, LayerEnum::TimeBars);
	
	bacteriaInvasion->SetPosition(theCamera.GetWorldMinVertex().X - 15, 0);
	bacteriaInvasion->SetRotation(0);
	bacteriaInvasion->SetColor(1.0f, 1.0f, 1.0f);
	bacteriaInvasion->SetSize(Vector2(3));
	bacteriaInvasion->SetSprite("Resources/Images/bacterium.png");
	bacteriaInvasion->SetMaxParticles(1000);
	deActivateBacteriaInvasion();
	bacteriaInvasion->SetParticleLifetime(12);
	bacteriaInvasion->SetSpread(MathUtil::Pi * 0.25f);
	bacteriaInvasion->SetSpeedRange(5.0f, 10.0f);
	bacteriaInvasion->SetGravity(Vector2(0));
	theWorld.Add(bacteriaInvasion);
	
	theSwitchboard.SubscribeTo(this, "startScreenFadeoutComplete");
	theSwitchboard.SubscribeTo(this, "endScreenFadeoutComplete");
	theSwitchboard.SubscribeTo(this, "helpScreenFadeoutComplete");
	theSwitchboard.SubscribeTo(this, "splashScreenFadeInComplete");
	//theSwitchboard.SubscribeTo(this, "splashScreenWaitComplete");
	theSwitchboard.SubscribeTo(this, "splashScreenFadeOutComplete");
}

CellWarsGameManager::~CellWarsGameManager()
{
	theSwitchboard.UnsubscribeFrom(this, "startScreenFadeoutComplete");
	theSwitchboard.UnsubscribeFrom(this, "endScreenFadeoutComplete");
	theSwitchboard.UnsubscribeFrom(this, "helpScreenFadeoutComplete");
	theSwitchboard.UnsubscribeFrom(this, "splashScreenFadeInComplete");
	//theSwitchboard.UnsubscribeFrom(this, "splashScreenWaitComplete");
	theSwitchboard.UnsubscribeFrom(this, "splashScreenFadeOutComplete");
}

CellWarsGameManager& CellWarsGameManager::GetInstance()
{
	if (s_CellWarsGameManager == NULL)
	{
		s_CellWarsGameManager = new CellWarsGameManager();
	}
	return *s_CellWarsGameManager;
}

void CellWarsGameManager::addMacrophageToGame(Macrophage* m)
{
	macrophages->push_back(m);
	++numSpawnedMacrophages;
}

void CellWarsGameManager::addCellToGame(Cell* c)
{
	cells->push_back(c);
	++numSpawnedCells;
}

void CellWarsGameManager::addBacteriumToGame(Bacterium* b)
{
	bacteria->push_back(b);
	++numSpawnedBacteria;
}

void CellWarsGameManager::removeMacrophageFromGame(Macrophage* m)
{
	std::list<Macrophage*>::iterator it;
	it = std::find(macrophages->begin(), macrophages->end(), m);
	if (it != macrophages->end())
		macrophages->erase(it);
}

void CellWarsGameManager::removeCellFromGame(Cell* c)
{
	std::list<Cell*>::iterator it;
	it = std::find(cells->begin(), cells->end(), c);
	if (it != cells->end())
		cells->erase(it);
}

void CellWarsGameManager::removeBacteriumFromGame(Bacterium* b)
{
	std::list<Bacterium*>::iterator it;
	it = std::find(bacteria->begin(), bacteria->end(), b);
	if (it != bacteria->end())
		bacteria->erase(it);
}

Cell* CellWarsGameManager::getNearestCell(Vector2 fromPos)
{
	float shortestDistance = (theCamera.GetWorldMaxVertex() - theCamera.GetWorldMinVertex()).Length();
	Cell* nearestCell = NULL;

	std::list<Cell*>::iterator it = cells->begin();
	while (it != cells->end())
	{
		float thisDistance = ((*it)->GetPosition() - fromPos).Length();
		if (!((*it)->IsDestroyed()) && thisDistance < shortestDistance)
		{
			shortestDistance = thisDistance;
			nearestCell = (*it);
		}
		++it;
	}

	return nearestCell;
}

Macrophage* CellWarsGameManager::getNearestMacrophage(Vector2 fromPos)
{
	float shortestDistance = (theCamera.GetWorldMaxVertex() - theCamera.GetWorldMinVertex()).Length();
	Macrophage* nearestMacrophage = NULL;

	std::list<Macrophage*>::iterator it = macrophages->begin();
	while (it != macrophages->end())
	{
		float thisDistance = ((*it)->GetPosition() - fromPos).Length();
		if (!((*it)->IsDestroyed()) && thisDistance < shortestDistance)
		{
			shortestDistance = thisDistance;
			nearestMacrophage = (*it);
		}
		++it;
	}

	return nearestMacrophage;
}

Bacterium* CellWarsGameManager::getNearestBacterium(Vector2 fromPos)
{
	float shortestDistance = (theCamera.GetWorldMaxVertex() - theCamera.GetWorldMinVertex()).Length();
	Bacterium* nearestBacterium = NULL;

	std::list<Bacterium*>::iterator it = bacteria->begin();
	while (it != bacteria->end())
	{
		float thisDistance = ((*it)->GetPosition() - fromPos).Length();
		if (!((*it)->IsDestroyed()) && thisDistance < shortestDistance)
		{
			shortestDistance = thisDistance;
			nearestBacterium = (*it);
		}
		++it;
	}

	return nearestBacterium;
}

Cell* CellWarsGameManager::getNearestCellFromActor(Actor* fromThis)
{
	float shortestDistance = (theCamera.GetWorldMaxVertex() - theCamera.GetWorldMinVertex()).Length();
	Cell* nearestCell = NULL;

	std::list<Cell*>::iterator it = cells->begin();
	while (it != cells->end())
	{
		float thisDistance = ((*it)->GetPosition() - fromThis->GetPosition()).Length();
		if (!((*it)->IsDestroyed()) && thisDistance < shortestDistance && 
			fromThis != (*it))
		{
			shortestDistance = thisDistance;
			nearestCell = (*it);
		}
		++it;
	}

	return nearestCell;
}

Macrophage* CellWarsGameManager::getNearestMacrophageActor(Actor* fromThis)
{
	float shortestDistance = (theCamera.GetWorldMaxVertex() - theCamera.GetWorldMinVertex()).Length();
	Macrophage* nearestMacrophage = NULL;

	std::list<Macrophage*>::iterator it = macrophages->begin();
	while (it != macrophages->end())
	{
		float thisDistance = ((*it)->GetPosition() - fromThis->GetPosition()).Length();
		if (!((*it)->IsDestroyed()) && thisDistance < shortestDistance && 
			fromThis != (*it))
		{
			shortestDistance = thisDistance;
			nearestMacrophage = (*it);
		}
		++it;
	}

	return nearestMacrophage;
}

Bacterium* CellWarsGameManager::getNearestBacteriumActor(Actor* fromThis)
{
	float shortestDistance = (theCamera.GetWorldMaxVertex() - theCamera.GetWorldMinVertex()).Length();
	Bacterium* nearestBacterium = NULL;

	std::list<Bacterium*>::iterator it = bacteria->begin();
	while (it != bacteria->end())
	{
		float thisDistance = ((*it)->GetPosition() - fromThis->GetPosition()).Length();
		if (!((*it)->IsDestroyed()) && thisDistance < shortestDistance && 
			fromThis != (*it))
		{
			shortestDistance = thisDistance;
			nearestBacterium = (*it);
		}
		++it;
	}

	return nearestBacterium;
}

void CellWarsGameManager::ReceiveMessage(Message* message)
{
	if (message->GetMessageName() == "startScreenFadeoutComplete")
	{
		if (startScreen)
		{
			startScreen->Destroy();
			startScreen = NULL;
		}
	}
	if (message->GetMessageName() == "endScreenFadeoutComplete")
	{
		if (endScreen)
		{
			endScreen->Destroy();
			endScreen = NULL;
		}
	}
	if (message->GetMessageName() == "helpScreenFadeoutComplete")
	{
		if (helpScreen)
		{
			helpScreen->Destroy();
			helpScreen = NULL;
		}
	}
	if (message->GetMessageName() == "splashScreenFadeInComplete")
	{
		//theSwitchboard.DeferredBroadcast(new Message("splashScreenWaitComplete", this), FADE_IN_OUT_TIME * 3);
	}
	/*if (message->GetMessageName() == "splashScreenWaitComplete")
	{
		if (splashScreen)
		{
			splashScreen->ChangeAlphaTo(0, FADE_IN_OUT_TIME * 3, true, "splashScreenFadeOutComplete");
			fadeScreen->ChangeAlphaTo(0, FADE_IN_OUT_TIME * 3, true);
		}
	}*/
	if (message->GetMessageName() == "splashScreenFadeOutComplete")
	{
		if (splashScreen)
		{
			splashScreen->Destroy();
			splashScreen = NULL;
		}
		if (fadeScreen)
		{
			fadeScreen->Destroy();
			fadeScreen = NULL;
		}
	}
}

void CellWarsGameManager::Render()
{
	multiTouchManager->render();
}

void CellWarsGameManager::Update(float dt)
{
	timeSinceStartup += dt;
	timeSinceLastInput += dt;

	multiTouchManager->update(dt);

	if (currentGameState == GameStates::SplashScreen)
	{
		if (gotInputThisFrame)
		{
			splashScreen->ChangeAlphaTo(0, FADE_IN_OUT_TIME * 3, true, "splashScreenFadeOutComplete");
			fadeScreen->ChangeAlphaTo(0, FADE_IN_OUT_TIME * 3, true);
			showStart();
		}
	}
	else if (currentGameState == GameStates::HowToPlay)
	{
		showSplashScreenIfGotNoInput();
	}
	else if (currentGameState == GameStates::Game)
	{
		if (isGameSuccess())
		{
			playTime = SURVIVAL_TIME;
			activateBacteriaInvasion();
			timeSinceInvasionStarted = 0;
			currentGameState = GameStates::Invasion;
		}
		else
			playTime += dt;
		
		leftSide->SetSize(leftSide->GetSize().X, (theCamera.GetWorldMaxVertex().Y - theCamera.GetWorldMinVertex().Y) * playTime / SURVIVAL_TIME);
		rightSide->SetSize(rightSide->GetSize().X, (theCamera.GetWorldMaxVertex().Y - theCamera.GetWorldMinVertex().Y) * playTime / SURVIVAL_TIME);

		timeSinceLastMacrophages += dt;
		if (timeSinceLastMacrophages > getCurrentTimeBetweenMacrophages())
		{
			timeSinceLastMacrophages = 0;
			SpawnMacrophageWave();
		}

		timeSinceLastCell += dt;

		if (timeSinceLastCell > TIME_BETWEEN_CELLS)
		{
			timeSinceLastCell = 0;
			SpawnBodyCell();
		}

		if (bacteria->size() == 0)
			showEndStats();
	}
	else if (currentGameState == GameStates::Invasion)
	{
		timeSinceInvasionStarted += dt;
		
		destroyRemainingBacteria(dt);

		if (timeSinceInvasionStarted >= INVASION_TIME)
			showEndStats();
	}
	else if (currentGameState == GameStates::StartScreen)
	{
		playTime = 0;
		showSplashScreenIfGotNoInput();
	}
	else /* endstats */
	{
		playTime = SURVIVAL_TIME;

		destroyRemainingBacteria(dt);

		timeSinceMusicFadeOutStart += dt;
		if (backgroundMusicSound)
		{
			float newVolume = mainVolume * (1 - timeSinceMusicFadeOutStart / FADE_IN_OUT_TIME);
			if (newVolume >= 0)
				theSound.SetVolume(backgroundMusicSound, newVolume);
			else
			{
				theSound.StopSound(backgroundMusicSound);
				backgroundMusicSound  = NULL;
			}
		}
		showSplashScreenIfGotNoInput();
	}

	gotInputThisFrame = false;
}

void CellWarsGameManager::SpawnMacrophageWave()
{
	//int spawnNumber = (numMacrophageWaves + 1);
	//int spawnNumber = 1 * exp(MACROPHAGE_WAVE_INCREASE_FACTOR * numMacrophageWaves);
	int spawnNumber = 1 + MACROPHAGE_WAVE_INCREASE_FACTOR * numMacrophageWaves;
	//int spawnNumber = 1;

	for (int i = 0; i < spawnNumber; ++i)
	{
		if (macrophages->size() >= MAX_NUM_MACROPHAGES)
			break;
		
		addMacrophageToGame(new Macrophage());

		++numSpawnedMacrophages;
	}

	++numMacrophageWaves;
}

void CellWarsGameManager::SpawnBodyCell()
{
	int spawnNumber = 1;

	for (int i = 0; i < spawnNumber; ++i)
	{
		if (cells->size() >= MAX_NUM_CELLS)
			break;
		
		addCellToGame(new Cell());

		++numSpawnedCells;
	}

	++numCellWaves;
}

Bacterium* CellWarsGameManager::spawnSingleBacterium(Vector2 spawnPos)
{
	Bacterium* newBact = NULL;
	if (bacteria->size() <= MAX_NUM_BACTERIA)
	{
		newBact = new Bacterium(spawnPos, multiTouchManager);
		addBacteriumToGame(newBact);

		++numSpawnedBacteria;
	}
	return newBact;
}

void CellWarsGameManager::SpawnStartBacteria()
{
	for (int i = 0; i < NUM_STARTING_BACTERIA; ++i)
	{
		Vector2 border(theCamera.GetWorldMaxVertex().X - theCamera.GetWorldMinVertex().X, 
			theCamera.GetWorldMaxVertex().Y - theCamera.GetWorldMinVertex().Y);
		border *= 0.20f;
		float xPos = MathUtil::RandomFloatInRange(theCamera.GetWorldMinVertex().X + border.X, theCamera.GetWorldMaxVertex().X - border.X);
		float yPos = MathUtil::RandomFloatInRange(theCamera.GetWorldMinVertex().Y + border.Y, theCamera.GetWorldMaxVertex().Y - border.Y);
		Vector2 spawnPos(xPos, yPos);
		spawnSingleBacterium(spawnPos);
	}
}

void CellWarsGameManager::SoundEnded(AngelSoundHandle sound)
{
	if (sound == backgroundMusicSound)
		backgroundMusicSound = NULL;
	if (sound == replicateSound)
		replicateSound = NULL;
	if (sound == upgradeSound)
		upgradeSound = NULL;
}

void CellWarsGameManager::initAssets()
{
	// preload all images
	GetTextureReference("Resources/Images/background.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/fadescreen.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/left_side.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/right_side.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/bacterium.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/cell.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/macrophage.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/macrophagePart.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/macrophageTentacle.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/cellPart.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/selectionCircle.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/multiSelectionCircle.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/flowparticle.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/titleScreen.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/title.png", GL_CLAMP, GL_LINEAR, false);
	
	GetTextureReference("Resources/Images/removeSelection active.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/replicate.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/replicate active.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/upgrade.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/upgrade active.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/health.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/resources.png", GL_CLAMP, GL_LINEAR, false);
	//GetTextureReference("Resources/Images/damage.png", GL_CLAMP, GL_LINEAR, false);
	//GetTextureReference("Resources/Images/life.png", GL_CLAMP, GL_LINEAR, false);
	//GetTextureReference("Resources/Images/resistance.png", GL_CLAMP, GL_LINEAR, false);
	//GetTextureReference("Resources/Images/camouflage.png", GL_CLAMP, GL_LINEAR, false);
	
	GetTextureReference("Resources/Images/exit.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/help.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/start.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/replay.png", GL_CLAMP, GL_LINEAR, false);
	
	GetTextureReference("Resources/Images/selecting.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/selected.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/inVolButton.png", GL_CLAMP, GL_LINEAR, false);
	GetTextureReference("Resources/Images/deVolButton.png", GL_CLAMP, GL_LINEAR, false);
	
	GetTextureReference("Resources/Images/cursor.png", GL_CLAMP, GL_LINEAR, false);

	theSound.SetSoundCallback(this, &GameManager::SoundEnded);
	
	backgroundMusicSample = theSound.LoadSample("Resources/Sounds/CellWars_Soundtrack.ogg", false /*no stream*/);
	attackSample = theSound.LoadSample("Resources/Sounds/attack.wav", false /*no stream*/);
	moveSample = theSound.LoadSample("Resources/Sounds/move.wav", false /*no stream*/);
	replicateSample = theSound.LoadSample("Resources/Sounds/replicate.wav", false /*no stream*/);
	upgradeSample = theSound.LoadSample("Resources/Sounds/upgrade.wav", false /*no stream*/);
}

void CellWarsGameManager::showHelp()
{
	if (currentGameState == GameStates::StartScreen)
	{
		currentGameState = GameStates::HowToPlay;
		if (startScreen)
		{
			startScreen->ChangeAlphaTo(0, FADE_IN_OUT_TIME, true, "startScreenFadeoutComplete");
		}
		helpScreen = new HelpScreen(multiTouchManager);
		//helpScreen->SetAlpha(0);
		//helpScreen->ChangeAlphaTo(1, FADE_IN_OUT_TIME, true);
	}
}

void CellWarsGameManager::showStart()
{
	if (currentGameState == GameStates::EndStats || currentGameState == GameStates::SplashScreen ||
		currentGameState == GameStates::HowToPlay)
	{
		currentGameState = GameStates::StartScreen;
		if (endScreen)
		{
			endScreen->ChangeAlphaTo(0, FADE_IN_OUT_TIME, true, "endScreenFadeoutComplete");
		}
		if (helpScreen)
		{
			helpScreen->ChangeAlphaTo(0, FADE_IN_OUT_TIME, true, "helpScreenFadeoutComplete");
		}
		startScreen = new StartScreen(multiTouchManager);
		startScreen->SetAlpha(0);
		startScreen->ChangeAlphaTo(1, FADE_IN_OUT_TIME, true);
		deActivateBacteriaInvasion();
	}
}

void CellWarsGameManager::startGame()
{
	if (currentGameState == GameStates::StartScreen)
	{
		currentGameState = GameStates::Game;
		if (startScreen)
		{
			startScreen->ChangeAlphaTo(0, FADE_IN_OUT_TIME, true, "startScreenFadeoutComplete");
		}
		resetGame();
		SpawnStartBacteria();

		if (backgroundMusicSample)
		{
			backgroundMusicSound = theSound.PlaySound(backgroundMusicSample, mainVolume, false/*no loop*/, 0);
			background->resetPhase();
		}
	}
}

void CellWarsGameManager::resetGame()
{
	numMacrophageWaves = 0;
	numSpawnedMacrophages = 0;
	std::list<Macrophage*>::iterator macIt(macrophages->begin());
	while (macIt != macrophages->end())
	{
		(*macIt)->Destroy();
		macIt = macrophages->begin();
	}

	numCellWaves = 0;
	numSpawnedCells = 0;
	std::list<Cell*>::iterator cellIt(cells->begin());
	while (cellIt != cells->end())
	{
		(*cellIt)->Destroy();
		cellIt = cells->begin();
	}

	numSpawnedBacteria = 0;
	std::list<Bacterium*>::iterator bacIt(bacteria->begin());
	while (bacIt != bacteria->end())
	{
		(*bacIt)->Destroy();
		bacIt = bacteria->begin();
	}

	timeSinceLastMacrophages = 0;
	timeSinceLastCell = 0;
	
	replications = 0;
	upgrades = 0;
	killedMacrophages = 0;
	killedCells = 0;
	playTime = 0;
}

void CellWarsGameManager::endGame()
{
	theWorld.StopGame();
}

void CellWarsGameManager::showEndStats()
{
	if (currentGameState == GameStates::Game || currentGameState == GameStates::Invasion)
	{
		currentGameState = GameStates::EndStats;
		endScreen = new EndScreen(multiTouchManager);
		
		endScreen->SetAlpha(0);
		endScreen->ChangeAlphaTo(1, FADE_IN_OUT_TIME, true);

		timeSinceMusicFadeOutStart = 0;
	}
}

void CellWarsGameManager::playUpgradeSound()
{
	if (!upgradeSound)
	{
		if (upgradeSample)
		{
			upgradeSound = theSound.PlaySound(upgradeSample, mainVolume, false/*no loop*/, 0);
		}
	}
}

void CellWarsGameManager::playReplicateSound()
{
	if (!replicateSound)
	{
		if (replicateSample)
		{
			replicateSound = theSound.PlaySound(replicateSample, mainVolume, false/*no loop*/, 0);
		}
	}
}

void CellWarsGameManager::showSplashScreenIfGotNoInput()
{
	if (timeSinceLastInput > 60)
	{
		currentGameState = GameStates::SplashScreen;
		if (startScreen)
		{
			startScreen->ChangeAlphaTo(0, FADE_IN_OUT_TIME, true, "startScreenFadeoutComplete");
		}
		if (endScreen)
		{
			endScreen->ChangeAlphaTo(0, FADE_IN_OUT_TIME, true, "endScreenFadeoutComplete");
		}
		if (helpScreen)
		{
			helpScreen->ChangeAlphaTo(0, FADE_IN_OUT_TIME, true, "helpScreenFadeoutComplete");
		}
		
		Vector2 screenSizeInAngelCoords(theCamera.GetWorldMaxVertex() - theCamera.GetWorldMinVertex());

		fadeScreen = new Actor();
		fadeScreen->SetColor(1,1,1,0);
		fadeScreen->ChangeAlphaTo(1, FADE_IN_OUT_TIME * 3, true);
		fadeScreen->SetSprite("Resources/Images/fadescreen.png");
		fadeScreen->SetSize(screenSizeInAngelCoords);
		theWorld.Add(fadeScreen, LayerEnum::ScreenOverlay);

		splashScreen = new Actor();
		splashScreen->SetColor(1,1,1,0);
		splashScreen->ChangeAlphaTo(1, FADE_IN_OUT_TIME * 3, true, "splashScreenFadeInComplete");
		splashScreen->SetSprite("Resources/Images/titleScreen.png");
		splashScreen->SetSize(screenSizeInAngelCoords);
		theWorld.Add(splashScreen, LayerEnum::SplashScreen);

		deActivateBacteriaInvasion();
	}
}

void CellWarsGameManager::destroyRemainingBacteria(float dt)
{
	timeSinceLastDestroyedMacrophage += dt * (float)macrophages->size();
		
	if (timeSinceLastDestroyedMacrophage > 0.5f * INVASION_TIME)
	{
		if (macrophages->size() > 0)
		{
			int damagedIndex = MathUtil::RandomIntInRange(0, macrophages->size() - 1);

			std::list<Macrophage*>::iterator it = macrophages->begin();

			for (int i = 0; i < damagedIndex; ++i)
				++it;

			float dmg = (*it)->getMaxLifePoints() * -0.5f;
			(*it)->addLifePoints(dmg);
		}

		timeSinceLastDestroyedMacrophage = 0;
	}
}
