import java.awt.Graphics;
import java.awt.Color;
import java.awt.Polygon;
import Sounds;

public class Asteroid extends Flying
{
 Polygon shape;
 int     aWidth;
 int     aHeight;
 double  angle;
 double  middleX;
 double  middleY;
 double  speedX;
 double  speedY;
 int     speedZ;
 int     crashStadium;
 public Polygon sprite;
 public int     shield;
 public int     zLevel;
 public boolean shown;
 public boolean dangerous;
 public boolean crashing;

 public Asteroid(int gameWidth, int gameHeight)
 {
  zLevel    = 0;
  aWidth    = gameWidth;
  aHeight   = gameHeight;
  shown     = false;
  crashing  = false;
  dangerous = false;
  shield    = 0;
 }

 public void start(int speedZ)
 {
  if(!shown)
  {
   shape = new Polygon();
   shape.addPoint((int)((Math.random()-0.5)*10),
    (int)((Math.random()-0.5)*10)-24);
   shape.addPoint((int)((Math.random()-0.5)*10)+8,
    (int)((Math.random()-0.5)*10)-16);
   shape.addPoint((int)((Math.random()-0.5)*10)+16,
    (int)((Math.random()-0.5)*10)-16);
   shape.addPoint((int)((Math.random()-0.5)*10)+16,
    (int)((Math.random()-0.5)*10)-8);
   shape.addPoint((int)((Math.random()-0.5)*10)+24,
    (int)((Math.random()-0.5)*10));
   shape.addPoint((int)((Math.random()-0.5)*10)+16,
    (int)((Math.random()-0.5)*10)+8);
   shape.addPoint((int)((Math.random()-0.5)*10)+16,
    (int)((Math.random()-0.5)*10)+16);
   shape.addPoint((int)((Math.random()-0.5)*10)+8,
    (int)((Math.random()-0.5)*10)+16);
   shape.addPoint((int)((Math.random()-0.5)*10),
    (int)((Math.random()-0.5)*10)+24);
   shape.addPoint((int)((Math.random()-0.5)*10)-8,
    (int)((Math.random()-0.5)*10)+16);
   shape.addPoint((int)((Math.random()-0.5)*10)-16,
    (int)((Math.random()-0.5)*10)+16);
   shape.addPoint((int)((Math.random()-0.5)*10)-16,
    (int)((Math.random()-0.5)*10)+8);
   shape.addPoint((int)((Math.random()-0.5)*10)-24,
    (int)((Math.random()-0.5)*10));
   shape.addPoint((int)((Math.random()-0.5)*10)-16,
    (int)((Math.random()-0.5)*10)-8);
   shape.addPoint((int)((Math.random()-0.5)*10)-16,
    (int)((Math.random()-0.5)*10)-16);
   shape.addPoint((int)((Math.random()-0.5)*10)-8,
    (int)((Math.random()-0.5)*10)-16);

   angle        = 0;
   middleX      = aWidth / 2;
   middleY      = aHeight / 2;
   this.speedZ  = speedZ;
   zLevel       = 1;
   shown        = true;
   dangerous    = false;
   crashing     = false;
   crashStadium = 0;
   shield       = 10;
   speedX       = 0;
   speedY       = 0;
   while(speedX == 0 && speedY == 0)
   {
    speedX = (Math.random()-0.5)*speedZ*2.2*speedZ;
    speedY = (Math.random()-0.5)*speedZ*2.2*speedZ;
   }
   render();
  }
 }

 public void move()
 {
  if(shown)
  {
   angle   += 0.02;
   middleX += speedX;
   middleY += speedY;
   zLevel  += speedZ;
   speedX *= 1.016;
   speedY *= 1.016;
   if(middleX < -50 || middleX > aWidth + 50
    || middleY < -50 || middleY > aHeight + 50)
   {
    shown = false;
   }
   if(zLevel >= 100)
   {
    dangerous = true;
   }
   if(crashing && crashStadium < 40)
   {
    crashStadium += 1;
   }
   render();
  }
 }

 public void paint(Graphics g)
 {
  if(shown)
  {
   if(crashing)
   {
    g.setColor(new Color(0x3f3f3f));
    g.fillPolygon(sprite);
    g.setColor(Color.gray);
    g.drawPolygon(sprite);
    middleX += crashStadium + 10;
    render();
    g.setColor(new Color(0x3f3f3f));
    g.fillPolygon(sprite);
    g.setColor(Color.gray);
    g.drawPolygon(sprite);
    middleY += crashStadium + 10;
    render();
    g.setColor(new Color(0x3f3f3f));
    g.fillPolygon(sprite);
    g.setColor(Color.gray);
    g.drawPolygon(sprite);
    middleX -= crashStadium * 2 + 20;
    render();
    g.setColor(new Color(0x3f3f3f));
    g.fillPolygon(sprite);
    g.setColor(Color.gray);
    g.drawPolygon(sprite);
    middleY -= crashStadium * 2 + 20;
    render();
    g.setColor(new Color(0x3f3f3f));
    g.fillPolygon(sprite);
    g.setColor(Color.gray);
    g.drawPolygon(sprite);
    middleX += crashStadium + 10;
    middleY += crashStadium + 10;
    render();
   }
   else
   {
    if(dangerous)
    {
     g.setColor(new Color(0x414141));
    }
    else if(zLevel > 50)
    {
     g.setColor(new Color(0x3a3a3a));
    }
    else
    {
     g.setColor(new Color(0x333333));
    }
    g.fillPolygon(sprite);
    g.setColor(Color.gray);
    g.drawPolygon(sprite);
   }
  }
 }

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

   if(shield >= 5)
   {
    g.setColor(new Color(0x00AA00));
   }
   else
   {
    g.setColor(new Color(0xBB0000));
   }
   g.fillRect((int)middleX-5, (int)middleY-11, shield, 3);
   if(dangerous && !crashing)
   {
    g.setColor(new Color(0xcdbb88));
   }
   else
   {
    g.setColor(Color.gray);
   }
   g.drawRect((int)middleX-5, (int)middleY-11, 10, 3);
  }
 }

 public void crash()
 {
  if(shown && !crashing)
  {
   Sounds.play(Sounds.asteroid);
   dangerous    = false;
   crashing     = true;
   crashStadium = 1;
   shield       = 0;
   while(speedX < 0.75 && speedX > -0.75
    && speedY < 0.75 && speedY > -0.75)
   {
    speedX *= 1.5;
    speedY *= 1.5;
   }
  }
 }

 public boolean hit(int impact)
 {
  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(crashing)
  {
   if(zLevel < 75)
   {
    for(int i = 0; i < shape.npoints; i++)
    {
     sprite.addPoint((int)(Math.round(shape.xpoints[i]*cos_a + shape.ypoints[i]*sin_a)*zLevel/500 + middleX),
      (int)(Math.round(shape.ypoints[i]*cos_a - shape.xpoints[i]*sin_a)*zLevel/500 + 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)/6 + middleX),
      (int)(Math.round(shape.ypoints[i]*cos_a - shape.xpoints[i]*sin_a)/6 + middleY));
    }
   }
  }
  else if(zLevel < 100)
  {
   for(int i = 0; i < shape.npoints; i++)
   {
    sprite.addPoint((int)(Math.round(shape.xpoints[i]*cos_a*zLevel/100 + shape.ypoints[i]*sin_a*zLevel/100) + middleX),
     (int)(Math.round(shape.ypoints[i]*cos_a*zLevel/100 - 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));
   }
  }
 }
}