import java.awt.Color;
import java.awt.Polygon;
import java.awt.Graphics;
import Ship;
import LaserShot;
import Missile;
import Explosion;

public class HeavyFighter extends Flying
{
 Polygon     shape;
 Explosion[] explosions;
 Ship    ship;
 int     aWidth;
 int     aHeight;
 double  angle;
 double  genSpeedX;
 double  genSpeedY;
 double  middleX;
 double  middleY;
 double  speedX;
 double  speedY;
 int     crashStadium;
 int     shotToShoot;
 boolean[] missilesFired;
 public Missile[]   missiles;
 public LaserShot[] shots;
 public Polygon     sprite;
 public int         shield;
 public int         zLevel;
 public boolean     shown;
 public boolean     dangerous;
 public boolean     crashing;

 public HeavyFighter(int gameWidth, int gameHeight, Ship ship)
 {
  zLevel    = 0;
  aWidth    = gameWidth;
  aHeight   = gameHeight;
  shown     = false;
  crashing  = false;
  dangerous = false;
  shield    = 0;
  this.ship = ship;
  shots     = new LaserShot[5];
  missiles  = new Missile[1];
  missilesFired = new boolean[1];
  explosions    = new Explosion[3];
  for(int i = 0; i < 5; i++)
  {
   shots[i] = new LaserShot(new Color(0x00aa00), false);
  }
  for(int i = 0; i < 3; i++)
  {
   explosions[i] = new Explosion();
  }
  missiles[0] = new Missile(new Color(0x00aa00), ship);
  missilesFired[0] = false;
 }

 public void start()
 {
  if(!shown && !crashing)
  {
   shape = new Polygon();
   shape.addPoint(0, -5);
   shape.addPoint(5, -10);
   shape.addPoint(20, -5);
   shape.addPoint(30, -15);
   shape.addPoint(25, 0);
   shape.addPoint(15, 6);
   shape.addPoint(8, 8);
   shape.addPoint(0, 10);
   shape.addPoint(-8, 8);
   shape.addPoint(-15, 6);
   shape.addPoint(-25, 0);
   shape.addPoint(-30, -15);
   shape.addPoint(-20, -5);
   shape.addPoint(-5, -10);

   zLevel    = 1;
   shown     = true;
   crashing  = false;
   dangerous = false;
   angle     = 0;
   shield    = 16;
   speedX    = 0;
   speedY    = 0;
   genSpeedX = 0;
   genSpeedY = 0;
   while(genSpeedX == 0 && genSpeedY == 0)
   {
    genSpeedX = (Math.random()-0.5)*1.5;
    genSpeedY = (Math.random()-0.5)*1.5;
   }
   shotToShoot = 0;
   middleX     = aWidth / 2;
   middleY     = aHeight / 2;
   render();
  }
 }

 public void move()
 {
  if(shown || crashing)
  {
   zLevel  += 1;
   middleX += speedX + genSpeedX;
   middleY += speedY + genSpeedY;
   genSpeedX *= 1.014;
   genSpeedY *= 1.014;
   
   if(!shots[4].shooting && !crashing && zLevel > 50 && ship.alive
    && middleX > 10 && middleX < aWidth - 10
    && middleY > 10 && middleY < aHeight - 10)
   {
    if(Math.pow(ship.middleX-(int)middleX, 2)
     + Math.pow(ship.middleY-(int)middleY, 2)
     <= 525 * zLevel)
    {
     switch(shotToShoot)
     {
      case 0:
       shots[0].shoot(sprite.xpoints[7], sprite.ypoints[7],
        ship.middleX, ship.middleY);
       Sounds.play(Sounds.laser);
       break;
      case 1:
       shots[1].shoot(sprite.xpoints[8], sprite.ypoints[8],
        ship.middleX - 20, ship.middleY + 15);
       Sounds.play(Sounds.laser);
      case 2:
       shots[2].shoot(sprite.xpoints[6], sprite.ypoints[6],
        ship.middleX + 20, ship.middleY + 15);
       Sounds.play(Sounds.laser);
       break;
      case 3:
       shots[3].shoot(sprite.xpoints[9], sprite.ypoints[9],
        ship.middleX - 20, ship.middleY - 15);
       Sounds.play(Sounds.laser);
       break;
      case 4:
       shots[4].shoot(sprite.xpoints[5], sprite.ypoints[5],
        ship.middleX + 20, ship.middleY - 15);
       Sounds.play(Sounds.laser);
       break;
      case 5:
       shotToShoot = -1;
     }
     shotToShoot++;
    }
    else if(!missilesFired[0] && zLevel > 75)
    {
     missiles[0].shoot((int)middleX, (int)middleY, zLevel + 1);
     missilesFired[0] = true;
    }
   }
   if(crashing)
   {
    if(Math.random() < 0.7)
    {
     angle += 0.1;
    }
    else
    {
     angle -= 0.1;
    }
    if(explosions[0].exploding)
    {
     explosions[0].middleX = sprite.xpoints[12] + (int)genSpeedX;
     explosions[0].middleY = sprite.ypoints[12] + (int)genSpeedY;
     explosions[1].middleX = (int)middleX + (int)genSpeedX;
     explosions[1].middleY = (int)middleY + (int)genSpeedY;
     explosions[2].middleX = sprite.xpoints[2] + (int)genSpeedX;
     explosions[2].middleY = sprite.ypoints[2] + (int)genSpeedY;
    }
    if(shown && explosions[0].stadium > 35)
    {
     shown = false;
    }
   }
   else
   {
    speedX *= 0.93;
    speedY *= 0.93;
   }
   if(middleX < -40 || middleX > aWidth + 40
    || middleY < -40 || middleY > aHeight + 40
    || explosions[0].stadium > 77)
   {
    shown    = false;
    crashing = false;
   }
   render();
  }
  for(int i = 0; i < 5; i++)
  {
   shots[i].move();
  }
  for(int i = 0; i < 3; i++)
  {
   explosions[i].go();
  }
  missiles[0].move();
 }

