#include	"ppPlayer.h"
#include	"ppLevel.h"
#include	"ppAliens.h"

//	***************************************************************************
//	CWeapon - Class
//
CWeapon::CWeapon()
{
}

CWeapon::~CWeapon()
{
}

// reset this bullet
void CWeapon::Reset()
{
	if (agk::GetSpriteExists(m_iBulletSprID) == 0)
		m_iBulletSprID = agk::CreateSprite(IMGID_BULLET);

	if (agk::GetParticlesExists(m_iExplosionPfxID) == 1)
		agk::DeleteParticles(m_iExplosionPfxID);

	agk::SetSpritePosition(m_iBulletSprID, -100.0f, -100.0f);
	agk::SetSpriteColorAlpha(m_iBulletSprID, 0);

	m_iActive = 0;
	m_fLife = 0;
}

// let the bullet explode
void CWeapon::Destroy()
{
	if (m_iActive == 1)
	{
		float fX = agk::GetSpriteX(m_iBulletSprID);
		float fY = agk::GetSpriteY(m_iBulletSprID);

		agk::SetSpritePosition(m_iBulletSprID, -100.0f, -100.0f);

		int explode = agk::CreateParticles(fX, fY);

		m_iExplosionPfxID = explode;

		agk::SetParticlesImage(explode, IMGID_PARTICLES);
		agk::SetParticlesStartZone(explode, -20, 20, -20, 20);
		agk::SetParticlesDirection(explode, 8, 8);
		agk::SetParticlesLife(explode, 2.0);
		agk::SetParticlesSize(explode, 16);
		agk::SetParticlesAngle(explode, 360);
		agk::SetParticlesFrequency(explode, 120);
		agk::AddParticlesColorKeyFrame(explode, 0.0f, 120, 0, 255, 255);
		agk::AddParticlesColorKeyFrame(explode, 2.0f, 255, 100, 255, 0);

		agk::AddParticlesForce(explode, 1.5f, 2.0f, 100, 100);
		agk::AddParticlesForce(explode, 1.5f, 2.0f, 250, 0);

		agk::SetParticlesMax(explode, 64);
	}
}
//	---------------------------------------------------------------------------



//	***************************************************************************
//	CPlayer - Class
//

// constructor of player class
// player main initialization. load player image
CPlayer::CPlayer()
{
	m_iShipSprID	= agk::CreateSprite(agk::LoadImage("space/playership.png"));

	ResetPlayer();
	ResetBullets();
}

CPlayer::~CPlayer()
{
}

// to set some shared pointers between classes
void CPlayer::SetReferences(CLevel * pLevel, CAliens * pAliens) 
{ 
	m_refScenery	= pLevel; 
	m_refAliens		= pAliens;
}

// reset player used after every new live and new game.
void CPlayer::ResetPlayer(int iNewGame)
{
	if (iNewGame)
	{
		m_iScore		= 0;
		m_iLives		= 3;
		m_iDelay		= 0;
		m_iGameOver		= 0;
		m_iState = 0;
	}

	agk::SetSpritePosition(m_iShipSprID, 200, 200);
	agk::SetViewOffset(0, 0);

	agk::SetSpriteVisible(m_iShipSprID, 1);

	if (agk::GetParticlesExists(m_iEnginePfxID) == 1)
		agk::DeleteParticles(m_iEnginePfxID);

	m_iEnginePfxID = agk::CreateParticles(200, 208);

	agk::SetParticlesImage				(m_iEnginePfxID, m_iParticleImgID);
	agk::SetParticlesStartZone			(m_iEnginePfxID, 0, 0, 0, 0);
	agk::SetParticlesDirection			(m_iEnginePfxID, -50, 0);
	agk::SetParticlesLife				(m_iEnginePfxID, 0.3f);
	agk::SetParticlesSize				(m_iEnginePfxID, 16);
	agk::SetParticlesAngle				(m_iEnginePfxID, 80);
	agk::SetParticlesFrequency			(m_iEnginePfxID, 60);
	agk::AddParticlesColorKeyFrame		(m_iEnginePfxID, 0.0f, 221, 136, 5, 255);
	agk::AddParticlesColorKeyFrame		(m_iEnginePfxID, 0.3f, 221, 136, 5, 0);

	if (agk::GetParticlesExists(m_iExplosionPfxID) == 1)
		agk::DeleteParticles(m_iExplosionPfxID);

	m_iExplosionPfxID = agk::CreateParticles(-1000, -1000);
}

