////  Midterm ////

String title="CST 112 Midterm Exam:  HALLOWEEN scene \n(evil witch, scary octopus; flapping bird, 3 nice fish) ";
String author="Joe Bloggs";

boolean day;

int score;
float surface;
float bottom;

float birdX, birdY, birdDX= 3;
float oneX, oneY, oneDX, oneDY;
float twoX, twoY, twoDX, twoDY;
float threeX, threeY, threeDX, threeDY;

float witchX, witchY, witchDX= -2;
float witchEyeX, witchEyeY;
float octX, octY, octDY= 1;
float helpX, helpY, helpDY=0;

float moonX,moonY;
float waveX=30, waveY=10;
float weedX=10, weedY=10;


void setup() {
  size(700,500);
  surface=  height/2;
  bottom=  height;
  score=0;
  day=  true;
  begin();
}
void begin() {
  ////  Move creatures back to starting positions.
  birdX=50;
  birdY=surface/2;
  oneX=twoX=threeX=  width/2 + 100 - random(200);          //// Always start NEAR mid-ocean
  oneY=twoY=threeY=  height*3/4 + 50 - random(100);
  // Random speeds for 3 fish.
  oneDX=  random(10) - 5;    oneDY=  random(6) - 3;
  twoDX=  random(10) - 5;    twoDY=  random(6) - 3;
  threeDX=  random(10) - 5;    threeDY=  random(6) - 3;
  //
  octX=  random( 100, width-100 );
  octY=surface;
  witchX=  width;
  witchY=  random( 50, surface-50 );
  witchDX= -2;
  //
  moonX=  50 + random( width-100 );
  moonY=  witchY + random( 50 ); 
  helpX=width*2/3;
  helpY=height/3;
}

void draw() {
  //// Draw the frame.
  scene();
  if (day) {
    bird();
    fish();
  } else {
    witch();
    octopus();
  }
  //// Write messages last (so they always show).
  messages();
}
void messages() {
  //// Messages on screen.
    //// Text on screen
    fill(0);
    text( title, 200, 20 );
    text( author, 20, height-20);
    text( witchX, 10,10 );
    // Score
    fill(255);
    if (score<0) fill(255,0,0);
    if (score != 0) text( "SCORE:  "+score, width*3/4, surface-50 );
    if (key == '?') help();
    fill(255);
    //--  text( "MOON:  "+moonX+","+moonY, helpX, helpY-20 );
}  

void scene() {
  //// Sky & ocean;
  if (day) {
    background( 200,200,255 );
    fill( 255,255,0 );
    ellipse( width-100, 50, 50,50 );    // sun
  } else {  
    background( 100,100,255 );
    fill( 200,100,100 );
    noStroke();
    ellipse( moonX, moonY, 70, 70 );    // moon
  }
  //// Ocean
  fill( 100,200,100 );
  noStroke();
  rectMode(CORNER);
  rect(0, surface, width, height-surface );
  waves( surface );
  seaweed( bottom );
}
void waves( float y ) {
  //// Make waves on surface of ocean.
  if (frameCount % 10 == 0) {
    waveX=  30 + random(0,10);    // Randomize wave width, every ten frames.
    waveY=  20 + random(0,4);
    if (day) waveX += 20;
    waveX = waveX -1 + random(2);
  }
  // Make waves across width of screen.
  for (float x=0; x<width+30; x+=waveX )
  {
    ellipse(x,y, waveX, waveY );
  }
}
void seaweed( float y ) {
  //// Make seaweed across the width of the screen.
  if (frameCount %10 == 0) {
    weedX=  10 - random(0,20);
    if (day) weedX *= 2;          // Weeds move more by day (due to fish).
    weedY=  20 - random(0,4);
  }
  for (float x=0; x<width+30; x+=30 )
  {
    strokeWeight(2);
    stroke( 50,100,0 );          // Dark-green seaweed.
    line(x,y, x+weedX, y-weedY );
    noStroke();
    weedX = weedX -1 + random(2);
  }
}


////// CREATURES //////
void bird() {
  //// Move & draw
  birdX += birdDX;
  if (birdX > width-50) { 
    background( 255,255,200 );    // Flash (sunrise);
    day=false; 
    begin(); 
    return; 
  }
  // Draw bird.
  fill(200,0,200);
  triangle( birdX,birdY, birdX-80,birdY-10, birdX-80,birdY+10 );
  fill(150,0,150);
  if (frameCount / 10 % 2 == 0) {
    triangle( birdX-30,birdY, birdX-80,birdY-30, birdX-80,birdY+30 );
  } else {
  }
}
void fish() {
  /// 3 fish swim in random directions.
  // If fish exists, reverse direction at sides, move it, draw fish.
  if (oneX>0) {
    if (oneX < 30 || oneX >width-30) { oneDX = -oneDX; }
    if (oneY < surface || oneY >height-30) { oneDY = -oneDY; }
    oneX=  oneX + oneDX;
    oneY=  oneY + oneDY;
    //// Draw fish (irridescent).
    drawFish( color(255-random(50),0,0), oneX, oneY, oneDX, 40+random(20) );
  }
  if (twoX>0) {
      // Check if this fish is WITHIN bounds; rev ers if not.
      twoDX=  (twoX > 30  &&  twoX < width-30) ? twoDX : -twoDX;          // Reverse at sides
      twoDY=  (twoY > surface  &&  twoY < height-30) ? twoDY : -twoDY-random(1);
      twoX += twoDX;
      twoY += twoDY;
      drawFish( color(0,255-random(25),255-random(25)), twoX, twoY, twoDX, 40+random(20) );
  }
  if (threeX>0) {
      threeDX=  (threeX > 30  &&  threeX < width-30) ? threeDX : -threeDX;          // Reverse at sides
      threeDY=  (threeY > surface  &&  threeY < height-30) ? threeDY : -threeDY-random(1);
      threeX += threeDX;
      threeY += threeDY;  
      drawFish( color(255-random(25),0,255-random(25)), threeX, threeY, threeDX, 40+random(20) );
  }
}
void drawFish( color c, float x, float y, float dx, float w ) {
  //// Draw fish, with tail at back.
  fill( c );
  ellipse( x, y, w, w/2 );
  if (dx<0) {
    float tail=  x + w/2;
    triangle( tail,y, tail+16,y+12, tail+16,y-12 );
  } else {
    float tail=  x - w/2;
    triangle( tail,y, tail-16,y+12, tail-16,y-12 );
  }
}

