import processing.core.*; 
import processing.xml.*; 

import java.applet.*; 
import java.awt.Dimension; 
import java.awt.Frame; 
import java.awt.event.MouseEvent; 
import java.awt.event.KeyEvent; 
import java.awt.event.FocusEvent; 
import java.awt.Image; 
import java.io.*; 
import java.net.*; 
import java.text.*; 
import java.util.*; 
import java.util.zip.*; 
import java.util.regex.*; 

public class sketch_aug27c extends PApplet {


ArrayList<rainDrop> rainDrops = new ArrayList<rainDrop>();
float myAngle = 0;
final float ANGLE_CHANGE = 0.006f;
float rainChance = 0.0f;

public void setup()
{
  size (800,600,P3D);
  noFill();
  rainDrops.add( new rainDrop() );
}

public void draw()
{
  background(0);
  
  rotateScreen();
  
  for ( int i=0; i < rainDrops.size(); i++ )
  {
    rainDrop thisRainDrop = rainDrops.get(i);
    thisRainDrop.draw();
  }
  
  removeOldRainDrops();
  
  if ( random(0,100) < rainChance)
    rainDrops.add(new rainDrop());
  rainChance += 0.1f;
}

public void rotateScreen()
{
  myAngle += ANGLE_CHANGE;
  if(myAngle >= TWO_PI || myAngle < 0)
    myAngle = 0.0f;   
  
  translate(width/2, height/2);
  
  //rotateX(myAngle);
  rotateY(myAngle);
  //rotateZ(myAngle);
  scale(0.3f);
  
  translate(width/-2, height/-2);
  
}

public void removeOldRainDrops()
{
  int i=0;
  while ( i < rainDrops.size() )
  {    
    rainDrop thisRainDrop = rainDrops.get(i);
    
    if ( thisRainDrop.isFullyGrown() )
    {
      i=0;
      rainDrops.remove(thisRainDrop);
    }
    else
      i++;
  }  
}

class rainDrop
{
  private vertex myPosition = new vertex();
  private float myRadius = 1;
  private colour myColour = new colour();
  private float myMaxRadius = random(75,150);
  private float myFallSpeed = random(-10,10);
  
  public rainDrop()
  {    
  }
  
  public void draw()
  {
    stroke (myColour.r, myColour.g, myColour.b);
    
    translate(myPosition.x, myPosition.y, myPosition.z);    
    ellipse(0, 0, myRadius, myRadius);
    translate(-myPosition.x, -myPosition.y, -myPosition.z);
    
    myRadius++;
    myPosition.z += myFallSpeed;
    myColour.darken();
  }
  
  public boolean isFullyGrown()
  {
    return myRadius >= myMaxRadius;
  }
  
}

class vertex
{
  public float x,y,z;
  public vertex(float _x, float _y, float _z)
  {
    x = _x;
    y = _y;
    z = _z;
  }
  public vertex()
  {
    x = random(0,width);
    y = random(0,height);
    z = random(0,300);
  }
}

class colour
{
  private int myDarkenSpeed = (int)random(1,5);
  
  public int r,g,b;
  public colour(int _r, int _g, int _b)
  {
    r = _r;
    g = _g;
    b = _b;
  }
  public colour()
  {
    r = (int)random(0,255);
    g = (int)random(0,255);
    b = (int)random(0,255);
  }
  public void darken()
  {
    r -= myDarkenSpeed;
    g -= myDarkenSpeed;
    b -= myDarkenSpeed;
    if ( r < 0 ) r=0;
    if ( g < 0 ) g=0;
    if ( b < 0 ) b=0;
  }
}

  static public void main(String args[]) {
    PApplet.main(new String[] { "--bgcolor=#F0F0F0", "sketch_aug27c" });
  }
}
