import java.applet.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.text.*; import java.util.*; import java.util.zip.*; import netscape.javascript.*; import javax.comm.*; import javax.sound.midi.*; import javax.sound.midi.spi.*; import javax.sound.sampled.*; import javax.sound.sampled.spi.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; import javax.xml.transform.sax.*; import javax.xml.transform.stream.*; import org.xml.sax.*; import org.xml.sax.ext.*; import org.xml.sax.helpers.*; public class SpringIcosahedron extends BApplet {PSystem ps;

class CrossParticle extends Particle {
public CrossParticle() {}
  void draw() {
    push();
    translate(pos[0], pos[1], pos[2]);
    stroke(255, 0, 0, 100);
    line(0, -10, 0, 10);
    line(-10, 0, 10, 0);
    pop();
  }
}

class RectParticle extends Particle {
public RectParticle() {}
  void draw() {
    if (pos[1] > -5) {
      if (this != a || !mouseDown) {
        pos[1] = -5;
        velocity[1] = -velocity[1];
      }
    }
  
    push();
    stroke(100, 100, 100, 100);
    translate(pos[0], pos[1], pos[2]);
    if (fixed()) {
      fill(0xffFF0000);
    }
    else {
      fill(0xffDDDDDD);
    }
    box(10, 10, 10);
    pop();
  }
}


Particle[] icosahedron(Particle parent, float scale) {
  final float X = .525731112119133606f;
  final float Z = .850650808352039932f;

  final float vdata[][] = {
    {-X, 0.0f, Z}, {X, 0.0f, Z}, {-X, 0.0f, -Z}, {X, 0.0f, -Z},
    {0.0f, Z, X}, {0.0f, Z, -X}, {0.0f, -Z, X}, {0.0f, -Z, -X},
    {Z, X, 0.0f}, {-Z, X, 0.0f}, {Z, -X, 0.0f}, {-Z, -X, 0.0f}};

  Particle particles[] = new Particle[12];

  int i;
  particles[0] = parent;
  parent.setPos(scale*vdata[0][0], scale*vdata[0][1], scale*vdata[0][2]);
  for (i = 1; i < 12; i++) {
    particles[i] = new RectParticle();
    particles[i].setPos(scale*vdata[i][0], scale*vdata[i][1], scale*vdata[i][2]);
    ps.addParticle(particles[i]);
  }
  
  for (i = 11; i > 0; i--) {
    for (int j = i-1; j >= 0; j--) {
      ps.addSpring(particles[i], particles[j]);
    }
  }
  return particles;
}


Particle a;
Spring mouseSpring;
Particle mouseParticle;
boolean mouseDown = false;
Particle[] particles;


void setup() {
  ps = (PSystem)loadPlugin("PSystem");

  size(450,450);
  translate(width/2, height/2);

  mouseParticle = new CrossParticle();
  mouseParticle.fix();
  ps.addParticle(mouseParticle);

  a = new RectParticle();
  a.setPos(0, 5, 0);
  ps.addParticle(a);
  
  ps.setGravity(0.6f);
  ps.defaultSpringRestLength = 100;
  ps.defaultSpringStrength = 0.6f;
  ps.defaultSpringDamping = 0.07f;

  particles = icosahedron(a, 100);
  
  mouseSpring = ps.addSpring(a, mouseParticle);
  mouseSpring.restLength = 0;
}



void mouseDragged() {
  mouseParticle.setPos(mouseX - width/2, mouseY - height/2, 0);
}

void mousePressed() {
  mouseDown = true;
  mouseParticle.setPos(mouseX - width/2, mouseY - height/2, 0);
  mouseParticle.fix();
}

void mouseReleased() {
  mouseDown = false;
  mouseParticle.unfix();
}


void loop() {
  background(0xff99CCCC);
  translate(width/2, height/2);
  color(100, 200, 100, 100);
  ps.draw();
  
  rotateX(PI/2);
  fill(100, 100, 100, 100);
  rect(-250, -250, 500, 500);
}


}