public final int  SZ=100;

int MAXBUBBLE = 5;

fish f;
plant p,p2;
bubble b[];

float s = 1.0;
void setup() { 
  size(100,100);
  smooth();
  noFill();
  f = new fish(SZ/20,SZ/6);
  p = new plant(0,SZ/4,0, SZ/3, SZ/3300.0);
  p2 = new plant(SZ/6,SZ/4,SZ/6, SZ*5/12, SZ/4800.0);
  b = new bubble[MAXBUBBLE];

} 

float spin;  

void loop(){
  background(200,200,255);
//centerized frame of reference...
    translate(SZ/2,SZ/2);
//rotate 'camera' based on mouse
   rotateY((mouseX-(SZ/2))/(float)(SZ/3));
   rotateX(((float)(SZ/2-mouseY))/((SZ*2)/3));

if(mousePressed){
  s = s +.01;
  s = constrain(s,0,2.2);
} else {
  if(s > 1.0) {
    s = s - .01;
  }

}
scale(s);

stroke(0);
    //draw tank
    box(SZ/2);

    f.move();
    stroke(255,100,0);
    f.drawfish();  
    stroke(0,255,0);
    p.move();
    p.drawplant();  
    
    
    p2.move();
    p2.drawplant();  
stroke(0);
   for(int i = 0; i < MAXBUBBLE; i++){
      if(b[i] != null){
        b[i].move();
        b[i].drawbubble();
         if(b[i].isOut()){
             b[i] = null;
          }   
      } else {
        b[i] = f.blowbubble();  

      
      }
}
}

class plant {

  float basex, basey, basez, plantheight, maxbend,nowbend;
  float dir;
  float nowdir = dir ;
  plant(float inx,float iny,float inz,float inheight, float indir){
    basex = inx; basey = iny; basez = inz; plantheight = inheight;
    maxbend = plantheight / 10;
    nowdir = dir = indir;
        }
  
  void move(){
    nowbend += nowdir;
    if(nowbend > maxbend){
      nowdir = -dir;
    } 
    if(nowbend < -maxbend){
      nowdir = dir;
    } 
  }
  
  
 void drawplant(){
    line(basex,basey,basez,basex+nowbend,basey-plantheight/2,basez);
    line(basex+nowbend,basey-plantheight/2,basez,basex,basey-plantheight,basez);
  }
}

class fish{
  float fishsize;
  float fishspin, fishradius,fishscale;
      fish(float insize, float inradius){
      fishsize = insize;
      fishradius = inradius;
    }
    
    void drawfish(){
    push();
    rotateY(spin);
    translate(0,0,fishradius);



    line(fishsize,0,0,0,-fishsize,0);
    line(0,0-fishsize,0 ,0-fishsize - fishsize, fishsize,0);
    line(0+fishsize,0,0,0,fishsize,0);
    line(0,fishsize,0, 0-fishsize - fishsize, 0-fishsize,0);


    pop();
  
    }
    void move(){
      spin += .01;    
    }
     bubble blowbubble(){
        if(random(100.0)<1.0){
                return new bubble(spin,0,fishradius,SZ/600.0, fishsize);
                } else {
                  return null;
                }
     }
}

class bubble{
  float bubangle,buby,bubradius , bubmove, buboffset;
    bubble(float inangle, float iny, float inradius, float inmove, float inoffset){
      bubangle = inangle;
      buby = iny;

      bubmove = inmove;
      bubradius = inradius;
      buboffset = inoffset;
    }
    void drawbubble(){
      push();
      rotateY(bubangle);
      translate(0,0,bubradius);
      point(buboffset+random(-1*(SZ/50), SZ/50),buby,0);
      pop();
    }
  
  
    void move(){
      buby -= bubmove;

        }
    boolean isOut(){

          if(buby > SZ/-4.0){
          return false;
      } else {
        return true;
    }
  }
}