/*****************************/
/* Inside The Machine - MKS  */
/*****************************/

#include "eBoss2.h"
#include "../WorldManager.h"
#include "../WorldState.h"

eBoss2::eBoss2()
{
	real = true;
	toDelete = false;
	stat = false;
	type = 2;
   genre = 0;
   explosionH = 0;
	explosionAlpha = 0; 
	sequence = 0;
	angle = 0;
	newAngle = 0;
	dontHitTime = -1;
}
   	
eBoss2::~eBoss2()
{
   
}

void eBoss2::Load()
{
   //On charge les images
	ulSetTransparentColor(RGB15(31, 0, 31));
	body.assign(worldMan->resMan->LoadImage("efs:/Boss2_All.png", UL_IN_VRAM, UL_PF_PAL4));
	ball.assign(worldMan->resMan->LoadImage("efs:/Boss1_Ball.png", UL_IN_VRAM, UL_PF_PAL2));
	bigball.assign(worldMan->resMan->LoadImage("efs:/Boss2_Ball.png", UL_IN_VRAM, UL_PF_PAL4));
	explosion.assign(worldMan->resMan->LoadImage("efs:/FX_Explosion_1.png", UL_IN_VRAM, UL_PF_PAL2));
	sprFx2.assign(worldMan->resMan->LoadImage("efs:/FX_Impact_2.png", UL_IN_VRAM, UL_PF_PAL2));	
	ulDisableTransparentColor();
	
	isBossActivated = true; //stub
	sequence = 0;
	
	life = 200;
	hit = false;
	timer = 0;
	hitTime = 0;
	canFight = true;
	actif = false;

	for(int k = 0; k < 12; k++)
	{
		balls[k].free = true;  
		balls[k].rect.x1 = 2; 
		balls[k].rect.y1 = 2; 
		balls[k].rect.x2 = 6; 
		balls[k].rect.y2 = 6;
		balls[k].rectbig.x1 = 4; 
		balls[k].rectbig.y1 = 4; 
		balls[k].rectbig.x2 = 12; 
		balls[k].rectbig.y2 = 12; 
		balls[k].type = 0;
		balls[k].angle = 0;
		balls[k].myangle = 0;
	}
	
	rect.x1 = 0;
	rect.y1 = 0;
	rect.x2 = 16;
	rect.y2 = 48;
	
	//Parametrage des animations
	body.setFrameWH(32,64);
	body.addAnim(0,0,5,7);
	body.animLoop(0);
	body.setRotCenter(8, 0);
	
	sprFx2.scale(32,32);
	sprFx2.setAlpha(true, 20);
	
}
   
void eBoss2::Draw(int layer)
{
   //On affiche le boss
   bool act;
   if(x_screen < (-32) || x_screen > (256+32) || y_screen < (-32) || y_screen > (192+32))
	   act = false;
	else
	   act = true;
   if(act && layer == 1)
   {
		//Sprite
		body.setXY(x_screen, y_screen);
		body.rotate(angle);
		body.play();
		body.draw();
		
		if(hit)
      {
	      sprFx2.setXY(x_screen-16, y_screen+16);
	      sprFx2.draw();
		}
		if(hitTime == 10)
			hit = false;
			
		//On affiche les boulettes
		for(int k = 0; k < 12; k++)
		{
		   if(balls[k].free == false && life > 0)
		   {
			   int bxscr = balls[k].x - FIX(worldMan->curLevel->map->scrollX);
			   int byscr = balls[k].y - FIX(worldMan->curLevel->map->scrollY);
			   if(balls[k].type == 0)
			   {
					ball.setXY(UNFIX(bxscr), UNFIX(byscr));
					ball.draw();
				}
				else
				{
				   bigball.setXY(UNFIX(bxscr), UNFIX(byscr));
				   bigball.rotate(balls[k].myangle);
					bigball.draw();
				}						
			}			
		}
		//Explosion
		if(life <= 0)
		{
		   if(explosionH > 0)
			{
				explosion.draw();	
			}
		}
	}	
}
   
