import pphys2d.bodies.*;
import pphys2d.joints.*;
import pphys2d.shapes.*;
import pphys2d.phys2d.raw.collide.*;
import pphys2d.phys2d.raw.strategies.*;
import pphys2d.phys2d.raw.forcesource.*;
import pphys2d.phys2d.util.*;
import pphys2d.phys2d.raw.shapes.*;
import pphys2d.*;
import pphys2d.phys2d.raw.*;
import pphys2d.phys2d.math.*;


Hammer h;

PPWorld world;  
void setup(){
smooth();
  size(500,500); 
  
  resetWorld();
  
}


void resetWorld(){
  world  = new PPWorld();
  world.setEdges(this, new Color (0,0,0,0));
  world. setEdgesRestitution(.8);

  h = new Hammer();

  world.add(h); 
 monsters = new HashSet();
   lastMonster = null;


}


HashSet monsters = new HashSet();
Monster lastMonster = null;


void draw(){
  background(60,20,60);
  world.draw(this);
  Iterator i = monsters.iterator();
  while(i.hasNext()){
    Monster m = (Monster)i.next();
    m.move();
    m.draw();
  }
  h.move();
  h.draw();
}


void keyPressed(){
   if(key == ' ') {resetWorld();  return; }
  addMonster(key);
}

void mousePressed(){
    char[] words = { 'v','w','g','f'};

    addMonster(words[int(random(words.length))]);
}

void addMonster(char key){
  Monster m = null;
  
  float a = random(2*PI);
  
  float mx = mouseX+ (30*cos(a));
    float my = mouseY+ (30*sin(a));
  float s = random(25,50);
  if(key == 'v'){
    m = new Vampire(mx, my,s);
   } 
   if(key == 'w'){
    m = new Witch(mx, my,s);
   } 
   if(key == 'g'){
    m = new Ghost(mx, my,s);
   } 
   if(key == 'f'){
    m = new Frankenstein(mx, my,s);
   } 
   if(m==null) return;
    monsters.add(m);
    world.add(m);    
  
    lastMonster = m;

}



abstract class Monster extends PPCircle{
  float sz;Monster t;
  Monster(float x, float y, float sz){
     super(sz);
    setDrawable(false);
    setMass(sz);
    this.sz = sz;
    setPosition(x,y);
      t = lastMonster;
      setRestitution(.8);

  }
  abstract void draw(); 
   boolean move(){
   float targetX = mouseX; float targetY = mouseY;
     if(t != null){
         targetX = t.getX();
                  targetY = t.getY();
     }
     
    float deltaX, deltaY;
    float mul = 2;
    if(getX() < targetX){
      deltaX = 1;
    } 
    else{
      deltaX = -1;       
    }
    if(getY() < targetY){
      deltaY = 1;
    } 
    else{
      deltaY = -1;       
    }
    setVelocity(getVelocityX() + deltaX*mul,getVelocityY()+deltaY*mul);
/*
    if(isTouchingBody(h)){
      //        world.remove(this);
      //   return true;

      dead = true; 
      return true; 
    }*/
    return false;
  }
}

class Vampire extends Monster {

  Vampire(float x,float y,float sz){
    super(x,y,sz);

  }
  void draw(){
    fill(200);
    stroke(0);
    strokeWeight(3);
    pushMatrix();
    translate(getX(),getY());
        rotate(getRotation());
    ellipse(0,0,sz,sz);
    fill(0);
    triangle(-sz/3,-sz*3/8,sz/3,-sz*3/8,0,-sz*9/16);//tohair
    triangle(-sz/3,-sz*3/8,sz/3,-sz*3/8,0,-sz/6);

    fill(255);

    triangle(-sz/4,0,-sz/8,sz/4,0,0); //left tooth
        triangle(sz/4,0,sz/8,sz/4,0,0); //right tooth
    fill(255,0,0);
    stroke(255,0,0);
    strokeWeight(5);
    line(-sz/8,sz/4,-sz/8,sz/4);
    line(sz/8,sz/4,sz/8,sz/4);

    strokeWeight(2);
    stroke(0);
    ellipse(-sz/4,-sz/6,sz/8,sz/8);
    ellipse(sz/4,-sz/6,sz/8,sz/8);

    popMatrix();

  }

}


