//Catch the Bee+Catch the Flower- 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 witch
//and the ijkl keys to move the bee.
//If the witch catches the bee, it starts dancing (and witch is reset to her start position)
//If the bee lands on the flower, the witch dances (and bee is reset to its start)
//Hitting the walls resets the character to their start + makes you lose a point
//witch: 'a' should move to the left, 'w' should move up )(forward), 'd' should move to the right, and 's' should move down (back)
//bee: 'j' should move to the left, 'i' should move up )(forward), 'l' should move to the right, and 'k' should move down (back)
//'r' key resets the position
//whichever character gets to 10 points wins!
//Look for TODOs


/* variables our program will use */
int xPosW, yPosW;
int xVelW, yVelW;
int xPosB, yPosB;
int xVelB, yVelB;
float tan;
boolean animBee, animWitch, discoWitch, discoBee;
boolean gotCookie = false;
float rotateBee = 0;
float rotateWitch = 0;
int offset = 50;
float xPosF, yPosF;
int beeScore, witchScore;
color TL, TR, ML, MR, BL, BR;
int bWidth = 250, bHeight = 150, path = 100;
int hitCount;
boolean stopMove;
int wallHit;
color wallColor;
boolean startGame = true;

/* initialization and set up */
void setup() {
  background(255);
  wallColor = color(7, 36, 4);
  size(600, 650);
  xPosW = path;
  yPosW = height*3/4;
  xPosB = width- path;
  yPosB = height/4;
  xPosF = random(275, 325);
  yPosF = random(275, 450);
  animBee = animWitch = discoWitch = discoWitch = false;
  beeScore = witchScore = 0;
  TL = TR = ML = MR = BL = BR = wallColor;
}

/* helper function to test against the walls */
boolean checkWalls(int px, int py) {
  int buffer = 5;
  color hitColor = color(247, 35, 237);

  //left walls
  if (px < bWidth-buffer && py < bHeight-buffer) {
    TL = hitColor;
    return true;
  }
  if (px < bWidth-buffer && (py > bHeight+path+buffer && py < 2*bHeight+path-buffer) ) {
    ML = hitColor;
    return true;
  }
  if (px < bWidth-buffer &&  py > 2*bHeight+2*path+buffer ) {
    BL = hitColor;
    return true;
  }

  //right walls
  if (px > bWidth+path+buffer && py < bHeight-buffer) {
    TR = hitColor;
    return true;
  }
  if (px > bWidth+path+buffer && (py > bHeight+path+buffer && py < 2*bHeight+path-buffer) ) {
    MR = hitColor;
    return true;
  }
  if (px > bWidth+path+buffer &&  py > 2*bHeight+2*path+buffer ) {
    BR = hitColor;
    return true;
  }
  return false;
}

/* method to test for collisions in our game */
void checkCollisions() {

  // check against the walls for both characters
  if (checkWalls(xPosW, yPosW)) {
    xVelW = 0;
    yVelW = 0;
    witchScore -= 1;
    xPosW = path;
    yPosW = height*3/4;
    wallHit = frameCount;
  }
  if (checkWalls(xPosB, yPosB)) {
    xVelB = 0;
    yVelB = 0;
    beeScore -= 1;
    xPosB = width- path;
    yPosB = height/4;
    wallHit = frameCount;
  }

  // see if witch has hit the bee
  boolean xCollision = false, yCollision = false;
  if (xPosW > xPosB-offset && xPosW < xPosB+offset) {
    xCollision = true;
  }
  if (yPosW > yPosB-offset && yPosW < yPosB+offset) {
    yCollision = true;
  } 
  if (xCollision && yCollision) {
    animBee = true;
    discoBee = true;
    witchScore += 1;
    xPosW = path;
    yPosW = height*3/4;
    xVelW = 0;
    yVelW = 0;
    hitCount = frameCount;
  }

  //check the bee against the flower
  xCollision = false;
  yCollision = false;
  if (xPosF > xPosB-offset && xPosF < xPosB+offset) {
    xCollision = true;
  }
  if (yPosF > yPosB-offset && yPosF < yPosB+offset) {
    yCollision = true;
  } 
  if (xCollision && yCollision) {
    discoWitch = true;
    animWitch = true;
    gotCookie = true;
    beeScore += 1;
    xPosB = width-path;
    yPosB = height/4;
    xVelB = 0;
    yVelB = 0;
    hitCount = frameCount;
  }
}


