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 undertow extends BApplet {
Circle circles[] = new Circle[20];
float centerX = 400;
float centerY = 400;
float limit = 100;

void setup()
{
  size(500,500);
  strokeWidth(3);
  framerate(40);
  ellipseMode(CENTER_DIAMETER);
  colorMode(HSB,100);
  background(96);
  initCircles();
  
}

void initCircles()
{
  for (int i = 0; i < circles.length; i++)
  {
    circles[i] = new Circle();
  }
}


void loop()
{
  for (int i = 0; i < circles.length; i++)
  {
    circles[i].draw();
  }
}

void kickBalls()
{
  for (int i = 0; i < circles.length; i++)
  {
    circles[i].kick();
  }
  
}


class Circle
{
  private float myX;
  private float myY;
  private float myRadius;
  private float xVel;
  private float yVel;
  private float myHue;
  private float mySaturation;
  
  public Circle()
  {
    myX = random(width);
    myY = random(height);
    myRadius = random(50) + 10;
    xVel = random(10) - 5;
    yVel = random(10) - 5;
    myHue = 30 + random(10);
    mySaturation = 5;
  }
  
  void draw()
  {
    push();
      move();
      checkForCollision();
        strokeWidth(2);
        stroke(90);
        float offset = myRadius/2;
        line(centerX,centerY,myX,myY);
        strokeWidth(3);
      translate(myX, myY);
      doFill();
      ellipse(0,0,myRadius, myRadius);
    pop();
    kickBalls();
  }
  
  void doFill()
  {
    float distanceFactor = 3 * (abs(xVel) + abs(yVel));
    float h = myHue + distanceFactor;
    float sat = mySaturation + distanceFactor;
    stroke(h, sat, 90);
  }
  
  void move()
  {
    myX += xVel;
    myY += yVel;
    xVel = xVel / 1.02f;
    yVel = yVel / 1.02f;
    
  }
  
  void kick()
  {
    float xDist = abs(myX - centerX);
    float yDist = abs(myY - centerY);
    float dist = sqrt((xDist * xDist) + (yDist * yDist));
    
    float force = 2/dist;
    float xForce = force * (xDist / (xDist+ yDist));
    float yForce = force * (yDist / (xDist+ yDist));
    
    
    if (centerX < myX)
    {
      xForce = -xForce;
    }
    
    if (centerY < myY)
    {
      yForce = -yForce;
    }

    xVel += xForce;
    if (xVel > limit)
    {
      xVel = limit;
    }
    if (xVel < -limit)
    {
      xVel = -limit;
    }
    yVel += yForce;
    if (yVel > limit)
    {
      yVel = limit;
    }
    if (yVel < -limit)
    {
      yVel = -limit;
    }
    
  }
  
  void checkForCollision()
  {
    if (myX < -400 || myX > (width + 400))
    {
      xVel = -xVel;
      myX += xVel;
    }
    if (myY < -400 || myY > (height + 400))
    {
      yVel = -yVel;
      myY += yVel;
    }
    
  }
}

}
