String title = "Witch versus Monster";
String author = "Chandni Ochani";
String news="...";
String hint1= "Click below horizon for a surprise.";
String hint2= "Use buttons to Zap or reset.";

Button one, two, three, four;
Witch orly = new Witch();
Monster carol = new Monster ();
Animal ion = new Animal();
Tree[] a = new Tree[5];

int score = 0;
float left = 30, right = 880, horizon = 300, bottom = 480;
float xTreat = 0, yTreat;
float nearby = 40;

void setup () {
  size (900, 700);
  horizon = height/2;
  one = new Button ("Zap", 60,40,color (250,100,100) );
  two = new Button ("Back", 60,80,color (200,250,100) );
  three = new Button ("Reset",60,120,color (250,150,250) );
  four = new Button ("Trees",60,160,color (280,150,150) );
  //
  xTreat = width - 60;
  yTreat = random(horizon+35,height-35);
  //
  randomTrees();
}
void randomTrees() {
  float top = horizon-0;
  for (int e=0; e<5; ++e) {
    a[e]=new Tree(random(left,right), random(top,bottom) );
  }
background (0,255,0);
}

void draw() {
  scene() ;
  action();
  trees();
  messages() ;
}

void scene() {
  background (120,150,200);
  fill (100,200,100);
  rect (0,horizon,width,height-horizon);
  fill (200,200,180);
  float xMoon=width/3, yMoon=horizon/3;
  if (abs(xMoon-orly.x)<50) fill (255,255,50);
  ellipse (xMoon,yMoon,80,80);
  // Buttons
  one.show();
  two.show();
  three.show();
  four.show();
}
void trees() {
  // Trees
  for (int e=0; e<5; ++e) {
    a[e].show();
  }
}

void action() {
  showTreat(xTreat,yTreat);
  // Monster runs for surprise;
  carol.show();
  carol.move();
  // Witch rides broom left to right;
  orly.show();
  orly.move();
  // Rabbit runs around;
  ion.show();
  ion.move();
}
void showTreat(float x, float y) {
  if (x<=0) return;
  float w=60, h=50;
  fill(random(250,255),0,0);
  ellipse(x,y,w-random(5),h-random(5) );
  fill(255,255,0);
  ellipse(x,y,w-random(6,8), h-random(6,8) );
  fill(random(250,255),random(250,255),0);
  ellipse(x,y,w-random(13,20), h-random(13,20) );
}
void messages() {
  fill(0);
  textSize(30);
  text(title,10,20);
  textSize(20);
  text("SCORE:"+score,width-200,30);
  textSize(20);
  text( news,width-200,50);
  text( hint1, width/4, 40);
  text( hint2, width/3,55);
  text( author,10,height-10);
}

//// EVENTS ////
void keyPressed() {
  news= ""+key;
  if (key=='c') {exit(); }
  if (key=='a') {reset(); }
  if (key=='n') {backWitch(); }
  if (key=='d') {zap(); }
  if (key=='y') {randomTrees(); }
}
void mousePressed() {
  news="(" +(int)mouseX+ ","+(int)mouseY+ ")";
  if (one.hit() ) {zap(); }
  else if (two.hit() ) {backWitch(); }
  else if (three.hit() ) {reset(); }
  else if (four.hit() ) {randomTrees(); }
  else if (ion.clicked() ) {ion.reset(); }
  else if (orly.clicked() ) {orly.reset(); }
  else if (carol.clicked() ) {carol.reset();xTreat=0; }
  //
  else if (mouseY>horizon) {
    xTreat=mouseX;
    yTreat=mouseY;
    score -=25;
    news= "Award was given.";
    carol.reset();
    orly.reset();
  }
}
void zap() {
  score-=25;
  background(255,0,0);
}
void backWitch() {
  orly.dx *=-1;
}
void reset() {
  //// Monster dissapears
  carol.reset();
  orly.reset();
  ion.reset();
}

class Button 
{ 
  // PROPERTIES //
  float x=60, y=60;
  int w=90, h=40;
  String name="Click here";
  color c=color(255,200,200);
  