// reset all bullets
void CPlayer::ResetBullets()
{
	for (int i = 0; i < 10; i++)
		m_Bullets[i].Reset();
}

// hide player (ship sprite and engine paricles)
void CPlayer::HidePlayer()
{
	agk::SetSpriteVisible		(m_iShipSprID, 0);
	agk::SetParticlesVisible	(m_iEnginePfxID, 0);
}

// show player (ship sprite and engine particles)
void CPlayer::ShowPlayer()
{
	agk::SetSpriteVisible		(m_iShipSprID, 1);
	agk::SetParticlesVisible	(m_iEnginePfxID, 1);
}

// update player dependency of player state
void CPlayer::UpdatePlayer()
{
	switch (m_iState)
	{
	case PLAYERSTATE_ALIVE:
		MovePlayer();
		CheckPlayerWithScenery();
		CheckPlayerWithAliens();
		FireBullets();
		UpdateBullets();
		CheckBulletsWithAliens();
		break;

	case PLAYERSTATE_DEAD:
		DestroyPlayer();
		break;

	}
}

// move player. continuosly in x-direction and dependency of cursor key's
void CPlayer::MovePlayer()
{
	float x = 1.0f;
	float y = 0.0f;

	if (agk::GetViewOffsetX() > 15300.0f)
	{
		HidePlayer();
		m_iGameOver = 1;
	}

	agk::SetViewOffset(agk::GetViewOffsetX() + x, 0);

	float fScreenX = agk::WorldToScreenX(agk::GetSpriteX(m_iShipSprID));

	float x1 = agk::GetDirectionX();
	float y1 = agk::GetDirectionY();

	x = x + x1 * 2.0f;
	y = y + y1 * 2.0f;

	if (fScreenX > 500.0f && x1 > 0.0f)
		x = 1.0;

	if (fScreenX < 20.0f && x1 < 0.0f)
		x = 1.0f;

	agk::SetSpritePosition(m_iShipSprID, agk::GetSpriteX(m_iShipSprID) + x, agk::GetSpriteY(m_iShipSprID) + y);
	agk::SetParticlesPosition(m_iEnginePfxID, agk::GetParticlesX(m_iEnginePfxID) + x, agk::GetParticlesY(m_iEnginePfxID) + y);
}

// check collision player vs scenry
void CPlayer::CheckPlayerWithScenery()
{
	if (m_refScenery->CheckCollisionWithLevel(m_iShipSprID))
		KillPlayer();
}

// check collision player vs aliens
void CPlayer::CheckPlayerWithAliens()
{
	CAlien* col = m_refAliens->CheckCollisionWithAliens(m_iShipSprID);
	if (col)
	{
		float x, y;
		col->GetPosition(&x, &y);

		m_refAliens->ExplodeAlien(x, y);
		col->SetPosition(-300.0f, -300.0f);
		KillPlayer();

		//agk::PlaySound(5);
	}
}

// check collision bullet vs aliens
void CPlayer::CheckBulletsWithAliens()
{
	for (int i = 0; i < 10; i++)
	{
		CAlien* col = m_refAliens->CheckCollisionWithAliens(m_Bullets[i].m_iBulletSprID);
		if (col)
		{
			float x, y;
			col->GetPosition(&x, &y);

			m_refAliens->ExplodeAlien(x, y);
			col->SetPosition(-300.0f, -300.0f);

			//agk::PlaySound(agk::Random(2, 4));

			m_Bullets[i].m_iActive = 0;
			agk::SetSpriteColorAlpha(m_Bullets[i].m_iBulletSprID, 0);
			agk::SetSpritePosition(m_Bullets[i].m_iBulletSprID, -100.0f, -100.0f);
			m_Bullets[i].m_fLife = 0.0f;

			m_iScore += 15;
		}
	}
}

// continuosly fire a bullet
void CPlayer::FireBullets()
{
	// fire a bullet
	m_fShootDelay = m_fShootDelay + 0.1f;

	if (m_fShootDelay >= 2.0f)
	{
		for (int i = 0; i < 10; i++)
		{
			if (m_Bullets[i].m_iActive == 0)
			{
				agk::PlaySound(SFXID_LASER);

				agk::SetSpritePosition(m_Bullets[i].m_iBulletSprID, agk::GetSpriteX(m_iShipSprID) + 28, agk::GetSpriteY(m_iShipSprID));
				m_Bullets[i].m_iActive = 1;
				break;
			}
		}

		//FireBulletsEnd:
		m_fShootDelay = 0.0;
	}
}

