//Dance party 2 - Key press version - by Katie Davis and Zoe Wood March 2015 for PCS 5th grade
//Fill in the correct velocities to make the wasd keyes work to move the main character (the witch)
//towards any of the animals to make it'dance'
// 'a' should move to the left, 'w' should move up )(forward), 'd' should move to the left, and 's' should move down (back)
//'r' key resets the witches position

final int FISH = 0, BEE = 1, BUG =2, BAT = 3, BUTTERFLY =4, SNAIL = 5, ANT = 6, DEER = 7;
int xPos, yPos;
int xVel, yVel;
float tan;
boolean animAnimal[];
float animRotate[];
int dir;
boolean dance;
int offset = 30;
int BeeX, BeeY;

void setup() {
  background(255);
  size(600, 600);
  xPos = width/2;
  yPos = height/2;
  dir = DEER;
  dance = false;
  BeeX = width -offset-10;
  BeeY = height/2 - offset;

  animAnimal = new boolean[8];
  animRotate = new float[8];
  for (int i=0; i < 8; i ++) {
    animAnimal[i] = false;
    animRotate[i] = 0;
  }
}

void drawArrow() {
  int degree = (dir+1) * 45;

  strokeWeight(6);
  if (dance) {
    stroke(random(0, 255), random(0, 255), random(0, 255));
    fill(random(0, 255), random(0, 255), random(0, 255));
    degree += random(-180, 180);
  }
  else {
    stroke(32, 32, 32);
    fill(32, 32, 32);
  }
  pushMatrix();
  translate(xPos, yPos);
  rotate(degree * PI / 180);
  translate(-xPos, -yPos);
  line(xPos, yPos, xPos, yPos - 50);
  triangle(xPos, yPos - 50, xPos - 10, yPos - 30, xPos + 10, yPos - 30);
  popMatrix();
}


void drawAnt(int tx, int ty) {
  pushMatrix();

  translate(tx, ty);
  rotate(radians(0)+animRotate[ANT]);
  scale(.5);
  translate(100, -100);
  rotate(radians(90));

  strokeWeight(1);
  stroke(0);
  fill(0);

  //body
  ellipse(100, 76, 28, 28);
  ellipse(100, 102, 16, 30);
  ellipse(100, 128, 36, 40);

  //head
  ellipse(100, 46, 28, 32); 
  fill(255);
  //antennas
  bezier(104, 32, 118, 28, 110, 22, 122, 18); 
  bezier(96, 32, 82, 28, 90, 22, 78, 18); 
  //eyes
  ellipse(90, 38, 10, 14);
  ellipse(110, 38, 10, 14);
  fill(0);
  ellipse(90, 36, 4, 6);
  ellipse(110, 36, 4, 6);

  //legs
  noFill();
  strokeWeight(2);
  bezier(102, 90, 132, 76, 130, 76, 142, 92);
  bezier(98, 90, 68, 76, 70, 76, 58, 92);
  bezier(110, 70, 124, 60, 128, 60, 132, 34); 
  bezier(90, 70, 76, 60, 72, 60, 68, 34);
  bezier(108, 102, 134, 122, 126, 120, 132, 148); 
  bezier(92, 102, 66, 122, 74, 120, 68, 148);

  popMatrix();

  if (animAnimal[ANT] == true) {
    animRotate[ANT] += 1;
  }
}

