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

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 AbilityTimer extends PApplet {

// This software is distributed under the terms of the MIT License.
// Copyright (c) 2018, molelord
// All rights reserved.

//import processing.awt.PSurfaceAWT;
//import processing.awt.PSurfaceAWT.SmoothCanvas;
//import javax.swing.JFrame;

//String appname = "Ability Timer";
//String version = "0.10";

class Timerdisplay {
  int x;
  int y;
  int endTime;
  boolean visible;
  Timerdisplay(int _x, int _y){
    x       = _x;
    y       = _y;
    endTime = 0;
    visible = false;
  }
  public void start(int seconds) {
    endTime = millis() + 1000*seconds;
    visible = true;
  }
  public boolean getVisible() {
    return visible;
  }
  public void render() {
    fill(0);
    rect(x, y, 80, 30);
    textSize(24);
    int currentTime = millis();
    int remainTime = endTime - currentTime;
    String msg = "000.0";
    if (remainTime <= 0) {
      fill(255, 0, 0);
      visible = false;
    } else {
      fill(0, 255, 0);
      int sec = remainTime / 1000;
      int dec = (remainTime / 100) % 10;
      String zeros = "";
      if (sec < 10) {
        zeros = "00";
      } else if (sec < 100) {
        zeros = "0";
      }
      msg = zeros + str(sec) + "." + str(dec);
    }
    text(msg, x+5, y+22);
  }
  public void press(){
    if(isOver()){
      visible = false;
    }
  }
  public boolean isOver(){
    return(mouseX>x&&mouseX<x+80&&mouseY>y&&mouseY<y+30);
  }
}

class Timerbutton {
  int seconds;
  int x, y;
  Timerdisplay td;
  boolean b;
  Timerbutton(int _seconds, int _x, int _y, Timerdisplay _td){
    seconds = _seconds;
    x  = _x;
    y  = _y;
    td = _td;
    b  = false;
  }
  public void render(){
    stroke(0); // color of box's flame
    strokeWeight(1);
    fill(isOver()?240:255); // color of box
    rect(x, y, 40, 30);
    stroke(64);
    rect(x+1, y+1, 40-3, 30-3);
    stroke(128);
    rect(x+2, y+2, 40-3, 30-3);
    if (b) {
      fill(0,255,0);
    } else {
      fill(0);
    }
    textSize(12);
    text(str(seconds) + "s", x+5, y+20);
  }
  public void press(){
    if(isOver()){
      td.start(seconds);
      b=true;
    }
  }
  public void release(){
    if(isOver()){
      b=false;
    }
  }
  public boolean isOver(){
    return(mouseX>x&&mouseX<x+40&&mouseY>y&&mouseY<y+30);
  }
}

class Timerbar {
  int seconds;
  int x, y;
  Timerdisplay td;
  Timerbar(int _seconds, int _x, int _y, Timerdisplay _td){
    seconds = _seconds;
    x  = _x;
    y  = _y;
    td = _td;
  }
  public void render(){
    stroke(224);
    strokeWeight(1);
    fill(255); // Left side
    triangle(x,y, x,y+360, x+75,y+360);
    fill(240); // Right side
    triangle(x,y, x+75,y,  x+75,y+360);

    if (isOver()) {
      fill(0, 255, 0);
      triangle(x,y, x,mouseY, x+mouseY/5,mouseY);
    }
  }
  public int computeSeconds() {
    int pos = mouseY/2;
    if (pos < 50) {
      // do nothing
    } else {
      pos = pos/5*5;
    }
    return pos;
  }
  public void textRender(){
    if (isOver()) {
      fill(0, 255, 0);
      textSize(24);
      text(str(computeSeconds()) + "sec", x+105, mouseY);
    }
  }
  public void press(){
    if(isOver()){
      td.start(computeSeconds());
    }
  }
  public boolean isOver(){
    return(mouseX>x&&mouseX<x+75&&mouseY>y&&mouseY<y+360);
  }
}

// Thanks to https://forum.processing.org/two/discussion/4849/checkbox
class Checkbox {
  int x, y;
  boolean b;
  Checkbox(int _x, int _y){
    x = _x;
    y = _y;
    b = false;
  }
  public void render(){
    stroke(0); // color of box's flame
    strokeWeight(1);
    fill(isOver()?224:255); // color of box
    rect(x, y, 20, 20);
    if(b){
      stroke(255, 0, 0); // color of v
      strokeWeight(2);
      line(x+2, y+10, x+10, y+15);
      line(x+10, y+15, x+18, y+2);
    }
  }
  public void click(){
    if(isOver()){
      b=!b;
    }
  }
  public boolean get(){
    return b;
  }
  public void set(){
    b = true;
  }
  public void reset(){
    b = false;
  }
  public boolean isOver(){
    return(mouseX>x&&mouseX<x+20&&mouseY>y&&mouseY<y+20);
  }
}

int next_y = 5;
int delta_y = 30;

class Mission {
  String name;
  Checkbox[] boxes;
  int y;
  Mission(String _name, int _items){
    name  = _name;
    boxes = new Checkbox[_items];
    y = next_y;
    next_y += delta_y;
    for(int i=0; i< boxes.length; i++){
      boxes[i] = new Checkbox(100 + 25 * i, y);
    }
  }
  public void render(){
    fill(0);
    textSize(12);
    text(name, 10, y+15);
    for(int i=0; i< boxes.length; i++){
      boxes[i].render();
    }
  }
}

ArrayList<Timerbutton> buttons = new ArrayList<Timerbutton>();
ArrayList<Mission> missions = new ArrayList<Mission>();
Timerdisplay tmdisp = new Timerdisplay(120, 10);
Timerbar     tmbar  = new Timerbar(180, 5, 5, tmdisp);

//JFrame jframe;

public void setup(){
  
  surface.setAlwaysOnTop(true);
  
  //PSurfaceAWT awtSurface = (PSurfaceAWT) surface;
  //SmoothCanvas smoothCanvas = (SmoothCanvas) awtSurface.getNative();
  //jframe = (JFrame)smoothCanvas.getFrame();
  //jframe.dispose();
  //jframe.setUndecorated(true);
  //jframe.setOpacity(.5f);
  //jframe.setVisible(true);
  
  
  //buttons.add(new Timerbutton(180, 10, 10, tmdisp));
  //buttons.add(new Timerbutton(15,  60, 10, tmdisp));
  missions.add(new Mission("Guild Order",    1));
  //missions.add(new Mission("Tower",          2));
  //missions.add(new Mission("Advent Battle",  5));
  //missions.add(new Mission("Advent Rag.",    1));
  //missions.add(new Mission("Advent Collab.", 5));
  missions.add(new Mission("Event Quests", 3));
  missions.add(new Mission("Daily Mission",  1));
  missions.add(new Mission("Material Exchg", 1));
  missions.add(new Mission("Gem Gacha",      1));
  missions.add(new Mission("Gem Quest",      2));
  missions.add(new Mission("Raid Quests",    1));
  missions.add(new Mission("Accessory Que.", 3));
}

int previous_time = 0;

public void draw(){
  background(240);
  if (tmdisp.getVisible()) {
    tmdisp.render();
  } else {
    tmbar.render();
    for(int i=0; i< buttons.size(); i++){
      buttons.get(i).render();
    }
    for(int i=0; i< missions.size(); i++){
      missions.get(i).render();
    }
    tmbar.textRender();
  }
}
 
public void mousePressed(){
  if (tmdisp.getVisible()) {
    tmdisp.press();
  } else {
    tmbar.press();
    for (int i=0; i< buttons.size(); i++) {
      Timerbutton b = buttons.get(i);
      b.press();
    }
    for (int i=0; i< missions.size(); i++) {
      Mission m = missions.get(i);
      for (int j=0; j< m.boxes.length; j++) {
        m.boxes[j].click();
        
        // Chain reaction
        if (m.boxes[j].get() == true) {
          for (int k = j-1; k >= 0; k--) {
            m.boxes[k].set();
          }
        }
        if (m.boxes[j].get() == false) {
          for (int k = j+1; k < m.boxes.length; k++) {
            m.boxes[k].reset();
          }
        }
      }
    }
  }
}

public void mouseReleased() {
  for (int i=0; i< buttons.size(); i++) {
    Timerbutton b = buttons.get(i);
    b.release();
  }
}
  public void settings() {  size(240,370);  smooth(); }
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "AbilityTimer" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}
