//Generic button class for all buttons to extend from.
//Imported from my JavaGame project.
class Button extends Scene {
  private String name = "Button";
  private boolean lastFramePressed = false;
  
  int x = 0; //x-position
  int y = 0; //y-position
  int w = 1; //width
  int h = 1; //height
  
  boolean can_press = true;
  
  int align = CENTER;
  private float x_mod; //how much the shape needs to be shifted based on its align.
  
  String text = "";
  int text_size = 16;
  color text_color = color(0);
  
  color outline_color = color(0);
  color fill_normal = color(255);
  color fill_hover = color(204);
  color fill_press = color(127);
  
  public Button(int x_pos, int y_pos, int wid, int hei, int a, String t, int ts) {
    x = x_pos;
    y = y_pos;
    w = wid;
    h = hei;
    setAlign(a);
    text = t;
    text_size = ts;
  }
  
  public Button(int x_pos, int y_pos, int wid, int hei, int a) {
    x = x_pos;
    y = y_pos;
    w = wid;
    h = hei;
    setAlign(a);
  }
  
  public Button() {
  }
  
  //Methods that need to be overridden in a child class.
  public void onHover() {}
  public void onPress() {}
  public void onJustPress() {}
  public void onRelease() {}
  
  //When making a child, if you update the process, make sure to call super.process() at the top.
  //This process draws the button based on its current state.
  public void process() {
    
    if (isPressed())       fill(fill_press);
    else if (isHovered())  fill(fill_hover);
    else                   fill(fill_normal);
    stroke(outline_color);
    rect(x - w*x_mod, y - h/2, w, h);
    
    fill(text_color);
    textSize(text_size);
    textAlign(align);
    text(text, x, y + text_size/2);
    
    if (isHovered()) onHover();
    if (isPressed()) onPress();
    if (isJustPressed()) onJustPress();
    if (isJustReleased()) onRelease();
    
    lastFramePressed = isPressed();
  }
  
  
  public boolean isHovered() {
    return can_press && mouseX > x - w*x_mod && mouseX < x + w - w*x_mod && mouseY > y - h/2 && mouseY < y + h/2;
  }
  
  public boolean isPressed() {
    return (isHovered() && mousePressed);
  }
  
  public boolean isJustPressed() {
    return isPressed() && isHovered() && !lastFramePressed;
  }
  
  public boolean isJustReleased() {
    return !isPressed() && isHovered() && lastFramePressed;
  }
  
  public void setCanPress(boolean can) {
    can_press = can;
  }
  
  public boolean getCanPress() {
    return can_press;
  }
  
  //sets the align of both the button's rectangle relative to its position
  //coordinates as well as the alignment of the text.
  public void setAlign(int a) {
    align = a;
    switch (align) {
      case LEFT:
        x_mod = 0;
        break;
      case RIGHT:
        x_mod = 1;
        break;
      case CENTER:
        x_mod = 0.5;
        break;
      default:
        println("oopsies, setAlign() was called with a value it can't take.");
    }
  }
  
}
