String title = "Witch vs Monster";
String author = "Chandni Ochani";
String news="...";
String hint1= "Click below horizon for a surprise!";
String hint2= "Use buttons to attack.";

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 = 10, right = 700, horizon = 400, bottom = 500;
float xTreat = 5, yTreat;
float nearby = 25;

void setup () {
  size (800,600);
  horizon = height/3;
  one = new Button ("Attack", 40,40,color (255,255,0) );
  two = new Button ("Reset", 40,80,color (255,0,255) );
  three = new Button ("Back",40,120,color (100) );
  four = new Button ("Trees",40,160,color (180) );
  //
  xTreat = width - 80;
  yTreat = random(horizon+25,height-25);
  //
  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,190,0);
}

void draw() {
  scene() ;
  action();
  trees();
  messages() ;
}

void scene() {
  background (80,80,80);
  fill (100,200,100);
  rect (0,horizon,width,height-horizon);
  fill (180,180,180);
  float xMoon=width/4, yMoon=horizon/4;
  if (abs(xMoon-orly.x)<30) fill (0);
  ellipse (xMoon,yMoon,60,60);
  // 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<=5) return;
  float w=60, h=50;
  fill(random(255,0),0,0);
  rect(x,y,w-random(10),h-random(10) );
  fill(255,0,0);
  rect(x,y,w-random(6,8), h-random(6,8) );
  fill(255,0,0);
  rect(x,y,w-random(13,20), h-random(13,20) );
}
void messages() {
  fill(255);
  textSize(20);
  text(title,15,15);
  textSize(18);
  text("SCORE:"+score,width-220,30);
  textSize(16);
  text( news,width-220,40);
  text( hint1, width/3, 30);
  text( hint2, width/3,50);
  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=5; }
  //
  else if (mouseY>horizon) {
    xTreat=mouseX;
    yTreat=mouseY;
    score -=25;
    news= "Award is given.";
    carol.reset();
    orly.reset();
  }
}
void zap() {
  score-=25;
  background(255,255,0);
}
void backWitch() {
  orly.dx *=-5;
}
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,90,90); }
  Button(float xx,float yy) {
    this("Click here",xx,yy);
  }
  Button(String name,float xx, float yy) {
    this(name, xx, yy, color(0,255,255) );
  }
  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=40,y=150,dx,dy;
  float w=40,h=80;
  void move() {
    if (xTreat<=5) {return;}
    dx= (xTreat-x) / random(800,1400); 
    dy= (yTreat-y) / random(800,1400);
    x +=dx;
    y +=dy;
    if (near(xTreat, yTreat)) {
    news= "Monster found the surprise!";
    score -=70;
    xTreat=0; // Treat vanishes.
    carol.reset();
    }
  }
  void reset() {x=0;}
  void show() {
    if (x<=0) return;
    float step=5;
    if (x%50<50) step= -step;
    fill(20);
    rect(x,y+step,w/3,h);
    rect(x+w/3,y-step,w/3,h);
    fill(0,255,255);
    ellipse( x+w/3,y-20,50,50);
    fill(255);
    ellipse( x+w/3-20,y-30,6,6); //eyes
    ellipse( x+w/3+20,y-30,6,6);
  }
  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(100,400);
    println(horizon);
    dx=random(4,6);
    dy=random(1,3);
  }
  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(225);
    ellipse(x,y,70,20);
    float front=x+20;
    float rear=x+20;
    if (dx<0) {front=x-20;rear=x+20;}
    ellipse(rear,y-20,14,14);
    stroke(255);
    fill(0,0,255);
    triangle(front-10,y-6,front-12,y-8,front-12,y-18);
    triangle(front-12,y-6,front-6,y-8,front-4,y-18);
    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,90);
    this.h=random(120,130);
    this.leaves=color(random(180),random(180,230),random(180) );
    this.trunk=color((51),(51),(51) );
  }
  void show () {
    fill(leaves);
    ellipse(x,y,w,w);
    fill(trunk);
    rect(x-w/10,y+w/2,w/10,h);
  }
}
