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.*; 

public class bounceLines extends BApplet {
float bounceFactor = 5;
int particleCount = 30;
Particle[] p = new Particle[particleCount];

void setup()
{
  size(500,500);
  background(223,218,228);
  noStroke();
  ellipseMode(CENTER_RADIUS);  
  for (int i = 0; i < p.length; i++)
  {
    p[i] = new Particle();
  }
}

void loop()
{
  float x;
  float y;

//  environment.draw();

  for (int i = 0; i < p.length; i++)
  {
    p[i].moveX();
    p[i].moveY();
    if (i < (p.length - 1))
    {
      stroke(255);
      line(p[i].x , p[i].y, p[i+1].x, p[i+1].y);
      noStroke();
    }

  }  
    
  for (int i = 0; i < p.length; i++)
    p[i].draw();
  
}


class Particle
{
  private float xVel = 0.0f;
  private float yVel = 0.0f;
  public float x = 200;
  public float y = 200;
  private float friction = 1.05f;
  private ColorTuple myColor;
  private ColorTuple[] colors = makeColors();
  
  private ColorTuple[] makeColors()
  { 
    ColorTuple[] c = new ColorTuple[10];
    int i = 0;
    
    c[i++] = new ColorTuple(134, 123, 117);
    c[i++] = new ColorTuple(50, 31, 33);
    c[i++] = new ColorTuple(159, 130, 135);
    c[i++] = new ColorTuple(86, 75, 64);
    c[i++] = new ColorTuple(119, 99, 62);
    c[i++] = new ColorTuple(211, 198, 189);
    c[i++] = new ColorTuple(86,93,101);
    c[i++] = new ColorTuple(155, 84, 2);
    c[i++] = new ColorTuple(162, 111, 54);
    c[i++] = new ColorTuple(79, 90, 96);
    return c;
  }
  
  
  public Particle()
  {
    myColor = colors[(int)random(colors.length)];
  }

  public float moveX()
  {
    x += xVel;
    if (collision(x, width))
    {
      xVel = -xVel;
      x+= xVel;
    }
    xVel /= friction;
    return x;
  }

  public float moveY()
  {
    y += yVel;
    if (collision(y, height))
    {
      yVel = -yVel;
      y+= yVel;
    }
    yVel /= friction;
    checkVelocities();
    return y;
  }
  
  private boolean collision(float value, int upperBound)
  {
    boolean result = false;
    if (value <= 0.0f)
    {
      result = true;
    }
    else if (value >= upperBound)
    {
      result = true;
    }
    return result;
  }

  private void checkVelocities()
  {
    float totalVel = abs(xVel) + abs(yVel);
    if (totalVel < .3f)
    {
      xVel = random(bounceFactor*2) - bounceFactor;
      yVel = random(bounceFactor*2) - bounceFactor;
    }
  }
  
  public void draw()
  {
    myColor.setFill();
    ellipse(x, y, 10, 10); 
    fill(255, 255, 255);
    ellipse(x, y, 5, 5); 
  }
}


class ColorTuple
{
  private int myR;
  private int myG;
  private int myB;
  
  public ColorTuple(int r, int g, int b)
  {
    myR = r;
    myG = g;
    myB = b;
  }
  
  public void setFill()
  {
    fill(myR, myG, myB);
  }
}

}