void eBoss2::Update()
{
   //Calcul de la position écran de l'entité
   x_screen = x - worldMan->curLevel->map->scrollX;
	y_screen = y - worldMan->curLevel->map->scrollY;
	
	//On vérifie si l'informateur est à l'écran
	if(worldMan->isScrollEnd)
	{
	   if(x_screen < (-32) || x_screen > (256+32) || y_screen < (-32) || y_screen > (192+32))
	   	actif = false;
	   else
	   	actif = true;
	}	
   
   //Explosion
	if(life <= 0)
	{
		//On augmente le rayon de l'explosion 		 
		explosionH += 1;
		explosionAlpha += 64;
		explosion.scale(explosionH, explosionH);
		
		if(explosionH == 1)
		{
			AS_SoundDefaultPlay(sndDie, 155520, soundVolume, 64, 0, 1);  
		} 
		
		//On change l'état moteur quand l'explosion est terminée
		if(explosionH == 256)
		{
		 	//On change l'état moteur
		 	WorldState::Instance()->FadeWhite();
		}
		if(explosionH >= 256+30)
		{
			//On passe a l'état de fin de niveau
			worldMan->isBossKilled = true;
		}   			
		if(explosionAlpha >= FIX(31))
			explosionAlpha = FIX(31);   
		//On affiche l'explosion
		explosion.setXY(x_screen-explosionH/2, y_screen-explosionH/2);
		explosion.setAlpha(true, UNFIX(explosionAlpha));
			
	}
		
   if(actif && isBossActivated && life > 0)
   {
      //ulDebug("life:%d\n", life);
      worldMan->isFightingBoss = true;
	   //Sequences d'attaque
	   timer++;

		//Idle
		if(timer < 180)
			sequence = 0;
		//Balls
		if(timer > 180 && timer < 480)
			sequence = 1;
		//Idle
		if(timer > 480 && timer < 660)
			sequence = 0;
		//BiG balls
		if(timer > 660 && timer < 960)
			sequence = 2;
		//Maj du timer
		if(timer > 960)
			timer = 0;

		//Programmation des séquences d'attaque
		if(sequence == 0)
		{
			//Idle
			canFight == true; //Le boss peut perdre de la vie
			//A chaque phase d'idle, on récupère l'angle 0
			if(angle <= 256)
				angle -= 1;
			if(angle > 256)
				angle += 1;
			if(angle == 0 || angle == 511)
				angle = 0;
			
		}
		if(sequence == 1)
		{
		 	//Balls
		 	int timeBalls = timer-180;
		 	if(timeBalls == 0)
		 		angle = 0;
		 		
		 	//Phase de rotation a gauche 
		 	if(timeBalls > 0 && timeBalls < 30)
		 		angle++;
		 	
		 	//On tire la 1ère boulette
		 	if(timeBalls == 60)
			{
			   //Boulette 1
			   balls[0].x = FIX(x-15);
			   balls[0].y = FIX(y+30);
			   balls[0].vx = -128;
			   balls[0].vy = +256;
			   balls[0].free = false;
			   balls[0].type = 0;
			   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
			}
			
			if(timeBalls == 90)
			{	 				   
			   //Boulette 2
			   balls[1].x = FIX(x-15);
			   balls[1].y = FIX(y+30);
			   balls[1].vx = -128;
			   balls[1].vy = +256;
			   balls[1].free = false;
			   balls[1].type = 0;
			   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
			}   
			
			//Phhase de retour a la position centrale
			if(timeBalls > 90 && timeBalls < 120)
		 		angle--;
		 		
		 	//On tire la 2ème boulette
		 	if(timeBalls == 150)
			{
			   //Boulette 3
			   balls[2].x = FIX(x);
			   balls[2].y = FIX(y+30);
			   balls[2].vx = 0;
			   balls[2].vy = +256;
			   balls[2].free = false;
			   balls[2].type = 0;
			   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
			}
			
			if(timeBalls == 180)
			{			   
			   //Boulette 4
			   balls[3].x = FIX(x);
			   balls[3].y = FIX(y+30);
			   balls[3].vx = 0;
			   balls[3].vy = +256;
			   balls[3].free = false;
			   balls[3].type = 0;
				AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1); 
				
				angle = 511;
			}   
			
			//Phase de rotation droite
			if(timeBalls > 180 && timeBalls < 210)
		 		angle--;
		 	
		 	if(timeBalls == 240)
			{
			   //Boulette 1
			   balls[4].x = FIX(x+10);
			   balls[4].y = FIX(y+30);
			   balls[4].vx = +128;
			   balls[4].vy = +256;
			   balls[4].free = false;
			   balls[4].type = 0;
			   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
			}
			
			if(timeBalls == 270)
			{
			 	//Boulette 2
			   balls[5].x = FIX(x+10);
			   balls[5].y = FIX(y+30);
			   balls[5].vx = +128;
			   balls[5].vy = +256;
			   balls[5].free = false;
			   balls[5].type = 0;
				AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1); 
			}
			
			//Phhase de retour a la position centrale
			if(timeBalls > 270 && timeBalls < 300)
		 		angle++; 
		 	
		 	if(timeBalls == 300)
		 		angle = 0;
		 	
		 	//Test des limites
		 	if(angle < 0)
		 		angle = 0;
		 	if(angle > 511)
		 		angle = 511;		 
		}
		if(sequence == 3)
		{
		   //Dash
		
		}
		if(sequence == 2)
		{
		   //Big Balls
		   //Calcul de l'angle
		   newAngle = PA_GetAngle(UNFIX(worldMan->hero->x)+16, UNFIX(worldMan->hero->y)+16, x+8, y);
			if(newAngle <= 128)
			{
				newAngle = 128-newAngle;
			}			
			if(newAngle > 128)
			{
				newAngle = 511+(128-newAngle);
			}			
			
			
			//On lisse l'angle
			angle = newAngle;
			
			//On effectue 3 Tirs
			int timeBalls = timer-660;
			
			if(timeBalls == 80 )
			{
			   //Boulette 2
				balls[6].vx = worldMan->hero->x+32 - FIX(x);
				balls[6].vy = worldMan->hero->y+32 - FIX(y);
				int norme = UNFIX(hwSqrt64(balls[6].vx*balls[6].vx + balls[6].vy*balls[6].vy));
				balls[6].vx = balls[6].vx/norme;
				balls[6].vy = balls[6].vy/norme;
				balls[6].x = FIX(x+ UNFIX(balls[6].vx*32));
				balls[6].y = FIX(y+ UNFIX(balls[6].vy*32));	
			   balls[6].free = false;
			   balls[6].type = 1;
			   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
			}
			
			if(timeBalls == 160 )
			{
			   //Boulette 2
				balls[7].vx = worldMan->hero->x+32 - FIX(x);
				balls[7].vy = worldMan->hero->y+32 - FIX(y);
				int norme = UNFIX(hwSqrt64(balls[7].vx*balls[7].vx + balls[7].vy*balls[7].vy));
				balls[7].vx = balls[7].vx/norme;
				balls[7].vy = balls[7].vy/norme;
				balls[7].x = FIX(x+ UNFIX(balls[7].vx*32));
				balls[7].y = FIX(y+ UNFIX(balls[7].vy*32));	
			   balls[7].free = false;
			   balls[7].type = 1;
			   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
			}
			
			if(timeBalls == 240 )
			{
			   //Boulette 2
				balls[8].vx = worldMan->hero->x+32 - FIX(x);
				balls[8].vy = worldMan->hero->y+32 - FIX(y);
				int norme = UNFIX(hwSqrt64(balls[8].vx*balls[8].vx + balls[8].vy*balls[8].vy));
				balls[8].vx = balls[8].vx/norme;
				balls[8].vy = balls[8].vy/norme;
				balls[8].x = FIX(x+ UNFIX(balls[8].vx*32));
				balls[8].y = FIX(y+ UNFIX(balls[8].vy*32));	
			   balls[8].free = false;
			   balls[8].type = 1;
			   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
			}
			
			if(timeBalls == 320 )
			{
			   //Boulette 2
				balls[9].vx = worldMan->hero->x+32 - FIX(x);
				balls[9].vy = worldMan->hero->y+32 - FIX(y);
				int norme = UNFIX(hwSqrt64(balls[9].vx*balls[9].vx + balls[9].vy*balls[9].vy));
				balls[9].vx = balls[9].vx/norme;
				balls[9].vy = balls[9].vy/norme;
				balls[9].x = FIX(x+ UNFIX(balls[9].vx*32));
				balls[9].y = FIX(y+ UNFIX(balls[9].vy*32));	
			   balls[9].free = false;
			   balls[9].type = 1;
			   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
			}
			   
		}
		
		//On update les boulettes
		for(int k = 0; k < 12; k++)
		{
			if(balls[k].free == false && life > 0)
			{
			   if(balls[k].type == 0)
			   {
					balls[k].x += balls[k].vx;
					balls[k].y += balls[k].vy;
				}
				else
				{
				   balls[k].x += balls[k].vx*2;
					balls[k].y += balls[k].vy*2;
				}							
							 
			   //Vérif des limites
			   if(balls[k].x < x-FIX(256))
			   	balls[k].free = true;
				if(balls[k].y < y-FIX(192))
			   	balls[k].free = true;
			}      
		}	   
	}			
}

