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

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

eBoss3::eBoss3()
{
	real = true;
	toDelete = false;
	stat = false;
	type = 2;
   genre = 0;
   explosionH = 0;
	explosionAlpha = 0; 
}
   	
eBoss3::~eBoss3()
{
   
}

void eBoss3::Load()
{
   //On charge les images
	ulSetTransparentColor(RGB15(31, 0, 31));
	body.assign(worldMan->resMan->LoadImage("efs:/Boss3_Body.png", UL_IN_VRAM, UL_PF_PAL4));
	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;
	canFireball = false;
	side = true;
	angle = 0;
	tour = false;
	actif = false;
	
	for(int k = 0; k < 12; k++)
	{
		balls[k].free = true;  
		balls[k].rect.x1 = 4; 
		balls[k].rect.y1 = 4; 
		balls[k].rect.x2 = 12; 
		balls[k].rect.y2 = 12; 
	}
	   
	//Parametrage des animations
	body.setFrameWH(32, 128);
	body.addAnim(0, 0, 5, 7);
	body.animLoop(0);
	rect.x1 = 3;
	rect.y1 = 23;
	rect.x2 = 28;
	rect.y2 = 59;
	orix = x;
	oriy = y;
	sprFx2.scale(32,32);
	sprFx2.setAlpha(true, 20);
	worldMan->screenAngle = 0;
}
   
void eBoss3::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 == 0)
   {
		body.setXY(x_screen, y_screen);
		body.play();
		body.mirror(side, false);
		body.draw();
		
		if(hit)
      {
	      sprFx2.setXY(x_screen, y_screen+48);
	      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);
			   bigball.setXY(UNFIX(bxscr), UNFIX(byscr));
				bigball.draw();
			}			
		}
	}
	if(act && layer == 1)
	{
		//Explosion
		if(life <= 0)
		{
		   if(explosionH > 0)
			{
				explosion.draw();
			}			 
		}     
	}   
}
   
