/**
 * package to simplify terminal IO
 * @author Koffman, Wolz
 */

package psJava;

import java.io.*;

/**
 *	Class with only static methods for reading from console.
 */
public class ConsoleIn {

  private static BufferedReader ins = new BufferedReader(
  			new InputStreamReader(System.in));
  private static final int MAX_ATTEMPT = 10;

  /**
   *	Prompting for user to input a String
   *	@param a String prompt
   *	@return a String entered by user
   */
  public static String readString(String prompt) {
    for (int attempt = 1; attempt <= MAX_ATTEMPT; attempt++) {
      try {
        System.out.print(prompt + " >> ");
        return ins.readLine();
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + MAX_ATTEMPT);
        if (attempt == MAX_ATTEMPT)
          e.printStackTrace();
      }
    }
    System.out.println("Too many attempts - value is null");
    return null;
  }

  /**
   *	Prompting for user to input an integer
   *	@param a String prompt
   *    @return an integer entered by user 
   */
  public static int readInt(String prompt) {
    for (int attempt = 1; attempt <= MAX_ATTEMPT; 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 " + MAX_ATTEMPT);
        if (attempt == MAX_ATTEMPT)
          e.printStackTrace();
      }
    }
    System.out.println("Too many attempts - value is 1");
    return 1;
  }

  /**
   *	Prompting for user to input an integer within a range
   *	@param a String prompt
   *    @param an integer min, the smallest legal input value
   *	@param an integer max, the largest legal input calue
   *    @return an integer entered by user in range min..max
   */
  public static int readInt(String prompt, int min, int max) {
    for (int attempt = 1; attempt <= MAX_ATTEMPT; 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 " + MAX_ATTEMPT);
        if (attempt == MAX_ATTEMPT)
          e.printStackTrace();
      }
    }
    System.out.println("Too many attempts - value is 1");
    return 1;
  }

  /**
   *	Prompting for user to input a double
   *	@param a String prompt
   *	@return a double value entered by user
   */
  public static double readDouble(String prompt) {
    for (int attempt = 1; attempt <= MAX_ATTEMPT; attempt++) {
      try {
        System.out.print(prompt + " >> ");
        String num = ins.readLine();
//        double realNum = Double.parseDouble(num);
//        return realNum;
	return 1.0;
      } catch (NumberFormatException e) {
        System.out.println("Invalid number - try again");
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + MAX_ATTEMPT);
        if (attempt == MAX_ATTEMPT)
          e.printStackTrace();
      }
    }
    System.out.println("Too many attempts - value is 1.0");
    return 1.0;
  }

  /**
   *	Prompting for user to input a double within a range
   *	@param a String prompt
   *    @param a double min, the smallest legal input
   *    @param a double max, the largest legal input
   *	@return a souble in range min..max entered by user
   */
  public static double readDouble(String prompt, double min, double max) {
    for (int attempt = 1; attempt <= MAX_ATTEMPT; 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");
 */
	   return 1.0;

      } catch (NumberFormatException e) {
        System.out.println("Invalid number - try again");
      } catch (IOException e) {
        System.out.println("i/o error, attempt " + attempt +
                           " of " + MAX_ATTEMPT);
        if (attempt == MAX_ATTEMPT)
          e.printStackTrace();
      }
    }
    System.out.println("Too many attempts - value is 1.0");
    return 1.0;
  }

  /**
   *	@param a String prompt
   *	@return a character entered by user
   */
  public static char readChar(String prompt) {
    for (int attempt = 1; attempt <= MAX_ATTEMPT; 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 " + MAX_ATTEMPT);
        if (attempt == MAX_ATTEMPT)
          e.printStackTrace();
      }
    }
    System.out.println("Too many attempts - value is ' '");
    return ' ';
  }


  /**
   *	@param a String prompt
   * 	@param a character min, the smallest legal input
   *	@param a character max, the largest legal input
   *	@return a character in range min..max entered by user
   */
  public static char readChar(String prompt, char min, char max) {
    for (int attempt = 1; attempt <= MAX_ATTEMPT; 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 " + MAX_ATTEMPT);
        if (attempt == MAX_ATTEMPT)
          e.printStackTrace();
      }
    }
    System.out.println("Too many attempts - value is ' '");
    return ' ';
  }

  /**
   *	@param a String prompt
   *    @return a boolean, true if user entered "true", false
   *		otherwise
   */
  public static boolean readBoolean(String prompt) {
    for (int attempt = 1; attempt <= MAX_ATTEMPT; 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 " + MAX_ATTEMPT);
        if (attempt == MAX_ATTEMPT)
          e.printStackTrace();
      }
    }
    System.out.println("Too many attempts - value is false");
    return false;
  }

  /**
   * 	@param a String prompt
   *	@param a String to represent "true"
   *	@param a String to represent "false"
   *	@return a boolean representing the user input
   */
  public static boolean readBoolean(String prompt, String trueAns, String falseAns) {
    for (int attempt = 1; attempt <= MAX_ATTEMPT; 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 " + MAX_ATTEMPT);
        if (attempt == MAX_ATTEMPT)
          e.printStackTrace();
      }
    }
    System.out.println("Too many attempts - value is false");
    return false;
  }

  /**
   *	@param a String prompt
   *	@param an array of Strings representing choices
   *	@return an integer, the index of the user input
   */
  public static int readChoice(String prompt, String[] options) {
    for (int attempt = 1; attempt <= MAX_ATTEMPT; 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 " + MAX_ATTEMPT);
        if (attempt == MAX_ATTEMPT)
          e.printStackTrace();
      }
    }
    System.out.println("Too many attempts - value is -1");
    return -1;
  }

}