void drawBee(int tx, int ty)
{
  strokeWeight(1);
  pushMatrix();
  translate(15+tx, 15+ty);
  scale(2);
  rotate(5 * PI / 4 + animRotate[BEE]);
  translate(-15, -15);
  fill(245, 144, 12);
  beginShape();
  vertex(11, 23);
  vertex(15, 23);
  vertex(17, 21);
  vertex(17, 19);
  vertex(16, 18);
  vertex(21, 18);
  vertex(23, 17);
  vertex(24, 15);
  vertex(23, 13);
  vertex(21, 13);
  vertex(19, 14);
  vertex(17, 15);
  vertex(16, 13);
  vertex(17, 11);
  vertex(17, 8);
  vertex(15, 6);

  vertex(14, 5);
  vertex(13, 4);
  vertex(12, 5);
  vertex(10, 6);
  vertex(9, 8);
  vertex(9, 11);
  vertex(10, 13);
  vertex(9, 15);
  vertex(7, 14);
  vertex(5, 13);
  vertex(3, 13);
  vertex(2, 15);
  vertex(3, 17);
  vertex(5, 18);
  vertex(10, 18);
  vertex(9, 19);

  vertex(9, 21);
  vertex(11, 23);
  endShape(CLOSE);

  stroke(0);
  line(10, 6, 15, 6);
  line(9, 8, 16, 8);
  line(9, 10, 17, 10);

  line(10, 12, 16, 12);
  line(9, 17, 3, 15);
  line(6, 16, 5, 13);
  line(6, 16, 4, 17);
  line(17, 17, 23, 15);
  line(19, 16, 21, 13);
  line(19, 16, 21, 18);

  fill(19, 100, 14);
  ellipse(10, 22, 3.25, 2.5);
  ellipse(16, 22, 3.25, 2.5);
  popMatrix();

  if (animAnimal[BEE] == true) {
    animRotate[BEE] += 1;
  }
}

void drawSnail(int tx, int ty) {
  float theta = 0;
  int numP = 40;
  float rad = 2;

  pushMatrix();
  translate(tx, ty);
  scale(1.5);
  rotate(animRotate[SNAIL]);

  //eye
  stroke(225, 232, 3);
  strokeWeight(2);
  line(15, 10, 22, 5);
  line(15, 10, 18, 3);
  fill(255);
  stroke(0);
  strokeWeight(1);
  ellipse(18, 3, 6, 6);
  ellipse(22, 5, 9, 9);
  fill(0);
  ellipse(22, 5, 2, 2);

  //body
  fill(225, 232, 37);
  ellipse(0, 10, 30, 8);

  //shell
  fill(149, 97, 29);
  beginShape();
  for (int i=0; i < numP; i++) {
    vertex(rad*sin(theta), rad*cos(theta));
    rad += 0.3;
    theta += TWO_PI*2.95/numP;
  }
  endShape();
  popMatrix();

  if (animAnimal[SNAIL] == true) {
    animRotate[SNAIL] += 1;
  }
}