void eBoss3::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;
	}   
	   
   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+16, y_screen-explosionH/2+32);
		explosion.setAlpha(true, UNFIX(explosionAlpha));
			
	}
	
   if(actif && isBossActivated)
   {
      worldMan->isFightingBoss = true;
		//On change de sens le boss
		if(x > UNFIX(worldMan->hero->x) )
			side = true;
		else
			side = false;
			
	   //Sequences d'attaque
	   if(life > 0)
	   	timer++;
	   
		if(life > 100)
		{
			//Idle
			if(timer < 180)
				sequence = 0;
			//Balls
			if(timer >= 180 && timer < 360)
				sequence = 1;
			//Idle
			if(timer >= 360 && timer < 540)
				sequence = 0;
			//Rotate
			if(timer >= 540 && timer < 850)
				sequence = 2;
			//Maj du timer
			if(timer >= 850)
				timer = 0;
		}
		if(life <= 100)
		{
			//Idle
			if(timer < 180)
				sequence = 0;
			//Balls
			if(timer >= 180 && timer < 360)
				sequence = 1;
			//Idle
			if(timer >= 360 && timer < 540)
				sequence = 0;
			//Move
			if(timer >= 540 && timer < 850)
				sequence = 2;
			//Torpille
			if(timer >= 850 && timer < 1210) // 6secs
				sequence = 3;
			//Maj du timer
			if(timer >= 1210)
				timer = 0;
		}
		//Programmation des séquences d'attaque
		if(life > 0 )
		{
			if(sequence == 0)
			{
				//Idle
				canFight = false;   //Le boss ne peut pas se saire toucher au CAC
				canFireball = true; //Le boss peut se faire toucher par les fireballs   
				tour = !tour;       //On inverse le tour de rotation
				x = orix;
				y = oriy;
			}
			if(sequence == 1)
			{
			 	//Balls
			 	int timeBalls = timer-180;
				
				if(timeBalls == 0)
				{
				   //Boulette 1
					balls[0].vx = worldMan->hero->x+16 - FIX(x+16);
					balls[0].vy = worldMan->hero->y+16 - FIX(y+32);
					int norme = UNFIX(hwSqrt64(balls[0].vx*balls[0].vx + balls[0].vy*balls[0].vy));
					balls[0].vx = balls[0].vx/norme;
					balls[0].vy = balls[0].vy/norme;
					balls[0].x = FIX(x+16);
					balls[0].y = FIX(y+32);	
				   balls[0].free = false;
				   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
				}
				if(timeBalls == 60)
				{
				   //Boulette 2
					balls[1].vx = worldMan->hero->x+32 - FIX(x+16);
					balls[1].vy = worldMan->hero->y+32 - FIX(y+32);
					int norme = UNFIX(hwSqrt64(balls[1].vx*balls[1].vx + balls[1].vy*balls[1].vy));
					balls[1].vx = balls[1].vx/norme;
					balls[1].vy = balls[1].vy/norme;
					balls[1].x = FIX(x+16);
					balls[1].y = FIX(y+32);	
				   balls[1].free = false;
				   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
				}
				if(timeBalls == 120)
				{
				   //Boulette 3
					balls[2].vx = worldMan->hero->x+32 - FIX(x+16);
					balls[2].vy = worldMan->hero->y+32 - FIX(y+32);
					int norme = UNFIX(hwSqrt64(balls[2].vx*balls[2].vx + balls[2].vy*balls[2].vy));
					balls[2].vx = balls[2].vx/norme;
					balls[2].vy = balls[2].vy/norme;
					balls[2].x = FIX(x+16);
					balls[2].y = FIX(y+32);	
				   balls[2].free = false;
				   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
				}
				if(timeBalls == 180)
				{
				   //Boulette 4
					balls[3].vx = worldMan->hero->x+32 - FIX(x+16);
					balls[3].vy = worldMan->hero->y+32 - FIX(y+48);
					int norme = UNFIX(hwSqrt64(balls[3].vx*balls[3].vx + balls[3].vy*balls[3].vy));
					balls[3].vx = balls[3].vx/norme;
					balls[3].vy = balls[3].vy/norme;
					balls[3].x = FIX(x+16);
					balls[3].y = FIX(y+48);	
				   balls[3].free = false;
				   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
				}
	
			}
			if(sequence == 2)
			{	   
			   //Deplacement
			   int timeMove = timer-540;
			   //Le monstre s'élève
				if(timeMove < 15)
					y -= 2;
				//Le monstre se déplace vers la gauche
				if(timeMove >= 15 && timeMove < 85)
					x -= 1;
				//Le monstre se déplace vers la droite
				if(timeMove >= 85 && timeMove < 225)
					x += 1;
				//Le monstre se déplace vers la gauche (retour pos originale)
				if(timeMove >= 225 && timeMove < 295)
					x -= 1;
				//Le monstre descend
				if(timeMove >=295 && timeMove < 310)
					y += 2;
			   					 
			}
			if(sequence == 3)
			{
			   //Torpille
			   int timeTorp = timer-850;
			   //Descente
			   if(timeTorp < 30)
			   	y += 4;
			   //Elevation Gauche
			   if(timeTorp == 30)
			   	x -= 85;
			   if(timeTorp >= 30 && timeTorp < 65)
			   	y -= 4;
			   //Descente
			   if(timeTorp >= 95 && timeTorp < 130)
			   	y += 4;
			   //Elevation Droite
			   if(timeTorp == 130)
			   	x += 85+100;
			   if(timeTorp >= 130 && timeTorp < 165)
			   	y -= 4;
			   //Descente
			   if(timeTorp >= 195 && timeTorp < 230)
			   	y += 4;
			   //Elevation Centrale
			   if(timeTorp == 230)
			   	x -= 85;
			   if(timeTorp >= 230 && timeTorp < 265)
			   	y -= 4;
			   //Descente
			   if(timeTorp >= 295 && timeTorp < 330)
			   	y += 4;
			   //Elevation retour posotion originale
			   if(timeTorp == 330)
			   	x = orix;
			   if(timeTorp >= 330 && timeTorp <= 360)
			   	y -= 4;
			}
		}		
		
		//On update les boulettes
		for(int k = 0; k < 12; k++)
		{
			if(balls[k].free == false && life > 0)
			{
			   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 eBoss3::CheckInteractions()
{
	//Attaques provenant du héros
	//ulDebug("life:%d\n", life);
	if(life > 0)
	{
	   hitTime--;
	   if(hitTime < 0)
	   	hitTime = 0;
	   	
		//On vérifie les collisions avec l'oeil
		if(worldMan->hero->isGroundBattle && canFight)
	   {
	   	if(worldMan->hero->sensH)
			{
				//Collision combo coup droit 
				if(hitTime == 0 && RectCollision(x, y, &rect, UNFIX(worldMan->hero->x), UNFIX(worldMan->hero->y), &worldMan->hero->rectBattleRight) )
				{
				   life -= 5;
				   hit = true;
					hitTime = 15; 
				}   
			}
			else
			{
			   //Collision combo coup gauche
				if(hitTime == 0 && RectCollision(x, y, &rect, UNFIX(worldMan->hero->x), UNFIX(worldMan->hero->y), &worldMan->hero->rectBattleLeft) )
				{
				   life -= 5;
				   hit = true;
				   hitTime = 15; 
				}
			}						 
	   }
	   
	   //Collision avec les fireballs du héros
	   if(canFireball)
	   {
			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(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; 
					}
	         }						  
	   	}   
	   }
		
		//Collisions entre le dash et le héros
		if(true)
		{
		   if(RectCollision(x, y, &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 -= 20; 
				}
	      }
		}
			  
	}   
}   

void eBoss3::Destroy()
{
   
}
