import processing.core.*; 
import processing.data.*; 
import processing.event.*; 
import processing.opengl.*; 

import ddf.minim.*; 

import java.util.HashMap; 
import java.util.ArrayList; 
import java.io.File; 
import java.io.BufferedReader; 
import java.io.PrintWriter; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.IOException; 

public class LD33_Who_s_Da_Monster extends PApplet {



int timeAware;
int timeBlind;
final int timeCage = 2000;
int timer = 0;
boolean blind = false;
int chosenOne = 0;
int cageX;
int cageY = -182;
int frameStop = 0;
int frameTrans = 14;

public void setup() {
 
  surface.setTitle("Who's Da Monster ? - Ludum Dare 33 - Natura-Time");
  noStroke();
  background(0);
  loadFonts();
  textFont(PFsleeve);
  textAlign(CENTER, CENTER);
  fill(0xffCC0000);
  text("Who's Da Monster ?", width / 2, 80);
  textSize(52);
  fill(255);
  text("Your people are getting eaten !\nYou must find the monster during his human form\nafter its first attack !\n \nClick to save your people !", width / 2, height / 2 + 30);
  textSize(32);
  text("By Natura-Time (Twitter : NaturaTime / naturatime.net) - Ludum Dare 33 : You are the monster", width / 2, 635);
  text("Musics by MagikStudio (Jamendo.com) - Sounds by LittleRobotSoundFactory, scorepion and sforsman (freesound.com)", width / 2, 670);
  textSize(128);
  HumansLook = new IntList();
  HumansPos = new IntList();
  Deads = new IntList();
  loadGraph();
  loadSounds();
  playMusic(true);
  cageX = (width / 2) - 80;
}

public void draw() {
  if (!blind) {
    if ((wave < 5) && (millis() - timer >= timeAware)) {
      timer = millis();
      blind = true;
      background(0);
      ASmonster[0].trigger();
    }
    else if ((wave == 5) && (millis() - timer >= timeCage)) {
      cageY += 8;
      displayChoose(true);
      if (cageY >= (height / 2) - 21) {
        wave = Humans.get(chosenOne).monster ? PApplet.parseByte(7) : PApplet.parseByte(6);
        timer = millis();
        frameStop = frameCount;
      }
    }
    else if ((wave == 6) && (millis() - timer >= timeCage)) {
      displayChoose(false);
      blind = false;
      wave = 10;
      timer = millis();
    }
    else if (wave == 7) {
      if (frameCount - frameStop >= 15) {
        frameStop = frameCount;
        frameTrans--;
      }
      if (frameCount - frameStop <= frameTrans) displayEnd(true);
      else displayEnd(false);
      if (frameTrans == -1) {
        wave = 8;
        timer = millis();
        ASmonster[1].trigger();
      }
    }
    else if ((wave == 8) && (millis() - timer >= timeCage)) {
      wave++;
      blind = false;
    }
    else if ((wave == 9) && !blind) {
      background(10);
      fill(255);
      text("Next level : " + (level + 1) + "\n \n Click to save your people !", width / 2, (height / 2) - 20);
    }
    else if ((wave == 10) && !blind && (millis() - timer >= timeCage * 2)) {
      playMusic(true);
      background(10);
      fill(255);
      if (level > 1) text("Next level : " + (level - 1) + "\n \n Click to save your people !", width / 2, (height / 2) - 20);
      else text("Next level : 1\n \n Click to save your people !", width / 2, (height / 2) - 20);
    }
  }
  else {
    if (millis() - timer >= timeBlind) {
      timer = millis();
      blind = false;
      killHumans();
      background(clrBg);
      for (int iter = 0; iter < Humans.size(); iter++) {
        Humans.get(iter).display();
      }
    }
  }
}

public void mouseClicked() {
  if ((wave > 0) && (wave < 5)) {
    int humanX;
    int humanY;
    for (int iter = HumansPos.size() - 1; iter >= round(wave * ((HumansPos.size() - 1) / 5.0f)); iter--) {
      humanX = HumansPos.get(iter) / 1000;
      humanY = HumansPos.get(iter) % 1000;
      if ((mouseX >= humanX) && (mouseX < humanX + 24) && (mouseY >= humanY) && (mouseY < humanY + 48)) {
        wave = 5;
        Humans.get(iter).X = (width / 2) - 12;
        Humans.get(iter).Y = (height / 2) + 96;
        chosenOne = iter;
        displayChoose(true);
        timer = millis();
        playMusic(true);
      }
    }
  }
  else if (wave == 9) newGame(level + 1);
  else if (wave == 10) newGame(level - 1);
  else if (level == 0) newGame(level + 1);
}

public void displayChoose(boolean good) {
  background(10);
  Humans.get(chosenOne).display();
  noTint();
  image(PIcage, cageX, cageY);
  if (good) {
    fill(0xffFFFFFF);
    text("YOU ARE THE MONSTER !!", width / 2, 150);
  }
  else {
    fill(0xffCC0000);
    text("Or... The last human alive...", width / 2, 150);
    ASmonster[2].trigger();
  }
}

public void displayEnd(boolean monster) {
  background(10);
  if (monster) {
    Humans.get(chosenOne).display();
    noTint();
  }
  else image(PImonster, cageX, cageY);
  image(PIcage, cageX, cageY);
  fill(0xffFFFFFF);
  text("YOU ARE THE MONSTER !!", width / 2, 150);
}
byte wave = 20;
int level = 0;

public void newGame(int lvl) {
  background(clrBg);
  level = lvl == 0 ? 1 : lvl;
  wave = 0;
  blind = false;
  chosenOne = 0;
  cageY = -182;
  frameTrans = 19;
  timeAware = timeAware <= 5000 ? 5000 : 9400 - (level * 400);
  timeBlind = timeBlind >= 2000 ? 2000 : level * 200;
  initHumans(2 + (level * 2));
  timer = millis();
  playMusic(false);
}

public void initHumans(int number) {
  Humans.clear();
  HumansLook.clear();
  HumansPos.clear();
  for (int iter = 0; iter < number; iter++) {
    createHuman(false);
    Humans.get(iter).display();
  }
}

public void createHuman(boolean monster) {
  int humanLook;
  int humanLookShirt;
  int humanLookClrShirt1;
  int humanLookClrShirt2;
  int humanPosX;
  int humanPosY;
  do {
    humanLook = floor(random(0, 8)) * 100000 + floor(random(0, 8)) * 10000 + floor(random(0, 8));
    humanLookShirt = floor(random(0, 8)) * 1000;
    humanLookClrShirt1 = floor(random(0, 8)) * 100;
    if (humanLookShirt == 0) humanLookClrShirt2 = humanLookClrShirt1 / 10;
    else do humanLookClrShirt2 = floor(random(0, 8)) * 10;
      while (humanLookClrShirt2 * 10 == humanLookClrShirt1);
    humanLook += humanLookShirt + humanLookClrShirt1 + humanLookClrShirt2;
  }
  while (HumansLook.hasValue(humanLook));
  HumansLook.append(humanLook);
  do {
    humanPosX = floor(random(32, 1145));
    humanPosY = floor(random(32, 621));
  }
  while (HumansPos.hasValue(humanPosX * 1000 + humanPosY));
  HumansPos.append(humanPosX * 1000 + humanPosY);
  Humans.add(new CLhuman(humanLook, humanPosX, humanPosY, PApplet.parseBoolean(floor(random(0, 2))), monster));
}

public void killHumans() {
  if (wave == 0) createHuman(true);
  for (int iter = round(wave * ((Humans.size() - 1) / 5.0f)); iter < round((wave + 1) * ((Humans.size() - 1) / 5.0f)); iter++) {
    Humans.get(iter).hair = -1;
  }
  wave = wave == 4 ? PApplet.parseByte(10) : PApplet.parseByte(wave + 1);
  timer = millis();
}
PImage[] PIhair = new PImage[8];
PImage[] PIshirt1 = new PImage[8];
PImage[] PIshirt2 = new PImage[8];
PImage[] PIbottom = new PImage[2];
PImage PIblood = createImage(24, 16, ARGB);
PImage PIcage;
PImage PImonster;
PFont PFsleeve;
int clrBg = 0xffBFA285;
int[] palette = {0xff000000, 0xff0000FF, 0xff00FF00, 0xff00FFFF, 0xffFF0000, 0xffFF00FF, 0xffFFFF00, 0xffFFFFFF};
Minim minim;
AudioPlayer[] APmusic = new AudioPlayer[2];
AudioSample[] ASmonster = new AudioSample[3];

public void loadGraph() {
  PIcage = loadImage("Assets/cage.png");
  PImonster = loadImage("Assets/monster.png");
  PImage PIhumans = loadImage("Assets/humans.png");
  PIblood.copy(PIhumans, 48, 48, 24, 16, 0, 0, 24, 16);
  for (int iter = 0; iter < 8; iter++) {
    int iter24 = iter * 24;
    PIhair[iter] = createImage(24, 16, ARGB);
    PIhair[iter].copy(PIhumans, iter24, 0, 24, 16, 0, 0, 24, 16);
    PIshirt1[iter] = createImage(24, 16, ARGB);
    PIshirt1[iter].copy(PIhumans, iter24, 16, 24, 16, 0, 0, 24, 16);
    PIshirt2[iter] = createImage(24, 16, ARGB);
    PIshirt2[iter].copy(PIhumans, iter24, 32, 24, 16, 0, 0, 24, 16);
    if (iter < 2) {
      PIbottom[iter] = createImage(24, 16, ARGB);
      PIbottom[iter].copy(PIhumans, iter24, 48, 24, 16, 0, 0, 24, 16);
    }
  }
}

public void loadFonts() {
  PFsleeve = createFont("Assets/sing_14l.ttf", 128);
}

public void loadSounds() {
  minim = new Minim(this);
  APmusic[0] = minim.loadFile("Assets/MagikStudio - Suspense trailer.mp3");
  APmusic[1] = minim.loadFile("Assets/MagikStudio - Trailer Percussion.mp3");
  ASmonster[0] = minim.loadSample("Assets/LittleRobotSoundFactory - Monster_04.wav");
  ASmonster[1] = minim.loadSample("Assets/sforsman - growl 2.wav");
  ASmonster[2] = minim.loadSample("Assets/scorepion - dinosaur.wav");
}

public void playMusic(boolean menuMusic) {
  if (!APmusic[PApplet.parseInt(menuMusic)].isPlaying()) {
    APmusic[PApplet.parseInt(!menuMusic)].pause();
    APmusic[PApplet.parseInt(!menuMusic)].rewind();
    APmusic[PApplet.parseInt(menuMusic)].loop();
  }
}
IntList HumansLook;
IntList HumansPos;
ArrayList<CLhuman> Humans = new ArrayList<CLhuman>();
IntList Deads;

class CLhuman {
  byte hair;
  byte clrHair;
  byte shirt;
  byte clrShirt1;
  byte clrShirt2;
  byte clrBottom;
  int X;
  int Y;
  boolean skirt;
  boolean monster;
  
