import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.util.*;

public class FLY3 extends Applet implements Runnable{
  Dimension d;  
  Thread tm;
  Random r = new Random();
  Image offI;
  int crashes=0;
  int speed=80;
  int DIR = 2;
  int altitude=25;
  boolean explode_now=false;
  int x_explode, y_explode, explode_cnt;
  int x_plane_body[] = { 10, 40, 7, 0, 10, 17, 10 };
  int y_plane_body[] = {  70, 55, 55, 65, 60, 60, 70 };
  int x_reset_body[] = { 10, 40, 7, 0, 10, 17, 10 };
  int y_reset_body[] = {  70, 55, 55, 65, 60, 60, 70 };
  int x_cockpit[] = { 20, 28, 40, 20 };
  int y_cockpit[] = { 55, 50, 55, 55 };
  int x_reset_cockpit[] = { 20, 28, 40, 20 };
  int y_reset_cockpit[] = { 55, 50, 55, 55 };
  int x_mtn[]={ 0,0,25,80,85,90,150,175,200,225,265,290,305,
                 340,360,415,425,435,500,500,0};
  int y_mtn[]={ 300,260,240,165,160,165,250,282,282,250,125,
                 120,125,250,250,170,178,170,280,300,300};
  int x_ball[] = {400,406,409,413,418,420,418,413,409,406,
                  400,394,391,387,382,380,382,387,391,394,400};
  int y_ball[] = { 10, 12, 16, 21, 25, 30, 35, 39, 43, 46,
                   50, 46, 43, 39, 35, 30, 25, 21, 16, 12, 10};
  int x_basket[] = {380, 400, 420, 405, 395, 380};
  int y_basket[] = { 65, 65,  65,  77,  77,  65};
  int r_ball[] = {400,406,409,413,418,420,418,413,409,406,
                  400,394,391,387,382,380,382,387,391,394,400};
  int r_basket[] = {380, 400, 420, 405, 395, 380};
  Point2D mountain[] = new Point2D[21];
  Point2D balloon[] = new Point2D[6];
  Image[] e;

  public void init(){
    d = getSize();
    for(int i = 0; i<x_mtn.length; i++){
      mountain[i] = new Point2D(x_mtn[i],y_mtn[i]);
    }
    setBalloonPts();
    offI=createImage(d.width,d.height);
    e=new Image[12];
    for(int i=0; i<11; i++){
      e[i]=getImage(getDocumentBase(), "cel"+(i+1)+".gif");
    }
    tm = new Thread(this);
    tm.start();
    requestFocus(); 
    this.addKeyListener(new KeyAdapter(){ 
      public void keyPressed(KeyEvent k) { 
        if(k.getKeyCode() == KeyEvent.VK_UP && y_plane_body[0]>5){
          for(int i = 0; i < y_plane_body.length; i++){
            y_plane_body[i]--;
          }
          for(int i = 0; i < y_cockpit.length; i++){
            y_cockpit[i]--;
          }
        } 
        else if(k.getKeyCode() == KeyEvent.VK_DOWN){
          for(int i = 0; i < y_plane_body.length; i++){
            y_plane_body[i]++;
          }
          for(int i = 0; i < y_cockpit.length; i++){
            y_cockpit[i]++;
          }
        }
        else if(k.getKeyCode() == KeyEvent.VK_LEFT){
          if(speed<150) speed+=10;
        }
        else if(k.getKeyCode() == KeyEvent.VK_RIGHT){
          if(speed>20) speed-=10;
        }
        repaint();
      }
    });
  }

  public boolean collision(){
     if(Tools2D.insidePolygon(new Point2D(x_plane_body[0],y_plane_body[0]), mountain))
       return true;
     else if(Tools2D.insidePolygon(new Point2D(x_plane_body[1],y_plane_body[1]), mountain))
       return true;
     setBalloonPts();
     if(Tools2D.insidePolygon(new Point2D(x_plane_body[0],y_plane_body[0]), balloon))
       return true;
     else if(Tools2D.insidePolygon(new Point2D(x_plane_body[1],y_plane_body[1]), balloon))
       return true;
     else return false;
  }