void witch() {
  //// Witch move & draw
  witchX += witchDX;
  if (witchX < 50) { 
    background(255,255,200);    // Flash (sunrise)
    day=true; 
    score -= 25;
    begin(); 
    return;
  }
  if (abs(witchX-moonX) < 15 ) {
    //// Witch crossing the moon.
    background(100,0,0);    // Flash (dark red)
    fill(255,255,0);
    text( "HEH \n     HEH      \n       HEH", witchX+50, witchY-50 );
  }
  drawWitch( witchX, witchY );
}
void drawWitch( float witchX, float witchY ) {
  //// Draw witch
  fill(100,50,50);
  rectMode(CENTER);
  rect( witchX, witchY, 40, 60 );    // Brown rectangle.
  fill(255,0,0);                      // Red face
  ellipse( witchX, witchY-40, 20, 20);
  // Yellow eye
  fill(255,255,0);
  ellipse( witchX-5, witchY-43, 5,5 );
  // Black hat.
  fill(0);
  triangle( witchX-10,witchY-50, witchX+10,witchY-50, witchX,witchY-70 );
  strokeWeight(3);
  stroke(0);
  line( witchX-20,witchY-50, witchX+20,witchY-50 );  // Hat brim.
  drawBroom( witchX-60, witchX+60, witchY+30 );
}
void drawBroom( float x1, float x2, float y ) {
  //// Broom from x1 to x2, at y
  strokeWeight(6);
  stroke(200,150,100);
  line( x1, y, x2, y );
  //// Bristles at x2.
  strokeWeight(1);
  float yy=  y-10;
  for (int j=0; j<8; j++ )
  {
    line( x2,yy, x2+40,yy );
    yy += 3;
  }
  noStroke();        // Reset
}


void octopus() {
  //// Octopus:  up & down
  octY += octDY;
  if (octY < surface) {
    //// Octopus surfaces:  lose 25 points, flash black, reverse begin sinking.
    octDY = +1;    // Sink slowly.
    background( 0, 50, 100 );    // Flash (dark blue)
    score -= 50;
  }
  else if (octY > height-50) {
    // Hit bottom
    octDY = -3;    // Rise fast.
  }
  if (octY > height-70) {
    background( 0, 50, 100 );    // Prolonged lash (dark blue) at bottom
    fill(0,255,255);
    text( "o\n        o\n         o\n          gurgle\n   gurgle\n gurgle", 
      octX+20, octY-120 );
    fill(255,255,0);
    text( "SCORE DROPS BY 50, WHEN I SURFACE!", octX-100, surface );
  }
  //// Draw body & slanty legs;
  fill( 50,50,150 );
  rectMode(CENTER);
  rect( octX,octY, 40, 50 );
  ellipse( octX,octY-30, 40, 40 );
  // Eye
  fill(200,150,0);
  ellipse( octX, octY-35, 15,10 );
  fill(0);
  ellipse( octX-2+random(4), octY-35, 4,4 );
  // Legs
  stroke( 50,50,150 );
  strokeWeight(2);
  float slant=0;
  if (octDY<0) {
    // Going up.
    slant = (frameCount % 10 < 5) ? -3 : +3;
  }
  for( float x=octX-20+2; x<octX+20; x+=5 )
  {
    line(x,octY+20, x+slant,octY+50);
  }
}


//// EVENT HANDLERS ////

void mousePressed() {
  //// Check for clicking on:  bird, witch, fish, octopus, etc.
  if (day) {
      if (dist( mouseX,mouseY, birdX,birdY) < 50 ) { day=false; return; }
      // Fish click adds 10 to score (and fish disappears).
      if ( dist( mouseX,mouseY, oneX, oneY )  <  25 ) { oneX=  -1;  score += 10; }
      if ( dist( mouseX,mouseY, twoX, twoY )  <  25 ) { twoX=  -1;  score += 10; }
      if ( dist( mouseX,mouseY, threeX, threeY )  <  25 ) { threeX=  -1;  score += 10; }
  } else {
      ////// Witch's eye adds 50 to score (and ends the night).
      if ( dist( mouseX,mouseY, witchX-20, witchY-50 )  <  15 ) { 
        background(0);
        day=false;  score += 50;           // Witch's eye
        witchDX +=  1;
      }
      // Octopus eye sends him downward
      if ( dist( mouseX,mouseY, octX, octY-30 )  <  15 ) { 
        background(0);
        octDY +=  1;
      }
 }  
}


    

void keyPressed() {
  //// Keys.
  if (key == 'd') { day=true; begin(); }
  if (key == 'n') { day=false; begin(); }
  if (key == 'q') exit();
}
void help() {
  //// Display help msgs
  helpDY=0;
  fill(0);
  text("H E L P", helpX, helpY+12*helpDY++ );
  text("H E L P", helpX, helpY+12*helpDY++ );
  text("H E L P", helpX, helpY+12*helpDY++ );
}

