#include	"ppAliens.h"

//	***************************************************************************
//	CAlien - Class
//

// constructor of alien class.
// here we do basic initialization of an alien ship.
CAlien::CAlien()
{
	// create alien and engine
	m_iShipSprID	= agk::CreateSprite(m_iShipImgID);
	m_iEnginePfxID	= agk::CreateParticles(30.0f, 10.0f);

	// give it a box shape
	agk::SetSpriteShape(m_iShipSprID, 2);

	// set up engine
	agk::SetParticlesImage			(m_iEnginePfxID, m_iParticleImgID);
	agk::SetParticlesStartZone		(m_iEnginePfxID, 0.0f, 0.0f, 0.0f, 0.0f);
	agk::SetParticlesDirection		(m_iEnginePfxID, 50.0f, 0.0);
	agk::SetParticlesLife			(m_iEnginePfxID, 0.4f);
	agk::SetParticlesSize			(m_iEnginePfxID, 16.0f);
	agk::SetParticlesAngle			(m_iEnginePfxID, 20.0f);
	agk::SetParticlesFrequency		(m_iEnginePfxID, 24.0f);
	agk::SetParticlesVelocityRange	(m_iEnginePfxID, 0.5f, 2.0f);
	agk::AddParticlesColorKeyFrame	(m_iEnginePfxID, 0.0f, agk::Random(0, 255), agk::Random(0, 255), 0, 255);
	agk::AddParticlesColorKeyFrame	(m_iEnginePfxID, 0.4f, 255, 255, 0, 0);

	// add one of four forces
	int mode = agk::Random(1, 4);

	if (mode == 1)
		agk::AddParticlesForce(m_iEnginePfxID, 0.2f, 0.4f, -1500.0f, -1550.0f);

	if (mode == 2)
		agk::AddParticlesForce(m_iEnginePfxID, 0.2f, 0.4f, 1500.0f, 1550.0f);

	if (mode == 3)
		agk::AddParticlesForce(m_iEnginePfxID, 0.2f, 0.4f, 100.0f, 100.0f);

	if (mode == 4)
		agk::AddParticlesForce(m_iEnginePfxID, 0.2f, 0.4f, -100.0f, -100.0f);

	// reset alien
	Reset();
}

CAlien::~CAlien()
{
}

// reset give the alien a new move property, engine effect and position 
// outside the screen
void CAlien::Reset()
{
	// set position
	float fX = 550.0f + agk::Random(20, 600);
	float fY = float(agk::Random(100, 300));

	float fEngineX	= fX + 30.0f;
	float fEngineY	= fY + 10.0f;

	// convert to world position instead of screen (because of scrolling)
	fX			= agk::ScreenToWorldX(fX);
	fY			= agk::ScreenToWorldY(fY);
	fEngineX	= agk::ScreenToWorldX(fEngineX);
	fEngineY	= agk::ScreenToWorldY(fEngineY);

	// generate new values for movement
	float speed		= float(agk::Random(10, 20));
	m_fSpeed		= speed / 10.0f;
	speed			= float(agk::Random(1, 10));
	m_fValueA		= speed / 100.0f;
	m_fValueB		= 0.0f;

	// clear particle colors and add new keyframes
	agk::ClearParticlesColors(m_iEnginePfxID);
	agk::AddParticlesColorKeyFrame(m_iEnginePfxID, 0.0f, agk::Random(0, 255), agk::Random(0, 255), 0, 255);
	agk::AddParticlesColorKeyFrame(m_iEnginePfxID, 0.4f, 255, 255, 0, 0);

	// set new position
	agk::SetSpritePosition(m_iShipSprID, fX, fY);
	agk::SetParticlesPosition(m_iEnginePfxID, fEngineX, fEngineY);
}

