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

import controlP5.*; 
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 AlbersGame extends PApplet {

/*
This is a simple sketch that uses rubbing, 
with sliders I found in the ControlP5 library via the Processing website, 
that allows the user to explore interactions of color a la joseph albers
*/

//imports the GUI library I'm using for the sliders. Should give some thought to coding these by hand though.

ControlP5 cp5;
//don't know what this is, but controlP5 says I need it
Slider abc;

//imports the library that handles music files

Minim minim;

//declares player instances for my audio tracks 
AudioPlayer elevator;
AudioPlayer wrong;
AudioPlayer correct;

//declares some fonts
PFont font;
PFont score;

//declares some images
PImage startScreen;
PImage playScreen;

//creates a color value for using with the controlP5 sliders
int myColor;

//delcares random colors for the inactive rect pair
int randoHue;
int randoSat;

//declares starting color for left innner rect; the one we change
int leftInnerHue;
int leftInnerSat;

//random color for the right outer rect; the one we want to match
int rightOuterHue;
int rightOuterSat;

//positioning values for the sliders
int sliderX;
int sliderY;

//the selection sweet spot for matching the colors
int sweetSpot;

//for showing the slider's label via code
boolean label;

//for controlling if we show the start screen or not
boolean gameStart;
int startCntr;

//boolean for checking for a match
boolean match;

//button class thingy
Button chk;
Button reset;
int bX;
int bY;
int bW;
int bH;

//for placing the "nope" or "nice" boxes
int rBX;
int rBY;
int rBW;
int rBH;

//for placing text in the response boxes
int rTX;
int rTY;
int rTSize;

//for setting the timer
int startTime;
int dispTime;
int matchTime;




public void setup() {
  
  //setting up the sketch's space
  colorMode(HSB, 100);
  size(1000, 400);
  noStroke();
  
  //colors for the slider
  myColor = color(0, 0, 0);
  
  // random colors for the inactive rect pair
  randoHue = PApplet.parseInt(random(100));
  randoSat = PApplet.parseInt(random(50, 100));
  
  // starting color for left innner rect; the one we change
  leftInnerHue = 55;
  leftInnerSat = 90;
  
  //random color for the right outer rect; the one we want to match
  rightOuterHue = PApplet.parseInt(random(100));
  rightOuterSat = PApplet.parseInt(random(20, 100));
  
  //positioning values for the sliders
  sliderX = 425;
  sliderY = 250;
  
  //the selection sweet spot for matching the colors
  sweetSpot = 6;
  
  //for showing the slider's label via code
  label = false;
  
  //for controlling if we show the start screen or not
  gameStart = false;
  startCntr = 1;
  
  //boolean for checking for a match
  match = false;
  
  //slider stuff
  cp5 = new ControlP5(this);
  
  //minim stuff
  minim = new Minim(this);
  
  //soundtrack
  elevator = minim.loadFile("Elevator Music Long.mp3");
  elevator.loop(3);
  elevator.pause();
  
  //right and wrong sounds
  wrong = minim.loadFile("wrong answer sound FX..mp3");
  correct = minim.loadFile("price is right.mp3");

  //loads png screens for game
  startScreen = loadImage("Albers Game-01.png");
  playScreen = loadImage("Albers Game-02.png");

  //loads font's for placing text
  font = loadFont("Mission-Script-50.vlw");
  score = loadFont("GearedSlab-Bold-115.vlw");
  
  //slider for Hue  
  cp5.addSlider("leftInnerHue")
    .setPosition(sliderX, sliderY)
    .setColorForeground(color(20, 20, 30))
    .setColorBackground(color(20, 20, 80))
    .setSize(150, 20)
    .setRange(0, 100)
    .setLabelVisible(label)
    ;

  //slider for saturation  
  cp5.addSlider("leftInnerSat")
    .setPosition(sliderX, sliderY + 30)
    .setColorForeground(color(20, 20, 30))
    .setColorBackground(color(20, 20, 80))
    .setSize(150, 20)
    .setRange(0, 100)
    .setLabelVisible(label)
    ;

  //set's values for our check & reset button's position
  bX = 409;
  bY = 345;
  bW = 86;
  bH = 45;
  
  //for the "check button"
  chk = new Button();
  chk.x = bX;
  chk.y = bY;
  chk.w = bW;
  chk.h = bH;
  
  //for the "reset" button
  reset = new Button();
  reset.x = bX;
  reset.y = bY;
  reset.w = bW;
  reset.h = bH;
  
  //for locating the response boxes (nope vs nice)
  rBX = 505;
  rBY = 345;
  rBW = 86;
  rBH = 45;
  
  //for controlling the text in the response boxes
  rTX = 525;
  rTY = 378;
  rTSize = 32;
  
  
}


public void draw() {
  
  background(75);
  elevator.pause();
  
  //controls when the start screen switches to the play screen
  if (gameStart == false) {
      
    //show's start screen
    image(startScreen, 0, 0);      
  }
  
  //shows play screen
  else if (gameStart == true) {
  
    elevator.play();
    
    //back rects
    
    //left rect
    fill(randoHue, randoSat, 100);
    rect(0, 0, width/2 - 100, height);
    //right outer rect
    fill(rightOuterHue, rightOuterSat, 100);
    rect(600, 0, width/2, height);


    //front rects
    
    //right inner rect
    fill(randoHue, randoSat, 100);
    rect(700, 100, width/4 - 50, height/2);

    // left inner rect 
    fill(leftInnerHue, leftInnerSat, 100);
    rect(100, 100, width/4 - 50, height/2);

    //draws the center play graphics
    image(playScreen, 0, 0);

    // if colors are the same
    if(match == true){
      
      //if game has started
      if (startCntr > 2){
        
        //draw a green box
        colorMode(HSB, 360, 100, 100);
        fill(127, 87, 93);
        rect(rBX, rBY, rBW, rBH);
      
        //put "nice!" in it
        colorMode(HSB, 100);
        fill(60);
        textFont(font, rTSize);
        text("nice!", rTX, rTY);
        
        //draw a reset button instead of the check button
        fill(100);
        rect(reset.x, reset.y, reset.w, reset.h);
        
        //put text in it
        fill(60);
        textFont(font, 32);
        text("reset?", 425, 378);
        
        //pause and rewind the music
        elevator.pause();
        elevator.rewind();
   
        //if reset gets clicked, refresh the variables and start at the beginning
        if (reset.isClicked() && match == true) {
          reboot();
        }        
      }
      
    //but if there is no color match      
    } else if (match == false)  {
      
      //draw a check button
      fill(100);
      rect(chk.x, chk.y, chk.w, chk.h);
      
      //put some text in it
      fill(60);
      textFont(font, 32);
      text("check?", 420, 378);
      
      //if this isn't the first click, to get past the start screen
      if (startCntr > 2){
        
        //draw an orange box
        colorMode(HSB, 360, 100, 100);
        fill(51, 85, 95);
        rect(rBX, rBY, rBW, rBH);
      
        //put "nope!" in it
        colorMode(HSB, 100);
        fill(60);
        textFont(font, rTSize);
        text("nope!", rTX, rTY);
      }
    }
    
    //setup our seconds/scoreboard
    fill(100);
    textAlign(CENTER);
    textFont(score, 115);
    
    //if there is no match
    if (match == false){
      
      //start counting by seconds
      dispTime = ((millis() - startTime) / 1000);
      println("dispTime: " + dispTime);
      text(dispTime, 500, 180);
    } 

      //if there is a match    
      else if (match == true){
        
      // grab the current time, and show that, and stop counting
      matchTime = dispTime;
      text(matchTime, 500, 180);    
    }
    
    //put the text back to left align
    textAlign(LEFT);    
  }
  
  //for debugging the values via the console
  if ((leftInnerHue + sweetSpot >= rightOuterHue) && (leftInnerHue - sweetSpot <= rightOuterHue)) {
    println("HUE!");
    println(leftInnerHue);
  }

  if ((leftInnerSat + sweetSpot >= rightOuterSat) && (leftInnerSat - sweetSpot <= rightOuterSat)) {
    println("SATURATION!" );
    println(leftInnerSat);
  }
}


//if the mouse is clicked, do this stuff
public void mouseClicked() {
  
  //add one to the start counter
  startCntr++;
  
  //get rid of the start screen and show the game
  if (startCntr == 2){
    gameStart = true;
    startTime = millis();    
  }
  
  //if we're playing the game, AND the mouse was clicked inside the check button
  if(startCntr > 2 && chk.isInside()){
    //and if there is a color match
    if ((leftInnerHue + sweetSpot >= rightOuterHue) && (leftInnerHue - sweetSpot <= rightOuterHue) && (leftInnerSat + sweetSpot >= rightOuterSat) && (leftInnerSat - sweetSpot <= rightOuterSat)){
      
      //then match is true
      match = true;
      
      //play the winning song
      correct.play();
      correct.rewind();
      
      //stop playing the elevator music
      elevator.pause();
      elevator.rewind();
    } 
      //otherwise, you're wrong so...   
      else {
      
      //there is no match
      match = false;
 
      //and play the buzzer track
      wrong.play();
      wrong.rewind();
    }  
  }
}


//this is a button class that tells us if the mouse is inside it
class Button{

  int x, y;
  int w, h;
  
  //for the boolean isInside, return true if inside, false if not
  public boolean isInside(){
    if(mouseX >= x && mouseX <= x+w && mouseY >= y && mouseY <= y+h){
      return true;
    }
    return false;
  }
  
  //boolean for knowing if button was clicked
  public boolean isClicked(){
    if((mousePressed == true) && (mouseX >= x && mouseX <= x+w && mouseY >= y && mouseY <= y+h)){
      return true;
    }
    return false;
  }
}

//this is a function for resetting the game
public void reboot(){
  //random colors for the inactive rect pair
  randoHue = PApplet.parseInt(random(100));
  randoSat = PApplet.parseInt(random(50, 100));

  //random color for the right outer rect; the one we want to match
  rightOuterHue = PApplet.parseInt(random(100));
  rightOuterSat = PApplet.parseInt(random(20, 100));
  
  //boolean for checking for a match
  match = false;

  //for controlling if we show the start screen or not
  startCntr = 0;
  gameStart = false;
}
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "AlbersGame" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}