// update all bullets
void CPlayer::UpdateBullets()
{
	for (int i = 0; i < 10; i++)
	{
		if (m_Bullets[i].m_iActive == 1)
		{
			agk::SetSpritePosition(m_Bullets[i].m_iBulletSprID, agk::GetSpriteX(m_Bullets[i].m_iBulletSprID) + 4.5f, agk::GetSpriteY(m_Bullets[i].m_iBulletSprID));
			m_Bullets[i].m_fLife = m_Bullets[i].m_fLife + 0.1f;

			if (m_Bullets[i].m_fLife < 10.0f)
			{
				if (agk::GetSpriteColorAlpha(m_Bullets[i].m_iBulletSprID) < 200)
				{
					agk::SetSpriteColorAlpha(m_Bullets[i].m_iBulletSprID, agk::GetSpriteColorAlpha(m_Bullets[i].m_iBulletSprID) + 32);
				}
			}

			if (m_Bullets[i].m_fLife >= 1.5f)
			{
				if (agk::GetSpriteColorAlpha(m_Bullets[i].m_iBulletSprID) > 32)
				{
					agk::SetSpriteColorAlpha(m_Bullets[i].m_iBulletSprID, agk::GetSpriteColorAlpha(m_Bullets[i].m_iBulletSprID) - 32);
				}
				else
				{
					agk::SetSpriteColorAlpha(m_Bullets[i].m_iBulletSprID, 0);
				}
			}

			if (m_Bullets[i].m_fLife > 6.0f)
			{
				agk::SetSpriteColorAlpha(m_Bullets[i].m_iBulletSprID, 0);
				agk::SetSpritePosition(m_Bullets[i].m_iBulletSprID, -100.0f, -100.0f);
				m_Bullets[i].m_fLife = 0.0f;
				m_Bullets[i].m_iActive = 0;
			}
		}
	}
}

// make a explosion to kill a player
void CPlayer::KillPlayer()
{
	agk::SetSpriteVisible				(m_iShipSprID, 0);
	agk::SetParticlesVisible			(m_iEnginePfxID, 0);
	agk::SetParticlesPosition			(m_iExplosionPfxID, agk::GetSpriteX(m_iShipSprID) + 22, agk::GetSpriteY(m_iShipSprID));
	agk::SetParticlesImage				(m_iExplosionPfxID, m_iParticleImgID);
	agk::SetParticlesStartZone			(m_iExplosionPfxID, 0.0f, 0.0f, 0.0f, 0.0f);
	agk::SetParticlesDirection			(m_iExplosionPfxID, -32.0f, -32.0f);
	agk::SetParticlesLife				(m_iExplosionPfxID, 2.0f);
	agk::SetParticlesSize				(m_iExplosionPfxID, 64);
	agk::SetParticlesAngle				(m_iExplosionPfxID, 360);
	agk::SetParticlesFrequency			(m_iExplosionPfxID, 120);
	agk::AddParticlesColorKeyFrame		(m_iExplosionPfxID, 0.0f, 121, 1, 255, 255);
	agk::AddParticlesColorKeyFrame		(m_iExplosionPfxID, 2.0f, 1, 252, 255, 0);
	agk::AddParticlesForce				(m_iExplosionPfxID, 1.1f, 2.0f, 0.0f, 250.0f);
	agk::AddParticlesForce				(m_iExplosionPfxID, 1.5f, 2.0f, -250.0f, 0.0f);
	agk::SetParticlesMax				(m_iExplosionPfxID, 250);

	DestroyAllBullets();

	agk::PlaySound(SFXID_HIT);

	m_iLives--;
	m_iState = 1;
}

// destroy all bullets
void CPlayer::DestroyAllBullets()
{
	for (int i = 0; i < 10; i++)
		m_Bullets[i].Destroy();
}

// destroy the player
void CPlayer::DestroyPlayer()
{
	if (agk::GetParticlesMaxReached(m_iExplosionPfxID) && m_iDelay == 0)
		m_iDelay = int(agk::Timer());

	if (m_iDelay != 0 && (agk::Timer() + m_iDelay + 2) != 0)
	{
		ResetPlayer();
		ResetBullets();
		m_refAliens->ResetAliens();

		m_iDelay = 0;
		m_iState = 0;
	}

	if (m_iLives == 0)
	{
		m_iDelay = 0;
		m_iGameOver = 1;
	}
}

//	---------------------------------------------------------------------------
