//The game scene. Contains all the input, output, and logic for the actual game.
public class Play extends Scene {
  
  //the access type for the answer should always be private.
  final String access = "private";
  
  //list of the return types for the questions in this game.
  final String[] types = new String[]{"int", "float", "boolean", "char", "String"};
  
  //list of java keywords from https://en.wikipedia.org/wiki/List_of_Java_keywords
  final String[] keywords = { "abstract", "assert", "boolean",
                "break", "byte", "case", "catch", "char", "class", "const",
                "continue", "default", "do", "double", "else", "extends", "false",
                "final", "finally", "float", "for", "goto", "if", "implements",
                "import", "instanceof", "int", "interface", "long", "native",
                "new", "null", "package", "private", "protected", "public",
                "return", "short", "static", "strictfp", "super", "switch",
                "synchronized", "this", "throw", "throws", "transient", "true",
                "try", "void", "volatile", "while" };
  
  //list of nouns for order examples.
  final String[] objects = { "cat", "house", "tree", "shoe", "coffee",
                "bee", "finger", "snack"};
  
  //list of attibutes of objects (for float)
  final String[] attributes = { "length", "width", "height", "weight",
                "mass", "volume", "splorpability"};
  
  //list of actions (for boolean)
  final String[] actions = { "walk", "run", "jump", "fly", "talk", "think",
                "go fishing", "take a nap" };
  
  //file path of the background image.
  final String bg_path = "crema.jpg";
  
  //file path of the image for the customer.
  final String customer_path = "fish.png";
  
  //background image
  PImage bg_img;
  
  //customer image
  PImage customer_img;
  
  //full prompt that the customer will ask.
  String prompt;
  
  //return type of the prompt.
  String prompt_type;
  
  //hint for the player if they got the order wrong.
  String hint_text = "";
  
  
  public Play() {
    addChild( new NavButton(width - 125, height - 65, 200, 50, CENTER, "Menu", 24).setVal(0) );
    GenerateOrder();
  }
  
  public void ready() {
    kb_text = "";
    hint_text = "";
    bg_img = loadImage(bg_path);
    customer_img = loadImage(customer_path);
  }
  
  //draw every frame. draws the basic shapes and text.
  public void process() {
    fill(color(204));
    image(bg_img, 0, 0, width, height);
    image(customer_img, 600, 100, 300, 200);
    rect(50, 50, width - 100, 50);
    rect(50, 350, width - 100, 50);
    triangle(620, 100, 700, 100, 650, 170);
    if (!hint_text.equals("")) rect(50, 400, width - 100, 50);
    
    fill(color(0));
    textAlign(CENTER);
    textSize(24);
    text(prompt, width/2, 85);
    text(kb_text, width/2, 385);
    textSize(16);
    if (!hint_text.equals("")) text(hint_text, width/2, 435);
  }
  
  //sets a random prompt_type and generates a new prompt statement.
  private void GenerateOrder() {
    prompt_type = types[(int)(rng.nextFloat() * types.length)];
    prompt = "I need a variable that stores ";
    
    switch (prompt_type) {
      case "int":
        prompt += "how many " + objects[(int)(rng.nextFloat() * objects.length)] + "s I have.";
        break;
      case "float":
        prompt += "the exact " + attributes[(int)(rng.nextFloat() * attributes.length)] + " of my "
          + objects[(int)(rng.nextFloat() * objects.length)] + ".";
        break;
      case "boolean":
        prompt += "whether or not my " + objects[(int)(rng.nextFloat() * objects.length)] + " can "
          + actions[(int)(rng.nextFloat() * actions.length)] + ".";
        break;
      case "char":
        prompt += "a letter in the word " + objects[(int)(rng.nextFloat() * objects.length)] + ".";
        break;
      case "String":
        prompt += "the name of my " + objects[(int)(rng.nextFloat() * objects.length)] + ".";
        break;
    }
    
  }
  
  
  public void CheckAnswer(String answer) {
    String hint = "";
    println(answer);
    String[] splits = split(answer, " ");
    
    if (!splits[0].equals(access)) {
      hint = "Remember our company's policy on encapsulation! (What comes before the data type?)";
    }
    
    else if (splits.length < 3) {
      hint = "Not enough terms! Are you missing the access, data type, or name?";
    }
    
    else if (!splits[1].equals(prompt_type)) {
      hint = "Something about that data type is wrong!";
    }
    
    else if (splits[2].equals(";")) {
      hint = "Looks like you didn't name the variable...";
    }
    
    else {
      String check = CheckName(splits[2].substring(0, splits[2].length() - 1));
      if (check != "correct") {
        hint = CheckName(splits[2]);
      }
      
      else if (!splits[2].substring(splits[2].length()-1).equals(";")) {
        hint = "I don't think that variable has its lid! (What does any statement end with in Java?)";
      }
      
      else if (splits.length > 3) {
        hint = "That's too many words for a simple variable declaration!";
      }
    }
    
    //win
    if (hint.equals("")) {
      gameManager.setCurrentScene(3);
      GenerateOrder();
    }
    //lose(ish)
    else {
      hint_text = hint;
    }
    
  }
  
  
  //Checks to see if the name of the variable follows Java naming conventions.
  //Returns "correct" if the name follows the rules, otherwise it
  //returns whatever the problem is.
  private String CheckName(String nam) {
    
    if (!canBeFirstChar(nam.charAt(0))) {
      return "The character " + nam.charAt(0) + " cannot be the first character in your variable's name!";
    }
    
    for (char c : nam.toCharArray()) {
      if (!isValidChar(c))
        return "The character " + c + " cannot be in the variable name!";
    }
    
    for (String s : keywords) {
      if (nam == s) {
        return "The word " + s + " is a Java keyword and cannot be used for your variable's name.";
      }
    }
    
    return "correct";
  }
  
  //returns true if the given character can be in the name of a variable.
  public boolean hasValidChars(String s) {
    boolean valid = true;
    for (char c : s.toCharArray()) {
      boolean v = false;
      if (c == '$') v = true;
      else if (c == '_') v = true;
      else if (c == ';') v = true;
      else if (c >= 48 && c <= 57) v = true;
      else if (c >= 65 && c <= 90) v = true;
      else if (c >= 97 && c <= 122) v = true;
      if (v) valid = false;
    }
    return valid;
  }
  
  //returns true if the given character can be in the name of a variable.
  public boolean isValidChar(char c) {
    boolean valid = false;
    if (c == '$') valid = true;
    else if (c == '_') valid = true;
    else if (c >= 48 && c <= 57) valid = true;
    else if (c >= 65 && c <= 90) valid = true;
    else if (c >= 97 && c <= 122) valid = true;
    return valid;
  }
  
  //returns true if the given character can be the first character of a variable.
  public boolean canBeFirstChar(char c) {
    boolean valid = false;
    if (c == '$') valid = true;
    else if (c == '_') valid = true;
    else if (c >= 65 && c <= 90) valid = true;
    else if (c >= 97 && c <= 122) valid = true;
    return valid;
  }
  
}
