import java.applet.*;
import java.awt.*;

public class Space extends Applet implements Runnable {
  Playfield bg;
  Thing objects[];
  Thread t;
  Image buffer;
  Vect2d grav1, grav2, grav3, grav4;
  final int num = 7, frame = 24;
  Thing drag;

  public void init() {
    Image planet[] = new Image[frame];
    Image ship[] = new Image[16];
    bg = new Playfield(getImage(getDocumentBase(), "stars2.gif"));
    objects = new Thing[num];

    for(int i=0; i<planet.length; i++)
      planet[i] = getImage(getDocumentBase(), "planet" + i + ".gif");

    for(int i=0; i<ship.length; i++)
      ship[i] = getImage(getDocumentBase(), "ship" + i + ".gif");

    objects[0] = new Thing(new Vect2d(0, 0), new Vect2d(-0.003265, 0), 1000,
			   planet, bg);
    objects[1] = new Thing(new Vect2d(100, 0), new Vect2d(0, 3), 1,
			   ship, bg);
    objects[2] = new Thing(new Vect2d(-150, 0), new Vect2d(0, -2), 1,
			   ship, bg);
    objects[3] = new Thing(new Vect2d(0, 150), new Vect2d(2.9, 0), 1,
			   ship, bg);
    objects[6] = new Thing(new Vect2d(0, -175), new Vect2d(2, 0), 20,
			   getImage(getDocumentBase(), "moon.gif"), bg);
    objects[4] = new Thing(new Vect2d(-200, 0), new Vect2d(0, -2), 1,
			   ship, bg);
    objects[5] = new Thing(new Vect2d(0, 100), new Vect2d(2, 0), 1,
			   ship, bg);
    for(int i=0; i<num; i++) {
      bg.addSprite(objects[i]);
      objects[i].render();
    }

    drag = null;
  }

  public void start() {
    t = new Thread(this);
    //t.setPriority(Thread.MAX_PRIORITY);
    t.start();
    bg.Draw();
    buffer = bg.toImage();
    repaint();
  }

  public void run() {
    while(true) {
      try {
	Thread.sleep(10);
      } catch (InterruptedException e) {
      }

      for(int i=0; i<num; i++) {
	Vect2d grav = new Vect2d();

	for(int j=0; j<num; j++) {
	  Vect2d force = new Vect2d(objects[j].pos.x, objects[j].pos.y);

	  force.sub(objects[i].pos);
	  force.scale(-objects[j].mass);
	  grav.add(force);
	}

	//System.out.println("g" + i + " "+ grav.x + " " + grav.y);
	if(bg.whatIsHere(objects[i].x, objects[i].y) != objects[i])
	  objects[i].destroy();

	objects[i].update(grav);
	objects[i].move();
      }
      objects[0].nextState();

      for(int i=1; i<6; i++) {
	double dir = objects[i].vel.getDir();

	dir /= Math.PI;
	dir *= 8;

	objects[i].setState((int)(8.5+dir));
      }

      bg.Draw();
      //buffer = null;
      //System.gc();
      //buffer = bg.toImage();
      bg.mem.newPixels();
      repaint();
      //System.out.println("render " + new java.util.Date().getTime());
    }
  }

  public boolean mouseDown(Event evt, int x, int y) {
    Thing t = (Thing)bg.whatIsHere(x, y);

    if(t == null)
      return false;
    drag = t;

    return true;
  }

  public boolean mouseDrag(Event evt, int x, int y) {
    if(drag == null)
      return false;

    drag.move(x, y);
    return true;
  }

  public boolean mouseUp(Event evt, int x, int y) {
    if(drag == null)
      return false;

    drag.move(x, y);
    drag = null;
    return true;
  }

  public void paint(Graphics g) {
    g.drawImage(buffer, 0, 0, this);
    //System.out.println("paint " + new java.util.Date().getTime());
  }

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