//CSC 123 base code for hierarchical duck lab
//by ZJ Wood - Fall 2011
//TODO: read through the code to make sure you understand what it is doing
//TODO: add code in order to make the duck have feet that also walk as it animates

PVector Dloc;
PVector dir;
float neckR, wingR, time;

boolean neckDown = true;
boolean wingDown = false;
boolean animate = false;
  
//code to draw the duck with animation parameters neckR and wingR - other transforms align
//the peices to the correct pivot points
void drawDuck() {
    noStroke();
    
    pushMatrix();
      //move the entire duck
      translate(Dloc.x, Dloc.y);
      scale(2); //scale the entire duck
      fill(245, 226, 12);
      ellipse(0, 0, 40, 30); //body
      
      //draw neck and head with possible animation transforms
      pushMatrix();
        translate(-16, 0); //move back into draw position
        rotate(neckR);  //rotate by neckR parameter
        translate(16, 0); //move neck and head to pivot point
        ellipse(-16, -10, 10, 18); //neck
        ellipse(-16, -17, 14, 14); //head
        fill(0);
        ellipse(-16, -19, 4, 4);  //eye
        fill(155, 111, 16);
        triangle(-26, -18, -20, -21, -20, -15); //beak
      popMatrix();
     
      //draw wing with possible animation transforms
      fill(227, 208, 66);
      pushMatrix();
         translate(-8, -5); //move into draw position
         rotate(wingR); //animtion parameter to control wing flap
         translate(14, 0); //move to the pivot point
        ellipse(0, 0, 34, 20); //wing
      popMatrix();
      
    popMatrix();
           
}
 
//function to update all animation parameters 
void animate() {
  //update the ducks global location
  Dloc.x = Dloc.x + dir.x*time;
  Dloc.y = Dloc.y + dir.y*time;
  
  //find out how much the neck is rotated to decide which way to rotate
  //these constrain how much the neck moves up and down
  if (neckR < -1) {
      neckDown = false;
  } 
  if (neckR > 0.3) {
    neckDown = true;
  }
 
  //depending on which way we need to rotate, do so
  if (neckDown == true) {
     neckR -= .03; 
  } else {
    neckR += .03;
  }
  
  //find out how much the wing is rotated to decide which way to rotate
  //these constrain how much the wing moves up and down
  if (wingR < -1.1) {
      wingDown = true;
  } 
  if (wingR > 0.3) {
    wingDown = false;
  }
 
  if (wingDown == false) {
     wingR -= .03; 
  } else {
    wingR += .03;
  }
}

//normal set up
void setup() {
  size(400, 400);
  smooth();
  neckR = 0;
  wingR =-.2;
  Dloc = new PVector(width*.9, height/2);
  dir = new PVector(-1, 0);
  time = 0.5;
}

//normal draw
void draw() {
  
  background(12, 245, 216);
  
  //foreground
  fill(78, 155, 16);
  rect(0, height/2, width, height/2);
  
  drawDuck();
  if (animate) {
    animate();
  }
  
}

//method to control starting the duck over again and control animation on and off
void mousePressed() {

  Dloc.x = width*.9;
  animate = !animate;

}