  public void setBalloonPts(){
     balloon[0] = new Point2D(x_ball[0],y_ball[0]);
     balloon[1] = new Point2D(x_ball[5],y_ball[5]);
     balloon[2] = new Point2D(x_basket[3],y_basket[3]);
     balloon[3] = new Point2D(x_basket[4],y_basket[4]);
     balloon[4] = new Point2D(x_ball[15],y_ball[15]);
     balloon[5] = new Point2D(x_ball[0],y_ball[0]);
  }

  public void reset(){
    x_explode = x_plane_body[0];
    y_explode = y_plane_body[0];
    for(int i = 0; i<x_reset_body.length; i++){
      x_plane_body[i] = x_reset_body[i];
      y_plane_body[i] = y_reset_body[i];
    }
    for(int i = 0; i<x_reset_cockpit.length; i++){
      x_cockpit[i] = x_reset_cockpit[i];
      y_cockpit[i] = y_reset_cockpit[i];
    }
    for(int i = 0; i<r_ball.length; i++){
      x_ball[i] = r_ball[i];
    }
    for(int i = 0; i<r_basket.length; i++){
      x_basket[i] = r_basket[i];
    }
    crashes++;
    explode_now=true;
    explode_cnt = 0;
    speed=80;
  }

  public void run(){
    while(true){
      repaint();
      if(!explode_now){
        for(int i = 0; i < x_plane_body.length; i++){
          x_plane_body[i] +=2;
        }
        for(int i = 0; i < x_cockpit.length; i++){
          x_cockpit[i] +=2;
        }
        for(int i = 0; i< x_basket.length; i++){
          x_basket[i] -=2;
        }
        for(int i = 0; i<x_ball.length; i++){
          x_ball[i] -=2;
        }
        if(x_plane_body[4]>d.width){
          for(int i = 0; i < x_plane_body.length; i++){
            x_plane_body[i] -= d.width+40;
          }
          for(int i = 0; i < x_cockpit.length; i++){
            x_cockpit[i] -= d.width+40;
          }
        }
        if(x_ball[5]<0){
          for(int i = 0; i< x_basket.length; i++){
            x_basket[i] +=d.width;
          }
          for(int i = 0; i<x_ball.length; i++){
            x_ball[i] +=d.width;
          }
        } 
        for(int i = 0; i< y_basket.length; i++){
          y_basket[i] += DIR;
        }
        for(int i = 0; i<y_ball.length; i++){
          y_ball[i] += DIR;
        }
        if(collision()) reset();
        if(y_ball[0]<3) DIR=1;
        else if(y_ball[0]>54) DIR=-1;
      }
      else{
        explode_cnt++;
        if(explode_cnt>10){
           explode_now=false;
           speed=80;
        }
      }
      try{
        Thread.sleep(speed);
      }catch(InterruptedException e){};
    }
  }

  public void update(Graphics g){
    paint(g);
  }

  public void paint(Graphics g){
    Graphics offG = offI.getGraphics();
    offG.setColor(Color.cyan);
    offG.fillRect(0,0,d.width,d.height);
    offG.setColor(new Color(100,150,50));
    Polygon mtn = new Polygon(x_mtn,y_mtn,x_mtn.length);
    offG.fillPolygon(mtn);
    if(!explode_now){
      Polygon planebody = new Polygon(x_plane_body, y_plane_body, x_plane_body.length);
      Polygon cockpit = new Polygon(x_cockpit, y_cockpit, x_cockpit.length);
      Polygon ball = new Polygon(x_ball, y_ball, x_ball.length);
      Polygon basket = new Polygon(x_basket, y_basket, x_basket.length);
      offG.setColor(Color.red);
      offG.fillPolygon(planebody);
      offG.setColor(Color.yellow);
      offG.fillPolygon(cockpit);
      offG.setColor(Color.green);
      offG.fillPolygon(ball);
      offG.setColor(Color.black);
      offG.drawLine(x_ball[7],y_ball[7],x_basket[2],y_basket[2]);
      offG.drawLine(x_ball[10],y_ball[10],x_basket[1],y_basket[1]);
      offG.drawLine(x_ball[13],y_ball[13],x_basket[0],y_basket[0]);
      offG.fillPolygon(basket);    
    }
    else{ // explosion
      offG.drawImage(e[explode_cnt], x_explode, y_explode-40, this);
    }

    offG.setColor(Color.red);
    offG.setFont(new Font("Courier", Font.BOLD, 24));
    offG.drawString("Crashes: " + crashes, d.width-180, d.height-10);
    g.drawImage(offI, 0, 0, this);
  }
}
