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

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


	CircleSaw class


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

#include "CircleSaw.h"

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


//------------------------------------------------------------------------------
//	CircleSaw Enemy
//------------------------------------------------------------------------------
CircleSaw::CircleSaw()
{
	x = 600 <<12;
	y = 96 << 12;
	Frame = 0;
	Active = false;	
	Alive = true;
	DestroyedCounter = 60 * 5;
	Hp = 38; 
	
	Rotation = 0;;
	Delta = 32;
	Radius = 50;
	
	DrawMode = EN_NORMAL;
}

CircleSaw::~CircleSaw()
{
}


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

void CircleSaw::Update()
{
	if( Active )
	{
		Rotation += Delta;
	
		Radius = 50 + ( ( sinLerp(Rotation*4) * 10 ) >> 12 );
		Path.Update();
		
		if( Path.GetIndex() == 5 ) ClosePath();
		
		x = Path.GetX();
		y = Path.GetY();
		
		Counter++;
		// animate
		Frame = 0;
	}
	
}


void CircleSaw::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 CircleSaw::Draw()
{
	static s32 rdelta = 0;
		
	glColorTable( GL_RGB16, ColorTable );
	if( Active )
	{
		if( (DrawMode == EN_WHITE) )
		{
			for( int i = 0; i < (BRAD_PI*2); i += BRAD_PI/6 )
			{
				int cx = x + Radius * cosLerp(i+Rotation);
				int cy = y + Radius * sinLerp(i+Rotation);
			
				rdelta += 32;
				DrawMode = EN_NORMAL;
				glColorTable( GL_RGB256, Palettes::Instance()->White() );
				glSpriteRotate( (cx >> 12), (cy >> 12), i+Rotation+rdelta, 
						  GL_FLIP_NONE, &Images[Frame] 
						);
				glColorTable( GL_RGB16, ColorTable );
			}

		}
		else
		{
			for( int i = 0; i < (BRAD_PI*2); i += BRAD_PI/6 )
			{
				int cx = x + Radius * cosLerp(i+Rotation);
				int cy = y + Radius * sinLerp(i+Rotation);
				rdelta += 32;
				
				glSpriteRotate( (cx >> 12), (cy >> 12), i+Rotation+rdelta, 
						  GL_FLIP_NONE, &Images[Frame] 
						);
				
			}
		}
	
	}

}


bool CircleSaw::Collide( StarFighter &Star )
{
	
	if( Active )
	{
		int rad2 = 16 * 16;
		for( int i = 0; i < (BRAD_PI*2); i += BRAD_PI/6 )
		{
			s32 rx = x + Radius * cosLerp(i+Rotation);
			s32 ry = y + Radius * sinLerp(i+Rotation);
			
			
			// veiw collision 
			//int gx = rx >> 12;
			//int gy = ry >> 12;
			//glBoxFilled( gx-8, gy-8, gx+8, gy+8, RGB15(31,31,31) );
			
			int cx = (rx >> 12) - (Star.x >> 12);
			int cy = (ry >> 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
						for( int i = 0; i < (BRAD_PI*2); i += BRAD_PI/6 )
						{	
							s32 dx = cosLerp(i+Rotation);
							s32 dy = sinLerp(i+Rotation);
							
							s32 rx = x + Radius * dx;
							s32 ry = y + Radius * dy;
			
							Explosion::Instance()->Spawn( rx >> 12,
													  ry >> 12,
													   dx,
													   dy,
													   EX_MEDIUM_1
													 );
							
						}
						
						x = 600 << 12;
						y = 96 << 12;
		
					}
					if( DrawMode == EN_NORMAL )
					{
						if( (Counter & 1) ) 
							DrawMode = EN_WHITE;
					}
				}
				else  // if not bursting
				{
					// kill star
					if( !Star.IsInvincible() ) Star.Kill();
				}
				return true;
			}
		
		}	// next i
		
		
	} // active

	return false;
}



void CircleSaw::Spawn()
{
	
	Active = true;
	Alive = true;	
	DestroyedCounter = 60 * 5;
	Frame = 0;
	Counter = 0;
	Hp = 364;
	Rotation = 0;;
	Delta = 64;
	Radius = 50;
	LoadPath( 300, 96, -300, 96 );

	
}

void CircleSaw::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) );
	
}