/*the main draw loop */
void draw() {
  clear();
  background(175, 250, 169);

  //manage resetting the characters to other side of screen for paths to wrap
  wrapAround();

  //Draw walls
  stroke(0);
  fill(TL);
  rect(0, 0, bWidth, bHeight);
  fill(TR);
  rect(bWidth + path, 0, bWidth, bHeight);
  fill(ML);
  rect(0, bHeight + path, bWidth, bHeight);
  fill(MR);
  rect(bWidth + path, bHeight + path, bWidth, bHeight);
  fill(BL);
  rect(0, bHeight*2 + path*2, bWidth, bHeight);
  fill(BR);
  rect(bWidth + path, bHeight*2 + path*2, bWidth, bHeight);

  /* draw the characters and flowers */
  drawFlower(xPosF, yPosF);
  drawBee(xPosB, yPosB);
  drawWitch(xPosW, yPosW);

  //if the game just started - print directions
  if (startGame) {
    fill(255);
    text("Use WASD for witch - find the bee", 0, 18);
    text("Use IJKL for bee - find the flower", 0, 32);
    text("Hit SPACE BAR to start", 0, 50);
  } 
  else { /* otherwise update variables to 'play the game */
    upDatePositions();
    checkCollisions();

    fill(255);
    text("Bee Score: " + beeScore, 10, height-20);
    text("Witch Score: " + witchScore, width-110, height-20);

    if (beeScore >= 10) {
      text("Bee Won!", path, path);
      stop();
    } 
    else   if (witchScore >= 10) {
      text("Witch Won!", path, path);
      stop();
    }

    //reset any hit response
    if ((animWitch || animBee) && frameCount > hitCount + 30) {
      ReSet();
    }
    if (frameCount > wallHit + 30) {
      TL = TR = ML = MR = BL = BR = wallColor;
    }
  }
}

//Helper function to advance both the witch and bee
//advance the witch or bee as necessary
void upDatePositions() {
  xPosW += xVelW;
  yPosW += yVelW;

  xPosB += xVelB;
  yPosB += yVelB;
}


/******************************************************************/
/******************************************************************/
/******************************************************************/
/********** START   *************************8/
/******************************************************************/
/******************************************************************/
/******************************************************************/

/* students will fill in */
//TODO fill in the correct values so the witch and bee can move in all directions!
//use 'r' to reset if you want the bee to stop dancing
void keyPressed() {
  //when you press the 'a' key the witch will move to the left
  if (key == 'a') {
    xVelW = -10;
    yVelW = 0;
  } //TODO fix these velocities to travel in the correct direction to move the witch
  else if (key == 'd') {
    xVelW = 0;
    yVelW = 0;
  }
  else if (key == 'w') {
    xVelW = 0;
    yVelW = 0;
  }
  else if (key == 's') {
    xVelW = 0;
    yVelW = 0;
  }
  //when you press the 'i' key the bee should move up!!!
  //TODO fix all these velocities so the bee travels in the correct directions!
  if (key == 'i') {
    xVelB = 0;
    yVelB = 0;
  } 
  else if (key == 'k') {
    xVelB = 0;
    yVelB = 0;
  }
  else if (key == 'j') {
    xVelB = 0;
    yVelB = 0;
  } 
  else if (key == 'l') {
    xVelB = 0;
    yVelB = 0;
  }
  /* space bar to start */
  if (key == ' ') {
    startGame = false;
  }

  //reset - leave this as is
  if (key == 'r') {
    ReSet();
    xPosW = width/2;
    yPosW = height*3/4;
    xPosB = width/2;
    yPosB = height/4;
  }
}
/*************************************************************/
/*************************************************************/
/*************************************************************/
/*************************************************************/
/*  NEXT    */
/*************************************************************/
/*************************************************************/
/*************************************************************/
/* wrap characters around when they reach the edge */
/* students fill in some sections */
//TODO - in order to make the characters wrap around to the start - we need to re-set their position
//if they go too far off the side
void wrapAround() {
  int delay = 4;
  //Move witch across screen if they reach the edge
  //x direction
  if (xPosW < 0-delay) {
    xPosW = width;
  }
  else if (xPosW > width+delay) {
    xPosW = 0;
  }  
  else if (yPosW < 0-delay) {
    //TODO - FIX this case - it is wrong!!  if the witch goes off the top - where should she reappear??
    yPosW = height/2;
  } 
  else if (yPosW > height+delay) {
    //TODO - FIX this case - it is wrong!!  if the witch goes off the bottom - where should she reappear??
    yPosW = height/2;
  }

  //Move bee across screen if it reaches the edge
  //y direction
  if (yPosB < 0-delay) {
    yPosB = height;
  }
  else if (yPosB > height+delay) {
    yPosB = 0;
  } 
  else if (xPosB < 0-delay) {
    //TODO - FIX this case - it is wrong!!  if the bee goes off the left edge - where should it reappear??
    xPosB = width/2;
  } 
  else if (xPosB > width+delay) {
    //TODO - FIX this case - it is wrong!!  if the bee goes off the right edge - where should it reappear??
    xPosB = width/2;
  }
}
/* stop the motion once the key is released */
void keyReleased() {
  if (key == 'i' || key == 'j' || key == 'k' || key == 'l') {
    xVelB = 0;
    yVelB = 0;
  }
  if (key == 'w' || key == 'a' || key == 's' || key == 'd') {
    xVelW = 0;
    yVelW = 0;
  }
}