void eBoss2::CheckInteractions()
{
	//Attaques provenant du héros
	if(life > 0)
	{
	   hitTime--;
	   if(hitTime < 0)
	   	hitTime = 0;
		//On vérifie les collisions entre les fireballs et le heros
	   //Collision avec les fireballs du héros
		for(int k = 0; k < BULLETMAX; k++)
		{
		   if(worldMan->hero->bullets[k].actif == true)
		   {
		   	if(RectCollision(worldMan->hero->bullets[k].x, worldMan->hero->bullets[k].y, &worldMan->hero->bullets[k].rect, x, y, &rect) )
		   	{
			   	if(hitTime == 0)
					{
						hitTime = 10;
						//On fait perdre de la vie aussi
						life -= 5;
						hit = true;
						worldMan->hero->bullets[k].actif = false;
					}
		      }						  
		   }   
		} 
	
	   //On vérifie les collisions entre les boulettes et le hero
	   for(int k = 0; k < 12; k++)
	   {
	   	if(balls[k].free == false)
	   	{
	   	   if(balls[k].type == 0)
	   	   {
		   	   if(RectCollision(UNFIX(balls[k].x), UNFIX(balls[k].y), &balls[k].rect, UNFIX(worldMan->hero->x), UNFIX(worldMan->hero->y), &worldMan->hero->rect) )
		   	   {
			   	   if(worldMan->hero->dontHitTime == -1)
						{
							worldMan->hero->dontHitTime = 30;
							worldMan->hero->dontMoveTime = 3;
							//On fait perdre de la vie aussi
							worldMan->hero->life -= 10; 
						}
		         }
				}
				if(balls[k].type == 1)
	   	   {
		   	   if(RectCollision(UNFIX(balls[k].x), UNFIX(balls[k].y), &balls[k].rectbig, UNFIX(worldMan->hero->x), UNFIX(worldMan->hero->y), &worldMan->hero->rect) )
		   	   {
			   	   if(worldMan->hero->dontHitTime == -1)
						{
							worldMan->hero->dontHitTime = 30;
							worldMan->hero->dontMoveTime = 3;
							//On fait perdre de la vie aussi
							worldMan->hero->life -= 20; 
						}
		         }
				}									  
	   	}   
	   }			  
	}   
}   

void eBoss2::Destroy()
{
   
}
