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

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


	Tentaklaus class


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

#include "Tentaklaus.h"

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


//------------------------------------------------------------------------------
//	Tentaklaus Enemy
//------------------------------------------------------------------------------
Tentaklaus::Tentaklaus()
{
	x = 600 <<12;
	y = 96 << 12;
	Frame = 0;
	RotDir = -1;
	Frame = 0;
	Active = false;	
	Alive = true;
	DestroyedCounter = 60 * 5;
	Hp = 2038; 
	DrawMode = EN_NORMAL;

	for( int i = 0; i < TENTAKLAUS_MAX_SEGMENTS; i++ )
	{
		Segments[i][0].x  = i * 10;
		Segments[i][0].y  = 0;

		Segments[i][1].x  = 0;
		Segments[i][1].y  = i * 10;

		Segments[i][2].x  = -i * 10;
		Segments[i][2].y  = 0;

		Segments[i][3].x  = 0;
		Segments[i][3].y  = -i * 10;
	}
	

}

Tentaklaus::~Tentaklaus()
{
}


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

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

		
	}
	
	for( int i = 0; i < TENTAKLAUS_MAX_SEGMENTS; i++ )
	{
		s32 t =  (Rotation*128) + (sinLerp((Rotation*512)+(i*2048)));
		for( int j = 0; j < 4; j++ )
		{
			Segments2[i][j].x = Segments[i][j].x * cosLerp(t) - Segments[i][j].y * sinLerp(t);
			Segments2[i][j].y = Segments[i][j].y * cosLerp(t) + Segments[i][j].x * sinLerp(t);
		}	
	}
	
}


void Tentaklaus::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(32,64));
	Path.SetT(0);
	
}


void Tentaklaus::Draw()
{
	glColorTable( GL_RGB256, ColorTable );
	if( Active )
	{
			if( (DrawMode == EN_WHITE) )
			{
				DrawMode = EN_NORMAL;
				glColorTable( GL_RGB256, Palettes::Instance()->Red() );
				int f = Frame;
				for( int i = 0; i < TENTAKLAUS_MAX_SEGMENTS; i ++)
				{
					int ff =  (f + i);
						if(ff > 5) ff = 0;
					for( int j = 0; j < 4; j++ )
					{
						s32 tx = Segments2[i][j].x;
						s32 ty = Segments2[i][j].y;
						glSprite( ((x >> 12) - 8) + (tx >> 12),
								  ((y >> 12) - 8) + (ty >> 12), 
								  GL_FLIP_NONE, &Images[44+ff] 
								);
					}	
				}
				glColorTable( GL_RGB256, ColorTable );
			}
			else
			{
				int f = Frame;
				for( int i = 0; i < TENTAKLAUS_MAX_SEGMENTS; i ++)
				{
					int ff =  (f + i);
						if(ff > 5) ff = 0;
					for( int j = 0; j < 4; j++ )
					{
						s32 tx = Segments2[i][j].x;
						s32 ty = Segments2[i][j].y;
						glSprite( ((x >> 12) - 8) + (tx >> 12),
								  ((y >> 12) - 8) + (ty >> 12), 
								  GL_FLIP_NONE, &Images[44+ff] 
								);
					}	
				}
				
			}  // end if color table
		
		
	}

}


bool Tentaklaus::Collide( StarFighter &Star )
{
	
	if( Active )
	{
		for( int i = 0; i < TENTAKLAUS_MAX_SEGMENTS; i ++)
		{
			for( int j = 0; j < 4; j++ )
			{
				int tx = ( Segments2[i][j].x >> 12 ) + ( x >> 12 );
				int ty = ( Segments2[i][j].y >> 12 ) + ( y >> 12 );
				int rad2 = 8 * 8;
				int cx = (tx) - (Star.x >> 12);
				int cy = (ty) - (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 += 20512;
							Sound::Instance()->PlaySFX(E_SFX_BIGEXP);
							// Add some nice explosions
							for( int k = 0; k < TENTAKLAUS_MAX_SEGMENTS; k ++)
							{
								for( int l = 0; l < 4; l++ )
								{
									int xx = (Segments2[k][l].x >> 12) + ( x >> 12 );
									int yy = (Segments2[k][l].y >> 12) + ( y >> 12 );
									Explosion::Instance()->Spawn( xx,
												   yy,
												   0,
												   0,
												   EX_SMALL_3
												 );
								}
							}
							
							for( int i = 0; i < 4; i++ )
							{	
								s32 dx = cosLerp(BRAD_PI/4 + i * BRAD_PI / 2);
								s32 dy = sinLerp(BRAD_PI/4 + i * BRAD_PI / 2);
								Explosion::Instance()->Spawn( x >> 12,
														  y >> 12,
														   dx,
														   dy,
														   EX_MEDIUM_2
														 );
								
							}
							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 Tentaklaus::Spawn()
{
	
	Active = true;
	Alive = true;	
	DestroyedCounter = 60 * 5;
	Frame = 0;
	Counter = 0;
	Hp = 164;
	LoadPath( 300, 96, -300, 96 );

	
}

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