import ddf.minim.*;

float GRAV  = .2;
float FLAP = 4;
float SIZE = 10;
float BALLSIZE=3;
int WINGSTEPS  =8;
float BALLSPEED=1.5;
fly player = new fly(10,150);
smartfly enemy = new smartfly(270,150);
dot ball = new dot(150,150,BALLSPEED,0);

int s = 0;


boolean gamegoing;
PImage start,win,lose;

AudioPlayer music;
void setup(){
  size(300,300); 
//  frame.setTitle("flywrenchpong");
  frameRate(60);
  Minim.start(this);
  music = Minim.loadFile("moveplay.mp3");
  music.play();
  music.loop();

  startgame();
  
  start = loadImage("start.gif");
  win  = loadImage("win.gif");
  lose = loadImage("lose.gif");


}


void startgame(){
  enemy.score = 0;
  player.score = 0;
 
}


void mouseClicked(){
  if(! gamegoing){
    startgame();
    gamegoing = true;
  } 
}


int[][] lcd =
{
  {
    1,1,1,0,1,1,1  }
  ,//0
  {
    0,0,1,0,0,0,1  }
  ,//1
  {
    0,1,1,1,1,1,0  }
  ,//2
  {
    0,1,1,1,0,1,1  }
  ,//3
  {
    1,0,1,1,0,0,1  }
  ,//4
  {
    1,1,0,1,0,1,1  }
  ,//5
  {
    1,1,0,1,1,1,1  }
  ,//6
  {
    0,1,1,0,0,0,1  }
  ,//7
  {
    1,1,1,1,1,1,1  }
  ,//8
  {
    1,1,1,1,0,0,1  }
  ,//9
  {
    0,0,1,0,0,0,1  }
  , //!
  {
    1,0,0,0,1,1,0  } //L

};


void drawnum(int s, float x, float y, int sz){
  if(lcd[s][0] == 1) rect(x,y+sz, sz,sz*2);
  if(lcd[s][1] == 1) rect(x+sz,y, sz*2,sz);
  if(lcd[s][2] == 1) rect(x+(3*sz),y+sz, sz,sz*2);
  if(lcd[s][3] == 1) rect(x+sz,y+(3*sz), sz*2,sz);
  if(lcd[s][4] == 1) rect(x,y+(4*sz), sz,sz*2);
  if(lcd[s][5] == 1) rect(x+sz,y+(6*sz), sz*2,sz);
  if(lcd[s][6] == 1) rect(x+(3*sz),y+(4*sz), sz,sz*2);
  if(s == 10) { //exclamatino mark needs extra box
    rect(x+(3*sz),y+(7.5*sz), sz,sz);
  }

}

void drawscore(fly f, float pos){
  fill(0,0,200,60);
  stroke(0,0,200,60);

  drawnum(f.score,pos,80,20);
}

void draw(){
  background(0); 
  drawscore(player,25);
  drawscore(enemy,195);
  if(! gamegoing){
     if(player.score == 0  && enemy.score ==  0 ) {
       image(start,50,50);
     } else {
        if(player.score == 10){
         image(win,50,50);
        } else {
          image(lose,50,50);
        }
     }
  } else {
  }
  

  player.move();
  player.draw();  
  if(gamegoing) enemy.ai();
  enemy.move();
  enemy.draw();  
  if(gamegoing){
    ball.move();
    ball.draw();
    ball.hitcheck();
    ball.scorecheck();
  }



}
void stop()
{
  music.close();
  super.stop();
}



void keyPressed(){
  player.flap();
  // enemy.flap();
  s++;
}
void keyReleased(){
  player.unflap();
  //  enemy.unflap();
}


class fly{
  float x,y,s;
  fly(float px, float py){
    x = px; 
    y = py;
    score = 0;
  } 
  boolean flapped = false;

  int percdown;
  float hite = 3;
  float inness = SIZE;
  int score;

  void draw(){

    strokeWeight(3);
    if(flapped){
      hite =  SIZE + (percdown / 2);
      inness = SIZE * (percdown / WINGSTEPS);
      stroke(255,0,0,200);

      line(x+inness,y+hite,x+SIZE,y); 
      line(x+SIZE,y,x+(SIZE*2)-inness,y+hite); 

      if(percdown < WINGSTEPS){
        percdown++;
      }       

    } 
    else {
      hite = 3;
      inness = SIZE;

      stroke(255);
      line(x,y,x+SIZE*2,y); 
    }
  }

  void flap(){
    if(! flapped){ 
      s = s - FLAP; 
      flapped = true;
      percdown++;
    }
  }
  void unflap(){
    flapped = false; 
    percdown = 0;
  }
  void bouncefloor(){
    if(y+hite >= 300){
      y = 300-hite;
      s = -.5 *  abs(s);
    }
  }

  void bounceceiling(){
    if(y < 0){
      y = 0;
      s = .8 *  abs(s);
    }
  }
  void move(){
    s = s + GRAV;
    y += s;
    bouncefloor();
    bounceceiling();

  }  




}


class smartfly extends fly{
  smartfly(float px, float py){
    super(px,py);
  } 
  int countdown;
  void ai(){
    if(!flapped && ball.xs > 0 && ball.y < y && countdown < 0){
      countdown = 10;
      flap();
    }  
    countdown--;
    if(countdown < 0){
      unflap(); 
    }
  }

}

class dot{
  float x,y,xs,ys;
  dot(float px, float py, float pxs, float pys ){
    x = px; 
    y = py; 
    xs = pxs; 
    ys = pys;  
  }
  void draw(){
    strokeWeight(3);
    stroke(255,200);
    fill(0);
    rect(x,y,BALLSIZE,BALLSIZE); 
  }
  void move(){
    x += xs;
    y += ys; 
    if(y < 0) {
      y = 0;
      ys *= -1;

    }

    if(y > 300-3) {
      y = 300-3;
      ys *= -1;

    }
  }

  void hitcheck(){
    if(x+2 > 10 && x+2 < 30 ){ //hit player?
      if(y+2 > player.y && y+2 < player.y +player.hite){
        xs = BALLSPEED;
        ys = constrain(player.s,-2,2); 
      }
    }

    if(x+2 > 270 && x+2 < 290 ){ //hit player?
      if(y+2 > enemy.y && y+2 < enemy.y +enemy.hite){
        xs = -BALLSPEED;
        ys = constrain(enemy.s,-2,2); 
      }
    }


  }

  void scorecheck(){
    if(x+BALLSIZE < 0){
      x = 150;
      enemy.score++;
      checkend();
    }
    if(x> 300){
      x = 150;
      //score player point 
      player.score++;
      checkend();
    }
  }
}


void  checkend(){
  if(enemy.score < 10 && player.score < 10){
    return;
  }
  if(enemy.score == 10){
    player.score = 11; //lose
    gamegoing = false;
  }
  if(player.score == 10){
    enemy.score = 11; //lose
        gamegoing = false;
  }

}