  CLhuman(int look, int XT, int YT, boolean skirtT, boolean monsterT) {
    hair = PApplet.parseByte(look / 100000);
    clrHair = PApplet.parseByte(look / 10000 % 10);
    shirt = PApplet.parseByte(look / 1000 % 10);
    clrShirt1 = PApplet.parseByte(look / 100 % 10);
    clrShirt2 = PApplet.parseByte(look / 10 % 10);
    clrBottom = PApplet.parseByte(look % 10);
    X = XT;
    Y = YT;
    skirt = skirtT;
    monster = monsterT;
  }
  
  public void display() {
    if (hair >= 0) {
      fill(0xffFFCC99);
      rect(X, Y, 24, 16);
      rect(X, Y + 42, 10, 6);
      rect(X + 14, Y + 42, 10, 6);
      tint(palette[clrHair]);
      image(PIhair[hair], X, Y);
      tint(palette[clrShirt1]);
      image(PIshirt1[shirt], X, Y + 16);
      tint(palette[clrShirt2]);
      image(PIshirt2[shirt], X, Y + 16);
      tint(palette[clrBottom]);
      image(PIbottom[PApplet.parseInt(skirt)], X, Y + 32);
    }
    else {
      noTint();
      image(PIblood, X, Y + 32);
    }
  }
}
  public void settings() {  size(1200, 700); }
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "LD33_Who_s_Da_Monster" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}
