/******************************************************************************
*******************************************************************************

	Bubble Fight EX
	relminator
	http://rel.betterwebber.com


	Moai class


*******************************************************************************
******************************************************************************/

#include "Moai.h"

#define MIN_X ( -32 << 12 )
#define MIN_Y ( -18 << 12 )


//------------------------------------------------------------------------------
//	Moai Enemy
//------------------------------------------------------------------------------
Moai::Moai()
{
	x = 600 <<12;
	y = 96 << 12;
	Frame = 0;
	Active = false;	
	Alive = true;
	DestroyedCounter = 60 * 5;
	Hp = 38; 
	DrawMode = EN_NORMAL;
	FlipMode = GL_FLIP_NONE;
}

Moai::~Moai()
{
}


void Moai::Init( int Palette, glImage* const Sprites )
{
	ColorTable = Palette;		// init needed data for drawing
	Images = Sprites;
}

void Moai::Update()
{
	if( Active )
	{
	
		Path.Update();
		
		if( Path.GetIndex() == 5 ) ClosePath();
		
		x = Path.GetX();
		y = Path.GetY();
		
		Counter++;
		// animate
		FlipMode = GL_FLIP_NONE;
		if( ( Counter & 3 ) == 0 )
		{
			Frame = (Frame + 1) & 7;
		}

		if( Frame>3 ) FlipMode = GL_FLIP_H;
	}
	
}


void Moai::LoadPath( int _sx, int _sy, int _ex, int _ey )
{
	Path.Init( 16 );
	
	Spline::Coord p;
	
	// start
	p.x = _sx;
	p.y = _sy;
	
	// we should use 2 points
	Path.AddPoint( p );
	Path.AddPoint( p );
	
	// randomize for now
	for (int i=0; i < 10; i++)
	{
		p.x = qran_range(0, 255);
		p.y = qran_range(0, 193);
		Path.AddPoint( p );
	}
	
	// close last 2 coords
	p.x = _ex;
	p.y = _ey;
	
	// we should use 2 points
	Path.AddPoint( p );
	Path.AddPoint( p );
	
	Path.SetSpeed(qran_range(16,32));
	Path.SetT(0);
	
}


void Moai::Draw()
{
	glColorTable( GL_RGB16, ColorTable );
	if( Active )
	{
		if( (DrawMode == EN_WHITE) )
		{
			DrawMode = EN_NORMAL;
			glColorTable( GL_RGB256, Palettes::Instance()->White() );
			glSprite( (x >> 12) - 32, (y >> 12) - 32, 
					  FlipMode, &Images[Frame & 3] 
					);
			glColorTable( GL_RGB16, ColorTable );

		}
		else
		{
			glSprite( (x >> 12) - 32, (y >> 12) - 32, 
					  FlipMode, &Images[Frame & 3] 
					);
		}
		
	}

}


bool Moai::Collide( StarFighter &Star )
{
	
	if( Active )
	{
		int rad2 = 32 * 32;
		int cx = (x >> 12) - (Star.x >> 12);
		int cy = (y >> 12) - (Star.y >> 12);
		if( ( (cx * cx) + (cy * cy) ) < (rad2 * (1+Star.IsBursting())) )
		{
			if( Star.IsBursting() )
			{
				Hp--;
				if( (Hp & 3) == 0 ) Sound::Instance()->PlaySFX(E_SFX_HIT);
				if( Hp < 0 )
				{
					Active = false;
					Alive = false;
					Star.Score += 11130;
					Sound::Instance()->PlaySFX(E_SFX_BIGEXP);
					// Add some nice explosions
					Explosion::Instance()->Spawn( x >> 12,
												  y >> 12,
												   0,
												   0,
												   EX_MEDIUM_2
												 );
						
					for( int i = 0; i < 4; i++ )
					{	
						s32 dx = cosLerp(i * BRAD_PI / 2);
						s32 dy = sinLerp(i * BRAD_PI / 2);
						Explosion::Instance()->Spawn( x >> 12,
												  y >> 12,
												   dx,
												   dy,
												   EX_SMALL_3
												 );
						
					}
					
					x = 600 << 12;
					y = 96 << 12;
	
				}
				if( DrawMode == EN_NORMAL )
				{
					if( (Counter & 1) ) DrawMode = EN_WHITE;
				}
			}
			else
			{
				// kill star
				if( !Star.IsInvincible() ) Star.Kill();
			}
			return true;
		}
	}

	return false;
}



void Moai::Spawn()
{
	
	Active = true;
	Alive = true;	
	DestroyedCounter = 60 * 5;
	Frame = 0;
	Counter = 0;
	Hp = 264;
	LoadPath( 300, 96, -300, 96 );

	
}

void Moai::ClosePath()
{
		
	Path.SetPoint( 0, qran_range(0, 255), qran_range(0, 193) );
	Path.SetPoint( 1, qran_range(0, 255), qran_range(0, 193) );
	
	Path.SetPoint( Path.GetMaxPoints() - 1, qran_range(0, 255), qran_range(0, 193) );
	Path.SetPoint( Path.GetMaxPoints() - 2, qran_range(0, 255), qran_range(0, 193) );
	
}