// updates the position of the alien-ship dependent of their movement properties.
void CAlien::Update()
{
	// get the new location
	float fShipX = agk::GetSpriteX(m_iShipSprID) - m_fSpeed;
	float fShipY = agk::GetSpriteY(m_iShipSprID);
	float fEngineX = agk::GetParticlesX(m_iEnginePfxID) - m_fSpeed;
	float fEngineY = agk::GetParticlesY(m_iEnginePfxID);

	// apply wavy movement
	m_fValueB = m_fValueB + m_fValueA;
	fShipY = fShipY + agk::Cos(m_fValueB * 180.0f / 3.14f);
	fEngineY = fEngineY + agk::Cos(m_fValueB * 180.0f / 3.14f);

	// reset once they have moved off the screen
	if (agk::WorldToScreenX(fEngineX) < -200)
	{
		Reset();
		return;
	}

	// update position of alien and engine
	agk::SetSpritePosition(m_iShipSprID, fShipX, fShipY);
	agk::SetParticlesPosition(m_iEnginePfxID, fEngineX, fEngineY);
}

// return the position of an alien
void CAlien::GetPosition(float * fX, float * fY)
{
	if (agk::GetSpriteExists(m_iShipSprID))
	{ 
		*fX = agk::GetSpriteX(m_iShipSprID);
		*fY = agk::GetSpriteY(m_iShipSprID);
	} 
}
//	---------------------------------------------------------------------------



//	***************************************************************************
//	CExplosion - Class
//

// constructor main initialization of an explosion
CExplosion::CExplosion()
{
	m_iParticlePfxID = agk::CreateParticles(-1000.0f, -1000.0f);
}

CExplosion::~CExplosion()
{
}

// only check if the max particles reached. Then reset the particles.
void CExplosion::Refresh()
{
	if (agk::GetParticlesMaxReached(m_iParticlePfxID) == 1)
	{
		agk::ClearParticlesColors(m_iParticlePfxID);
		agk::ClearParticlesForces(m_iParticlePfxID);
		m_iActive = 0;
	}
}

// make and play an explosion.
void CExplosion::Explode(float fX, float fY)
{
	// reset
	agk::ResetParticleCount(m_iParticlePfxID);

	// set position
	agk::SetParticlesPosition(m_iParticlePfxID, fX, fY);

	// set properties
	agk::SetParticlesFrequency		(m_iParticlePfxID, 250);
	agk::SetParticlesLife			(m_iParticlePfxID, 1.0f);
	agk::SetParticlesSize			(m_iParticlePfxID, 32);
	agk::SetParticlesStartZone		(m_iParticlePfxID, -10, 0, 10, 0);
	agk::SetParticlesImage			(m_iParticlePfxID, IMGID_PARTICLES);
	agk::SetParticlesDirection		(m_iParticlePfxID, 20, 20.0f);
	agk::SetParticlesAngle			(m_iParticlePfxID, 360.0f);
	agk::AddParticlesColorKeyFrame	(m_iParticlePfxID, 0.0f, 0, 0, 0, 0);
	agk::AddParticlesColorKeyFrame	(m_iParticlePfxID, 0.2f, agk::Random(0, 100), agk::Random(100, 255), agk::Random(100, 255), 255);
	agk::AddParticlesColorKeyFrame	(m_iParticlePfxID, 1.0f, 0, 100, 255, 0);
	agk::AddParticlesForce			(m_iParticlePfxID, 0.2f, 0.8f, 400.0f, 0.0f);

	// set up a random force for the particles
	int a = agk::Random(200, 1000);

	if (agk::Random(1, 2) == 1)
	{
		a = -a;
	}

	int b = agk::Random(500, 5000);
	int c = 0;

	if (agk::Random(1, 2) == 1)
	{
		b = -b;
	}

	if (agk::Random(1, 3) == 1)
	{
		c = b;
	}

	// add force near the end of its life
	agk::AddParticlesForce(m_iParticlePfxID, 0.6f, 1.0f, float(c), float(a));

	// random kind of explosion
	if (agk::Random(1, 3) == 1)
	{
		agk::ClearParticlesColors(m_iParticlePfxID);
		agk::ClearParticlesForces(m_iParticlePfxID);

		int col = agk::Random(1, 3);

		if (col == 1)
		{
			agk::AddParticlesColorKeyFrame(m_iParticlePfxID, 0.0f, 255, 0, 0, 255);
			agk::AddParticlesColorKeyFrame(m_iParticlePfxID, 0.4f, 255, 100, 0, 255);
			agk::AddParticlesColorKeyFrame(m_iParticlePfxID, 0.8f, 255, 200, 0, 255);
			agk::AddParticlesColorKeyFrame(m_iParticlePfxID, 1.0f, 255, 255, 0, 0);
		}
		else if (col == 2)
		{
			agk::AddParticlesColorKeyFrame(m_iParticlePfxID, 0.0f, 0, 0, 255, 255);
			agk::AddParticlesColorKeyFrame(m_iParticlePfxID, 0.4f, 0, 100, 255, 255);
			agk::AddParticlesColorKeyFrame(m_iParticlePfxID, 0.8f, 0, 200, 255, 255);
			agk::AddParticlesColorKeyFrame(m_iParticlePfxID, 1.0f, 0, 255, 255, 0);
		}
		else
		{
			agk::AddParticlesColorKeyFrame(m_iParticlePfxID, 0.0f, 0, 0, 255, 255);
			agk::AddParticlesColorKeyFrame(m_iParticlePfxID, 0.4f, 100, 0, 255, 255);
			agk::AddParticlesColorKeyFrame(m_iParticlePfxID, 0.8f, 200, 0, 255, 255);
			agk::AddParticlesColorKeyFrame(m_iParticlePfxID, 1.0f, 255, 0, 255, 0);
		}

		agk::SetParticlesDirection(m_iParticlePfxID, 40.0f, 40.0f);

		int up = agk::Random(200, 1000);

		agk::AddParticlesForce(m_iParticlePfxID, 0.2f, 0.4f, 0.0f, float(-up));
		agk::AddParticlesForce(m_iParticlePfxID, 0.4f, 1.0f, 0.0f, float(up));
	}

	agk::SetParticlesMax(m_iParticlePfxID, 100);
}
//	---------------------------------------------------------------------------



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