  //CONSTRUCTORS (chained) //
  Button() {this("Click here"); }
  Button(String name) {this(name,100,100); }
  Button(float xx,float yy) {
    this("Click here",xx,yy);
  }
  Button(String name,float xx, float yy) {
    this(name, xx, yy, color(255,200,200) );
  }
  Button(String name, float x, float y, color c)
  {
    this.name=name;
    this.x=x;
    this.y=y;
    this.c=c;
  }
  
  // METHODS //
  void show() {
    fill( c );
    rect( x,y, w,h );
    fill(0);
    textSize(20);
    text( name, x+30, y+40 );
  }
boolean hit() {
  return(
  mouseX>x
  && mouseX<x+w
  && mouseY>y
  && mouseY<y+h);
}
}

class Witch
{
  float x=600,y=100, dx;
  float w=40, h=80, hh=30;           // body w&h, head height
  void show() {
    if (x<=0) return;
    float broom=y+h;                   // broom
    fill(255,100,0);
    ellipse( x,y, 25,hh );             // Orange face.
    fill(0);
    rect( x-w/2, y+hh/2, w, h );
    triangle( x-10,y-hh/2, x+10,y-hh/2, x,y-45 );  // hat
    rect( x-20,y-15, 40,3 );                       // brim
    fill(100,0,0);
    rect( x-60,broom, 120,3 );         // Brown broomstick
    triangle( x+50,broom, x+60,broom-12, x+60,broom+12 );
   {
    news= "MISSED.";
    score -=25;
    return;
  }
  }
  void move() {
    x+=dx;
  }
  void reset() {x=width-30;dx=-1; }
  boolean clicked() {
    return (dist(x,y,mouseX,mouseY)<30);
  }
  }// class Witch //
class Monster
{
  float x=20,y=200,dx,dy;
  float w=60,h=120;
  void move() {
    if (xTreat<=0) {return;}
    dx= (xTreat-x) / random(900,1500); //Chase the treat
    dy= (yTreat-y) / random(900,1500);
    x +=dx;
    y +=dy;
    if (near(xTreat, yTreat)) {
    news= "Monster ate the candy!";
    score -=50;
    xTreat=0; // Treat vanishes.
    carol.reset();
    }
  }
  void reset() {x=0;}
  void show() {
    if (x<=0) return;
    float step=3;
    if (x%50<25) step= -step;
    fill(0);
    rect(x,y+step,w/3,h);
    rect(x+w/2,y-step,w/3,h);
    fill(255,100,255);
    ellipse( x+w/3,y-10,40,40);
    fill(0);
    ellipse( x+w/3-10,y-20,8,8); //eyes
    ellipse( x+w/3+10,y-20,8,8);
  }
  boolean near(float xx, float yy) {
    return dist(x,y,xx,yy)<nearby;
  }
  boolean clicked() {
    return near (mouseX,mouseY);
  }
}// class Monster //

class Animal
{
  float x,y,dx,dy;
  Animal() {reset(); }
  void reset() {
    x=30;
    y=random(200,500);
    println(horizon);
    dx=random(3,5);
    dy=random(2,4);
  }
  void move() {
    if (x>width+30 || x<30) dx=-dx;
    if (y>height-30 || y<horizon+30) dy=-dy;
    x +=dx;
    y +=dy;
  }
  void show() {
    noStroke();
    fill(255);
    ellipse(x,y,90,40);
    float front=x+25;
    float rear=x+30;
    if (dx<0) {front=x-10;rear=x+30;}
    ellipse(rear,y-10,16,16);
    stroke(255);
    fill(255,150,150);
    triangle(front-20,y-8,front-12,y-8,front-16,y-20);
    triangle(front-12,y-8,front-4,y-8,front-8,y-20);
    stroke(0);
  }
  boolean near (float xx,float yy) {
    return dist(x,y,xx,yy)<nearby;
  }
  boolean clicked() {
    return near(mouseX, mouseY);
  }
}// class Animal //

class Tree
{
  float x,y,w,h;
  color leaves,trunk;
  Tree(float x, float y)
  {
    this.x=x;
    this.y=y;
    this.w=random(120,100);
    this.h=random(100,150);
    this.leaves=color(random(100),random(100,250),random(100) );
    this.trunk=color(random(100,200),random(0,100),random(0,100) );
  }
  void show () {
    fill(leaves);
    ellipse(x,y,w,w);
    fill(trunk);
    rect(x-w/14,y+w/2,w/8,h);
  }
}