class Ghost extends Monster {
  Ghost(float x,float y,float sz){
    super(x,y,sz);

  }
  void draw(){
    rectMode(CORNER);
    fill(255);
    stroke(0);
    strokeWeight(3);
    pushMatrix();

    translate(getX(),getY());
    rotate(getRotation());

    ellipse(0,0,sz,sz);
noStroke();
    rect(-sz/2,0,sz,sz/2);
    stroke(0);
  line(-sz/2,0,-sz/2,sz/2);
    line(-sz/2,sz/2,sz/2,sz/2);
    line(sz/2,sz/2,sz/2,0);

stroke(0);
    arc(0,0,sz,sz,PI,2*PI);

  fill(0);
    ellipse(-sz/4,-sz/5,sz/8,sz/8);
        ellipse(sz/4,-sz/5,sz/8,sz/8);
        ellipse(0,0,sz/8,sz/8);
    popMatrix();
}
}




class Witch extends Monster {

  Witch(float x,float y,float sz){
    super(x,y,sz);

  }
  void draw(){
    fill(0,128,0);
    stroke(0);
    strokeWeight(3);
    pushMatrix();
    translate(getX(),getY());
    rotate(getRotation());
    ellipse(0,0,sz,sz);
    fill(0);
    triangle(-sz/3,-sz*3/8,sz/3,-sz*3/8,0,-sz);//tophat
    triangle(-sz*3/4,-sz*3/8,sz*3/4,-sz*3/8,0,-sz*3/8);//bot hat

    noFill();

    triangle(0,-sz/8,sz/8,sz/8,-sz/8,sz/8); //nose
  //mouth
    line(-sz/4,sz/3,0,sz/4);
        line(sz/4,sz/3,0,sz/4);

  //eyes
  fill(255,0,0);
    strokeWeight(2);
    stroke(0);
    eye(-sz/4,-sz/6);
        eye(sz/4,-sz/6);
    popMatrix();

  }

  void eye(float x,float y){
    triangle(x-sz/8,y-sz/8,x,y+sz/8,x+sz/8,y-sz/8);
  }

}




class Frankenstein extends Monster {
  Frankenstein(float x,float y,float sz){
    super(x,y,sz);

  }
  void draw(){
    rectMode(CORNER);
    fill(120,250,120);
    stroke(0);
    strokeWeight(3);
    pushMatrix();

    translate(getX(),getY());
    rotate(getRotation());
    rect(-sz/2,-sz/2,sz,sz);
  

    //nose  
   //     eye(0,0);
  fill(0);
//hair
    rect(-sz/2,-sz/2,sz,sz/8);
        //ok eyes
    fill(128,128,0);
    eye(-sz/4,-sz/6);
    eye(sz/4,-sz/6);
  
  line(-sz/4,sz/4,sz/4,sz/4);
  fill(200);
  rect(-sz/2-sz/10,sz/2-sz/10,sz/10,sz/10);

  rect(-sz/2-sz/5, sz/2-sz*3/20,     sz/10,sz/5);

  rect(sz/2,sz/2-sz/10,sz/10,sz/10);

  rect(sz/2 + sz/10, sz/2-sz*3/20,     sz/10,sz/5);

  
    popMatrix();
}

  void eye(float x, float y){
     rect(x-sz/16,y-sz/16,sz/8,sz/8);
  }

}









class Hammer extends PPCircle{
  Hammer(){
    super(40); 
    setPosition(250,250);
    setFillColor(new Color(128,128,128));
    setStrokeColor(new Color(0,0,0));
    setRotDamping(5);
  }
  void move(){
    float deltaX, deltaY;
    deltaX =( mouseX - getX() )/2; 
    deltaY = (mouseY - getY() )/2; 

    setVelocity(getVelocityX() + deltaX,getVelocityY()+deltaY);
    setVelocity(getVelocityX()*.95,getVelocityY()*.95);


  }
  void draw(){
    strokeWeight(2);
    stroke(0);
    line(getX(),getY(),mouseX,mouseY); 
  }
}