void drawBat(int tx, int ty) {

  pushMatrix();
  translate(tx, ty);
  rotate(animRotate[BAT]);
  fill(#313632);
  stroke(0);
  beginShape();
  vertex(-10, 20);
  vertex(10, 10);
  vertex(20, 20);
  vertex(22, 5);
  vertex(24, 12);
  vertex(26, 5);
  vertex(28, 12);
  vertex(32, 12);
  vertex(26, 20);
  vertex(36, 12);
  vertex(56, 23);
  vertex(51, 28);
  vertex(44, 25);
  vertex(37, 30);
  vertex(30, 25);
  vertex(23, 32);
  vertex(17, 25);
  vertex(10, 28);
  vertex(5, 25);
  vertex(0, 28);
  endShape(CLOSE);
  popMatrix();

  if (animAnimal[BAT] == true) {
    animRotate[BAT] += 1;
  }
}

void drawFish(int tx, int ty) {
  pushMatrix();
  translate(tx, ty);
  rotate(animRotate[FISH]);
  noStroke();
  fill(0, 0, 255);
  ellipse(0, 0, 30, 20);
  triangle(0, 0, -20, 10, -20, -10);

  fill(255);
  ellipse(8, -3, 8, 8);
  fill(0);
  ellipse(9, -3, 5, 5);
  popMatrix();

  if (animAnimal[FISH] == true) {
    animRotate[FISH] += 1;
  }
}


void drawBug(int tx, int ty) {
  pushMatrix();
  translate(tx, ty);
  rotate(animRotate[BUG]);
  //body
  stroke(0);
  strokeWeight(1);
  fill(194, 85, 45);
  ellipse(0, 0, 30, 40);
  line(0, -20, 0, 20);
  //head

  ellipse(0, -15, 25, 10);
  //eyes
  strokeWeight(.5);
  //noStroke();
  fill(126, 25, 0);
  ellipse(-8, -18, 5, 3);
  ellipse(8, -18, 5, 3);

  stroke(194, 85, 45);
  noFill();
  strokeWeight(1);
  beginShape();
  curveVertex(-2, -5);
  curveVertex(-2, -15);
  curveVertex(-2, -35);
  curveVertex(-6, -40);
  curveVertex(-8, -40);
  endShape();
  beginShape();
  curveVertex(2, -5);
  curveVertex(2, -15);
  curveVertex(2, -35);
  curveVertex(6, -40);
  curveVertex(8, -40);
  endShape();

  //decoration on shell
  strokeWeight(2);
  stroke(255, 188, 136);
  fill(66, 71, 80);
  ellipse(-7, -3, 10, 10);
  noStroke();
  fill(248, 184, 73);
  ellipse(-7, -3, 4, 4);
  stroke(255, 188, 136);
  fill(66, 71, 80);
  ellipse(7, -3, 10, 10);
  noStroke();
  fill(248, 184, 73);
  ellipse(7, -3, 4, 4);
  noFill();
  stroke(201, 153, 98);
  arc(-7, -3, 16, 16, PI*.25, 0.75*PI);
  arc(7, -3, 16, 16, PI*.25, 0.75*PI);

  stroke(232, 124, 43);
  fill(151, 47, 0);
  ellipse(6, 12, 4, 4);
  ellipse(-6, 12, 4, 4);
  noFill();
  stroke(255, 192, 93);
  arc(6, 12, 9, 9, PI*1.25, 1.75*PI);
  arc(-6, 12, 9, 9, PI*1.25, 1.75*PI);
  popMatrix();

  if (animAnimal[BUG] == true) {
    animRotate[BUG] += 1;
  }
}


//draw a butterfly (filled in with lines)
void drawButterfly(int tx, int ty) {
  float r, cx, cy;
  r =10;

  stroke(10, 134, 136);
  for (float t=0; t<2*PI; t=t+0.05) {
    cx =r*sin(t)*(exp(cos(t)) -2*cos(4*t) -pow(sin(t/12), 5));
    cy = r*cos(t)*(exp(cos(t)) -2*cos(4*t) -pow(sin(t/12), 5));
    pushMatrix();
    translate(tx, ty);
    rotate(PI+animRotate[BUTTERFLY]);
    line(0, 0, cx, cy);
    popMatrix();
  }

  if (animAnimal[BUTTERFLY] == true) {
    animRotate[BUTTERFLY] += 1;
  }
}

int smallRandom[] = {
  -2, 4, 1, 3, 4, -1, 2
};

/* a procedure to draw a deer at a given location and of a given size */
void drawDeer(float deerSize, int deerTx, int deerTy) {
  fill(137, 80, 33);
  pushMatrix();
  translate(76*deerSize+deerTx, 307*deerSize + deerTy);
  scale(deerSize);
  rotate(animRotate[DEER]);
  translate(-76, -307);
  beginShape(); 
  vertex(25, 39);
  vertex(25, 44);
  vertex(0, 45);
  vertex(-25, 70);
  vertex(-25, 90);
  vertex(-50, 110);
  vertex(-50, 125);
  vertex(-25, 125);
  vertex(40, 100);
  vertex(80, 144);
  vertex(98, 198);
  vertex(76, 307);
  vertex(96, 307);
  vertex(132, 199);
  vertex(223, 178);
  vertex(276, 307);
  vertex(291, 307);
  vertex(290, 273);
  vertex(270, 215);
  vertex(291, 184);
  vertex(293, 116);
  vertex(308, 100);
  vertex(258, 91);        
  vertex(130, 91);
  vertex(42, 56);
  vertex(41, 36);
  endShape(CLOSE);

  //the eye
  fill(245);
  ellipse(10, 75, 20, 20);
  fill(0);
  ellipse(8, 77, 10, 14);

  stroke(0);
  strokeWeight(6);
  line(8, 50, -14, 18);
  line(8, 50, 23, 19);

  strokeWeight(1);
  //some spots
  for (int i=0; i < 3; i++) {
    for (int j=0; j < 2; j++) {
      fill(216, 143, 83);
      ellipse(245+i*13+smallRandom[i], 122+j*13+smallRandom[i+j], 10, 11);
    }
  }
  popMatrix();

  if (animAnimal[DEER] == true) {
    animRotate[DEER] += 1;
  }
}

//function to draw the witch
void drawWitch(int tx, int ty) {

  pushMatrix();
  translate(tx, ty);
  fill(0);
  //the body
  ellipse(0, 0, 10, 20);
  ellipse(0, -15, 10, 10);
  //legs
  ellipse(9, 7, 11, 4);
  ellipse(12, 12, 4, 11);

  //the hat
  triangle(-10, -20, 0, -35, 10, -20);

  //the broom
  strokeWeight(6);
  stroke(0);
  line(25, -20, -10, 20);
  quad(-18, 30, -11, 18, -7, 21, -12, 34);

  strokeWeight(1);
  popMatrix();
}


void checkCollisions() {
  //first test against fish
  if (xPos > width-offset && yPos < offset) {
    dance = true;
    animAnimal[0] = true;
  } //bee
  else if (xPos >= BeeX && (yPos >= BeeY- (offset+10)  && yPos <= BeeY + (offset+10))) {
    dance = true;
    animAnimal[1] = true;
  } //bug
  else if (xPos > width-offset && yPos > height-offset) {
    dance = true;
    animAnimal[2] = true;
  } //bat
  else if ((xPos > width/2-(offset+10) && xPos < width/2+(offset+10)) && yPos > height-offset) {
    dance = true;
    animAnimal[3] = true;
  } //butterfly
  else if (xPos < offset && (yPos > height-offset)) {
    dance = true;
    animAnimal[4] = true;
  } //snail
  else if (xPos < offset && (yPos > height/2-(offset+10) && yPos < height/2+(offset+10))) {
    dance = true;
    animAnimal[5] = true;
  } //ant
  else if (xPos < offset && yPos < offset) {
    dance = true;
    animAnimal[6] = true;
  } //deer
  else if ((xPos > width/2-(offset+10) && xPos < width/2+(offset+10)) && yPos < offset) {
    dance = true;
    animAnimal[7] = true;
  }
}

void draw() {

  clear();
  background(255, 255, 255);

  int delay = 4;
  //reset position if witch reaches end of screen
  if (xPos == 0-delay || yPos == 0-delay || xPos == width+delay || yPos == height+delay) {
    for (int i=0; i < 8; i++) {
      animAnimal[i] = false;
      animRotate[i] = 0;
    }
    dance = false;
    xPos = width/2;
    yPos = height/2;
  }

  fill(128);
  stroke(128);
  triangle(100, 0, 250, 0, 250, 200);
  triangle(0, 100, 200, 250, 0, 250);

  triangle(350, 0, 500, 0, 350, 200);
  triangle(width, 100, width-200, 250, width, 250);

  triangle(100, height, 250, height, 250, height-200);
  triangle(0, height-100, 200, height-250, 0, height-250);

  triangle(350, height, 500, height, 350, height-200);
  triangle(width, height-100, width-200, height-250, width, height-250);

  drawAnt(offset, offset);
  drawBee(BeeX, BeeY);
  drawSnail(offset, height/2- offset+10);
  drawBat(width/2- offset, height-offset-10);
  drawFish(width-30, offset);
  drawBug(width-30, height-offset);
  drawDeer(0.25, width/2-offset, 0);
  drawButterfly(offset, height-offset);

  drawWitch(xPos, yPos);

  checkCollisions();
}

//TODO fill in the correct values so the witch can move in all directions! - Can you make all the creatures dance?
//use 'r' to reset if you want the animals to stop dancing
void keyPressed() {
  //when you press the 'a' key the witch will move to the left
  if (key == 'a') {
    xVel = -10;
    yVel = 0;
  } // TODO fix these velocities to travel in the correct direction to move the witch
  else if (key == 'd') {
    xVel = 0;
    yVel = 0;
  }
  else if (key == 'w') {
    xVel = 0;
    yVel = 0;
  }
  else if (key == 's') {
    xVel = 0;
    yVel = 0;
  }

  //reset - leave this as is
  if (key == 'r') {
    for (int i=0; i < 8; i++) {
      animAnimal[i] = false;
      animRotate[i] = 0;
    }
    dance = false;
    xPos = width/2;
    yPos = height/2;
    BeeX = width -offset-10;
    BeeY = height/2 - offset;
  }

  //if any of the motion keyes are hit, advance the position
  if (key == 'a' || key == 'd' || key == 'w' || key == 's') {
    xPos += xVel;
    yPos += yVel;
  }
}