CAliens::~CAliens()
{
}

void CAliens::CreateAlienExplosions()
{
}

// update all aliens. look CAlien::Update for further details
void CAliens::UpdateAliens()
{
	// update the aliens
	for (int i = 0; i < 10; i++)
		m_AliensSprID[i].Update();
}

// reset all aliens. look CAlien::Reset for further details
void CAliens::ResetAliens()
{
	// reset all aliens
	// run through them
	for (int i = 0; i < 10; i++)
		m_AliensSprID[i].Reset();
}

// play an explosion
void CAliens::ExplodeAlien(float x, float y)
{
	// destroy an alien

	// find which explosion from the 5 is available
	int ID = -1;
	for (int i = 0; i < 5; i++)
	{
		m_ExplosionsPfxID[i].Refresh();
		if (!m_ExplosionsPfxID[i].IsActive())
			ID = i;
	}

	// back out if all 5 are being used
	if (ID == -1)
		return;

	agk::PlaySound(agk::Random(SFXID_EXPLOSION1, SFXID_EXPLOSION3));

	m_ExplosionsPfxID[ID].Explode(x, y);
}

// check collision with ALL aliens 
CAlien*		CAliens::CheckCollisionWithAliens(int iSprite)
{
	for (int j = 0; j < 10; j++)
	{
		if (agk::GetSpriteColorAlpha(iSprite) > 16)
		{
			if (m_AliensSprID[j].CheckCollision(iSprite))
			{
				float x = agk::GetSpriteX(m_AliensSprID[j].m_iShipSprID);
				float y = agk::GetSpriteY(m_AliensSprID[j].m_iShipSprID);
				float x1 = agk::WorldToScreenX(x);
				float y1 = agk::WorldToScreenY(y);

				return &m_AliensSprID[j];
			}
		}
	}

	return 0L;
}
//	---------------------------------------------------------------------------