//function to draw the witch
//TODO - if you want - change the witch to be another creature - just keep the shape 
//centered around (0, 0) and about 40 pixels by 40 pixels
void drawWitch(int tx, int ty) {

  pushMatrix();
  translate(tx, ty);
  rotate(rotateWitch);

  //-- start changes here ----
  //the broom
  strokeWeight(3);
  stroke(113, 72, 6);
  line(25, -20, -10, 20);
  fill(211, 179, 13);
  quad(-18, 30, -11, 18, -7, 21, -12, 34);
  noStroke();

  //leave this if test if you want your creature to change colors
  if (discoWitch) {
    fill(random(0, 255), random(0, 255), random(0, 255));
  } 
  else {
    fill(0);
  }
  //---you can change these shapes if you want to --------
  //the body
  ellipse(0, 0, 10, 20);
  ellipse(0, -15, 10, 10);
  pushMatrix();
  translate(0, -5);
  //rotate(1);
  ellipse(4, 0, 16, 4);
  popMatrix();
  //legs
  ellipse(8, 7, 12, 4);
  ellipse(12, 12, 4, 11);

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

  ///---- end of section to change ------
  strokeWeight(1);
  popMatrix();

  if (animWitch == true) {
    rotateWitch += 1;
  }
}


//TODO - you can change the bee if you want to - you can create any shape you'd like - make sure its
//vertices are between 0 and 30 -- also leave transform code
void drawBee(int tx, int ty)
{
  strokeWeight(0.5);
  pushMatrix();
  translate(15+tx, 15+ty);
  scale(2);
  rotate(5 * PI / 4 + rotateBee);
  translate(-15, -15);
  if (discoBee) {
    fill(random(0, 255), random(0, 255), random(0, 255));
  } 
  else {
    fill(245, 144, 12);
  }
  //-start changes here ---------
  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);

  //------end of section to change-----------
  popMatrix();

  if (animBee == true) {
    rotateBee += 1;
  }
}

//TODO - change the flower color if you want
void drawFlower(float center_x, float center_y) {

  float r, cx, cy;

  r = 10;

  fill(255, 255, 200);
  ellipse(center_x, center_y, 10, 10);

  fill(213, 34, 78);
  for (float t=0; t<2*PI; t+=2*PI/12) {
    cx =r*cos(t);
    cy = r*sin(t);
    ellipse(center_x+cx, center_y+cy, 10, 10);
  }
}

/* helper function to reset the values - including making a new flower spawn */
void ReSet() {
  animBee = animWitch = false;
  discoBee = discoWitch = false;
  gotCookie = false;
  if (frameCount%2 == 0) {
    //center
    xPosF = random(bWidth, bWidth+path);
    yPosF = random(bHeight, 2*bHeight+path);
  } 
  else if (frameCount%3 == 0) {
    //top path left
    xPosF = random(0, bWidth);
    yPosF = random(bHeight, bHeight+path);
  } 
  else {
    //bottom path
    xPosF = random(0, width);
    yPosF = random(2*bHeight+path, 2*bHeight+2*path);
  }
  rotateWitch = rotateBee = 0;
  TL = TR = ML = MR = BL = BR = wallColor;
}


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

/* An alternative for drawing a magic cookie instead of a flower */
void drawMagicCookie() {

  if (!gotCookie) {
    pushMatrix();
    translate(xPosF, yPosF);
    fill(183, 22, 162);
    stroke(0);
    ellipse(0, 0, 20, 20);
    stroke(128);
    fill(80, 247, 15);
    for (int i=0; i < 8; i+=2) {
      ellipse(smallRandom[i], smallRandom[i+1], 3, 3);
    }
    popMatrix();
  }
}