 public void paint(Graphics g)
 {
  if(shown)
  {
   if(crashing)
   {
    g.setColor(new Color(0x253a25));
   }
   else
   {
    g.setColor(new Color(0x335033));
   }
   g.fillPolygon(sprite);
   g.setColor(new Color(0xaaaaaa));
   g.drawPolygon(sprite);
  }
  for(int i = 0; i < 5; i++)
  {
   shots[i].paint(g);
  }
  for(int i = 0; i < 3; i++)
  {
   explosions[i].paint(g);
  }
  missiles[0].paint(g);
 }

 public void paintBar(Graphics g)
 {
  if(shown && shield != 0 && zLevel > 25)
  {
   g.setColor(Color.black);
   g.fillRect((int)middleX - 5, (int)middleY - 20, 10, 3);

   if(shield >= 8)
   {
    g.setColor(new Color(0x00AA00));
   }
   else if(shield >= 5)
   {
    g.setColor(new Color(0xBBBB00));
   }
   else
   {
    g.setColor(new Color(0xBB0000));
   }
   g.fillRect((int)middleX - 5, (int)middleY - 20, shield*10/16, 3);
   if(!crashing && zLevel >= 100)
   {
    g.setColor(new Color(0xcdbb88));
   }
   else
   {
    g.setColor(Color.gray);
   }
   g.drawRect((int)middleX - 5, (int)middleY - 20, 10, 3);
  }
 }

 public void crash()
 {
  if(shown && !crashing)
  {
   Sounds.play(Sounds.enemy);
   crashing   = true;
   genSpeedX *= 1.5;
   genSpeedY *= 1.5;
   speedX    /= 4;
   speedY    /= 4;
   shield    = 0;
   missiles[0].crash();
   explosions[0].explode(sprite.xpoints[12], sprite.ypoints[12], 40);
   explosions[1].explode((int)middleX, (int)middleY, 40);
   explosions[2].explode(sprite.xpoints[2], sprite.ypoints[2], 40);
  }
 }

 public boolean hit(int impact)
 {
  if(shown)
  {
   if(Math.random() < 0.5)
   {
    speedX = (genSpeedX + speedX) * -1.4;
   }
   else
   {
    speedY = (genSpeedY + speedY) * -1.4;
   }
   shield -= impact;
   if(shield <= 0)
   {
    shield = 0;
    crash();
    return true;
   }
  }
  return false;
 }

 public boolean inside(int x, int y)
 {
  return shown && !crashing && zLevel > 25 && sprite.contains(x, y);
 }

 void render()
 {
  sprite = new Polygon();
  double sin_a = Math.sin(angle);
  double cos_a = Math.cos(angle);
  if(zLevel < 100)
  {
   for(int i = 0; i < shape.npoints; i++)
   {
    sprite.addPoint((int)(Math.round(shape.xpoints[i]*cos_a
     + shape.ypoints[i]*sin_a)*zLevel/100 + middleX),
     (int)(Math.round(shape.ypoints[i]*cos_a
     - shape.xpoints[i]*sin_a)*zLevel/100 + middleY));
   }
  }
  else
  {
   for(int i = 0; i < shape.npoints; i++)
   {
    sprite.addPoint((int)(Math.round(shape.xpoints[i]*cos_a
     + shape.ypoints[i]*sin_a) + middleX),
     (int)(Math.round(shape.ypoints[i]*cos_a
     - shape.xpoints[i]*sin_a) + middleY));
   }
  }
 }

}