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

public class Interceptor extends Flying
{
 Polygon     shape;
 Ship        ship;
 Explosion[] explosions;
 int     aWidth;
 int     aHeight;
 double  angle;
 double  genSpeedX;
 double  genSpeedY;
 double  middleX;
 double  middleY;
 double  speedX;
 double  speedY;
 int     speedZ;
 int     cannon1X;
 int     cannon1Y;
 int     cannon2X;
 int     cannon2Y;
 int     crashStadium;
 public LaserShot[] shots;
 public Polygon     sprite;
 public int         shield;
 public int         zLevel;
 public boolean     shown;
 public boolean     dangerous;
 public boolean     crashing;

 public Interceptor(int gameWidth, int gameHeight, Ship ship)
 {
  zLevel    = 0;
  aWidth    = gameWidth;
  aHeight   = gameHeight;
  shown     = false;
  crashing  = false;
  dangerous = false;
  shield    = 0;
  this.ship = ship;
  explosions = new Explosion[2];
  shots     = new LaserShot[2];
  for(int i = 0; i < 2; i++)
  {
   shots[i] = new LaserShot(Color.green, false);
   explosions[i] = new Explosion();
  }
 }

 public void start()
 {
  if(!shown && !crashing)
  {
   shape = new Polygon();
   shape.addPoint(0, -3);
   shape.addPoint(3, -2);
   shape.addPoint(6, -6);
   shape.addPoint(12, -9);
   shape.addPoint(18, -6);
   shape.addPoint(21, -2);
   shape.addPoint(20, -6);
   shape.addPoint(17, -12);
   shape.addPoint(12, -14);
   shape.addPoint(14, -16);
   shape.addPoint(21, -12);
   shape.addPoint(22, -9);
   shape.addPoint(24, 0);
   shape.addPoint(22, 9);
   shape.addPoint(21, 12);
   shape.addPoint(14, 16);
   shape.addPoint(12, 14);
   shape.addPoint(17, 12);
   shape.addPoint(20, 6);
   shape.addPoint(21, 2);
   shape.addPoint(18, 6);
   shape.addPoint(12, 9);
   shape.addPoint(6, 6);
   shape.addPoint(3, 2);
   shape.addPoint(0, 3);
   shape.addPoint(-3, 2);
   shape.addPoint(-6, 6);
   shape.addPoint(-12, 9);
   shape.addPoint(-18, 6);
   shape.addPoint(-21, 2);
   shape.addPoint(-20, 6);
   shape.addPoint(-17, 12);
   shape.addPoint(-12, 14);
   shape.addPoint(-14, 16);
   shape.addPoint(-21, 12);
   shape.addPoint(-22, 9);
   shape.addPoint(-24, 0);
   shape.addPoint(-22, -9);
   shape.addPoint(-21, -12);
   shape.addPoint(-14, -16);
   shape.addPoint(-12, -14);
   shape.addPoint(-17, -12);
   shape.addPoint(-20, -6);
   shape.addPoint(-21, -2);
   shape.addPoint(-18, -6);
   shape.addPoint(-12, -9);
   shape.addPoint(-6, -6);
   shape.addPoint(-3, -2);

   speedZ    = 1;
   zLevel    = 1;
   shown     = true;
   crashing  = false;
   dangerous = false;
   angle     = 0;
   shield    = 1;
   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;
   }
   middleX   = aWidth / 2;
   middleY   = aHeight / 2;
   render();
  }
 }

 public void move()
 {
  for(int i = 0; i < 2; i++)
  {
   explosions[i].go();
   shots[i].move();
  }
  if(shown || crashing)
  {
   zLevel  += 1;
   middleX += speedX + genSpeedX;
   middleY += speedY + genSpeedY;
   genSpeedX *= 1.014;
   genSpeedY *= 1.014;
   if(crashing)
   {
    angle += 0.03;
    if(explosions[0].exploding)
    {
     explosions[0].middleX = cannon1X + (int)genSpeedX;
     explosions[0].middleY = cannon1Y + (int)genSpeedY;
     explosions[1].middleX = cannon2X + (int)genSpeedX;
     explosions[1].middleY = cannon2Y + (int)genSpeedY;
    }
    if(shown && explosions[0].stadium > 35)
    {
     shown = false;
    }
   }
   else
   {
    if(Math.random() < 0.01)
    {
     speedX = 2.5;
     speedY = 0;
    }
    if(Math.random() < 0.01)
    {
     speedX = -2.5;
     speedY = 0;
    }
    if(Math.random() < 0.01)
    {
     speedY = 2.5;
     speedX = 0;
    }
    if(Math.random() < 0.01)
    {
     speedY = -2.5;
     speedX = 0;
    }
    if(speedX == 2.5)
    {
     angle = Math.PI / 8;
    }
    else if(speedX == -2.5)
    {
     angle = Math.PI / -8;
    }
    else
    {
     angle = 0;
    }
   }
   if(!crashing && zLevel > 50 && ship.alive
    && !shots[0].shooting
    && Math.pow(ship.middleX-(int)middleX, 2)
     + Math.pow(ship.middleY-(int)middleY, 2)
     <= 900 * zLevel)
   {
    Sounds.play(Sounds.laser);
    shots[0].shoot(cannon1X, cannon1Y,
     ship.middleX + (int)(Math.random()*-10), ship.middleY);
    shots[1].shoot(cannon2X, cannon2Y,
     ship.middleX + (int)(Math.random()*10), ship.middleY);
   }
   if(middleX < -20 || middleX > aWidth + 20
    || middleY < -20 || middleY > aHeight + 20
    || explosions[0].stadium > 72)
   {
    shown    = false;
    crashing = false;
   }
   render();
  }
 }

 public void paint(Graphics g)
 {
  if(shown)
  {
   if(crashing)
   {
    g.setColor(new Color(0x303040));
   }
   else
   {
    g.setColor(new Color(0x303080));
   }
   g.fillPolygon(sprite);
   g.setColor(new Color(0x999999));
   g.drawPolygon(sprite);
  }
  for(int i = 0; i < 2; i++)
  {
   shots[i].paint(g);
   explosions[i].paint(g);
  }
 }

 public void paintBar(Graphics g)
 {
  if(shown && shield != 0 && zLevel > 25)
  {
   g.setColor(Color.black);
   g.fillRect((int)middleX - 5, (int)middleY - 12, 10, 3);
   g.setColor(new Color(0x00AA00));
   g.fillRect((int)middleX - 5, (int)middleY - 12, shield*10, 3);
   if(!crashing && zLevel >= 100)
   {
    g.setColor(new Color(0xcdbb88));
   }
   else
   {
    g.setColor(Color.gray);
   }
   g.drawRect((int)middleX - 5, (int)middleY - 12, 10, 3);
  }
 }

 public void crash()
 {
  if(shown && !crashing)
  {
   Sounds.play(Sounds.enemy);
   crashing  = true;
   genSpeedX *= 1.5;
   genSpeedY *= 1.5;
   speedX    /= 2;
   speedY    /= 2;
   shield    = 0;
   explosions[0].explode(cannon1X, cannon1Y, 38);
   explosions[1].explode(cannon2X, cannon2Y, 38);
  }
 }

 public boolean hit(int impact)
 {
  if(shown)
  {
   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));
   }
   cannon1X = (int)(-12*cos_a*zLevel/100 + middleX);
   cannon1Y = (int)( 12*sin_a*zLevel/100 + middleY);
   cannon2X = (int)( 12*cos_a*zLevel/100 + middleX);
   cannon2Y = (int)(-12*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));
   }
   cannon1X = (int)(-12*cos_a + middleX);
   cannon1Y = (int)( 12*sin_a + middleY);
   cannon2X = (int)( 12*cos_a + middleX);
   cannon2Y = (int)(-12*sin_a + middleY);
  }
 }

}