package psJava;

import java.io.*;

public class ConsoleIn {

  private static InputStreamReader inStream = new InputStreamReader(System.in);
  private static BufferedReader ins = new BufferedReader(inStream);
  private static int maxAttempt = 10;

  public ConsoleIn() {
  }

  public static String readString(String prompt) {
    for (int attempt = 1; attempt <= maxAttempt; attempt++) {
      try {
        System.out.print(prompt + " >> ");
        return ins.readLine();
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + maxAttempt);
        if (attempt == maxAttempt)
          e.printStackTrace();
      }
    } // end for

    System.out.println("Too many attempts - value is null");
    return null;
  }

  public static int readInt(String prompt) {
    for (int attempt = 1; attempt <= maxAttempt; attempt++) {
      try {
        System.out.print(prompt + " >> ");
        String num = ins.readLine();
        int intNum = Integer.parseInt(num);
        return intNum;
      } catch (NumberFormatException e) {
        System.out.println("Invalid integer - try again");
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + maxAttempt);
        if (attempt == maxAttempt)
          e.printStackTrace();
      }
    } // end for

    System.out.println("Too many attempts - value is 1");
    return 1;
  }

  public static int readInt(String prompt, int min, int max) {
    for (int attempt = 1; attempt <= maxAttempt; attempt++) {
      try {
        System.out.print(prompt + " (" + min + "..." + max + ") >> ");
        String num = ins.readLine();
        int intNum = Integer.parseInt(num);
        if (intNum >= min && intNum <= max)
          return intNum;
        else if (intNum < min)
          System.out.println(intNum + " is too small - try again");
        else
          System.out.println(intNum + " is too large - try again");
      } catch (NumberFormatException e) {
        System.out.println("Invalid integer - try again");
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + maxAttempt);
        if (attempt == maxAttempt)
          e.printStackTrace();
      }
    } // end for

    System.out.println("Too many attempts - value is 1");
    return 1;
  }

  public static double readDouble(String prompt) {
    for (int attempt = 1; attempt <= maxAttempt; attempt++) {
      try {
        System.out.print(prompt + " >> ");
        String num = ins.readLine();
        double realNum = Double.parseDouble(num);
        return realNum;
      } catch (NumberFormatException e) {
        System.out.println("Invalid number - try again");
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + maxAttempt);
        if (attempt == maxAttempt)
          e.printStackTrace();
      }
    } // end for

    System.out.println("Too many attempts - value is 1.0");
    return 1.0;
  }

  public static double readDouble(String prompt, double min, double max) {
    for (int attempt = 1; attempt <= maxAttempt; attempt++) {
      try {
        System.out.print(prompt + " (" + min + "..." + max + ") >> ");
        String num = ins.readLine();
        double realNum = Double.parseDouble(num);
        if (realNum >= min && realNum <= max)
          return realNum;
        else if (realNum < min)
          System.out.println(realNum + " is too small - try again");
        else
          System.out.println(realNum + " is too large - try again");
      } catch (NumberFormatException e) {
        System.out.println("Invalid number - try again");
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + maxAttempt);
        if (attempt == maxAttempt)
          e.printStackTrace();
      }
    } // end for

    System.out.println("Too many attempts - value is 1.0");
    return 1.0;
  }

  public static char readChar(String prompt) {
    for (int attempt = 1; attempt <= maxAttempt; attempt++) {
      try {
        System.out.print(prompt + " >> ");
        String str = ins.readLine();
        if (str.length() == 1)
          return str.charAt(0);
        else {
          System.out.println(str + " is not a single character - try again");
        }
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + maxAttempt);
        if (attempt == maxAttempt)
          e.printStackTrace();
      }
    } // end for

    System.out.println("Too many attempts - value is ' '");
    return ' ';
  }


  public static char readChar(String prompt, char min, char max) {
    for (int attempt = 1; attempt <= maxAttempt; attempt++) {
      try {
        System.out.print(prompt + " (" + min + "..." + max + ") >> ");
        String str = ins.readLine();
        if (str.length() == 1) {
          char ch = str.charAt(0);
          if (ch >= min && ch <= max)
            return ch;
          else if (ch < min)
            System.out.println(ch + " is too small - try again");
          else
            System.out.println(ch + " is too large - try again");
        } else {
          System.out.println(str + " is not a single character - try again");
        }
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + maxAttempt);
        if (attempt == maxAttempt)
          e.printStackTrace();
      }
    } // end for

    System.out.println("Too many attempts - value is ' '");
    return ' ';
  }

  public static boolean readBoolean(String prompt) {
    for (int attempt = 1; attempt <= maxAttempt; attempt++) {
      try {
        System.out.print(prompt + " (true/false) >> ");
        String str = ins.readLine();
        if (str.equalsIgnoreCase("true") || str.equalsIgnoreCase("t"))
          return true;
        else if (str.equalsIgnoreCase("false") || str.equalsIgnoreCase("f"))
          return false;
        else
          System.out.println(str + " is not boolean - try again");
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + maxAttempt);
        if (attempt == maxAttempt)
          e.printStackTrace();
      }
    } // end for

    System.out.println("Too many attempts - value is false");
    return false;
  }

  public static boolean readBoolean(String prompt, String trueAns, String falseAns) {
    for (int attempt = 1; attempt <= maxAttempt; attempt++) {
      try {
        System.out.print(prompt + " (" + trueAns + "/" + falseAns + ") >> ");
        String str = ins.readLine();
        if (str.equalsIgnoreCase(trueAns))
          return true;
        else if (str.equalsIgnoreCase(falseAns))
          return false;
        else
          System.out.println(str + " is not " + trueAns +
                             "/" + falseAns + " - try again");
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + maxAttempt);
        if (attempt == maxAttempt)
          e.printStackTrace();
      }
    } // end for

    System.out.println("Too many attempts - value is false");
    return false;
  }

  public static int readChoice(String prompt, String[] options) {
    for (int attempt = 1; attempt <= maxAttempt; attempt++) {
      try {
        System.out.print(prompt + " (");
        // Display choices after prompt.
        for (int i = 0; i < options.length - 1; i++)
          System.out.print(options[i] + ", ");
        System.out.println(options[options.length-1] + ") >> ");
        String str = ins.readLine();

        // Return the index if str matches a choice.
        for (int i = 0; i < options.length; i++)
          if (options[i].equals(str))
            return i;
        System.out.println(str + " does not match any choice - try again");
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + maxAttempt);
        if (attempt == maxAttempt)
          e.printStackTrace();
      }
    } // end for

    System.out.println("Too many attempts - value is -1");
    return -1;
  }

  /*
  //  main method to test class methods
  public static void main(String[] args) {
     String data = readString("Enter name ");
     System.out.println("name is " + data);
     int kids = readInt("How many kids ");
     System.out.println("number of kids is " + kids);
     kids = readInt("How many kids ", 1, 5);
     System.out.println("number of kids is " + kids);
     double sal = readDouble("Enter salary $");
     System.out.println("Salary is " + sal);
     sal = readDouble("Enter salary $", 500.0, 1000.0);
     System.out.println("Salary is " + sal);
     char ch = readChar("enter letter");
     System.out.println("letter is " + ch);
     ch = readChar("enter letter", 'a', 'z');
     System.out.println("letter is " + ch);
     boolean bool = readBoolean("Your status is single");
     System.out.println("single status is " + bool);
     bool = readBoolean("Are you single", "yes", "no");
     System.out.println("single status is " + bool);
     String[] choices = {"black", "cream only", "sugar only", "cream & sugar"};
     int coffee = readChoice("Select a coffee choice", choices);
     System.out.println("choice is " + coffee);
  }
  */
}