package futils;

import utils.ReplaceString;
import utils.BooleanException;

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.StringTokenizer;


public class ReaderUtil {
  private static BufferedReader br =
      new BufferedReader(
          new InputStreamReader(
              System.in));

  public static void setReader(BufferedReader _br) {
    br = _br;
  }

  public static BufferedReader getReader() {
    return br;
  }


  public static String getString(
      String prompt) {
    if (prompt != null)
      System.out.print(prompt);
    try {
      return br.readLine();
    } catch (IOException e) {
    }
    return null;
  }

  public static void print(Object o[]) {
    for (int i = 0; i < o.length; i++)
      System.out.println(o[i]);
  }

  public static void print(int o[]) {
    for (int i = 0; i < o.length; i++)
      System.out.println(o[i]);
  }

  public static int sum(int o[]) {
    int s = 0;
    for (int i = 0; i < o.length; i++)
      s = s + o[i];
    return s;
  }

  public static int[] string2Int(String s[]) {
    int ia[] = new int[s.length];
    for (int i = 0; i < s.length; i++)
      ia[i] = Integer.parseInt(s[i]);
    return ia;
  }

  public static String[]
      getTokens(String s) {
    StringTokenizer
        st = new StringTokenizer(
            s, ", \t\n\r\f\\");
    int n = st.countTokens();
    System.out.println("n=" + n);
    String t[] = new String[n];
    for (int i = 0; i < n; i++)
      t[i] = st.nextToken();
    return t;
  }

  public static void main(String args[]) {
    testGetReadFile();
  }

  public static void testGetTokenizer() {
    String s = getString(
        "please enter a string of data:");
    System.out.println("s=" + s);

    String a[] = getTokens(s);
    int ia[] = string2Int(a);
    print(ia);
    System.out.println("sum=" + sum(ia));
  }

  /**
   * isReadableFile() - validates the file is exists and readable
   *
   * @param f The file to be examined.
   * @param File - input file which would be validated
   * @return boolean - file is readable true/false
   */

  public static boolean isReadableFile(File f) {
    try {
      if (!f.exists())
        throw (new FileNotFoundException("No Such File :" + f));
      if (!f.canRead())
        throw (new IOException("File Not Readable: " + f));
      return true;
    } catch (FileNotFoundException e) {
      System.out.println(e.getMessage() + "\n");
      return false;
    } catch (IOException e) {
      System.out.println(e.getMessage() + "\n");
      return false;
    }

  }

  /** "@param prompt
   */
  public static BufferedReader getBufferedReader(String prompt) {
    return getBufferedReader(
        Futil.getReadFile(prompt));
  }

  /** "@param f
   */
  public static BufferedReader
      getBufferedReader(File f) {
    try {
      return new BufferedReader(
          new FileReader(
              f));
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }

  /** 
   * @param br
   */
  public static String readLine(BufferedReader br) {
    try {
      return br.readLine();
    } catch (IOException e) {
      e.printStackTrace();
      return null;
    }
  }

  /** "@param br
   */
  public static void close(
      BufferedReader br) {
    try {
      br.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  /** Prompt the user for a file select and return the File instance.
   *
   * @param prompt String displayed in a dialog
   * @return File selected by a user
   */
  private static File getReadFileAWT(String prompt) {
    FileDialog fd = new FileDialog(
        new Frame(), prompt);
    fd.setVisible(true);
    return new File(fd.getDirectory() + fd.getFile());
  }


  public static void testGetReadFile() {
    System.out.println(
        "file=" + Futil.getReadFile("select a file"));
  }

  private static File getReadFileSwing(String prompt) {
    JFileChooser jfc = new JFileChooser();

    jfc.showOpenDialog(new JFrame());
    return jfc.getSelectedFile();
  }

  public static FileReader getFileReader(String prompt) {
    return getFileReader(Futil.getReadFile(prompt));
  }

  public static FileReader getFileReader(File file) {
    FileReader fr = null;
    try {
      fr = new FileReader(file);
    } catch (IOException e) {
      System.out.println("futil:Could not open file");
    }
    return fr;
  }

  public static void close(FileReader fr) {
    try {
      fr.close();
    } // end try
    catch (IOException exe) {
      System.out.println("could not close FileReader");
    }
  }

  /** @param file
   * @param data
   * @exception IOException
   */
  public static void readDataFile(File file,
                                  double data[]) throws IOException {
    System.out.println("processing:\t" + file);
    FileReader fr = getFileReader(file);
    StreamTokenizer tokens = new StreamTokenizer(fr);
    int next = 0;
    int num = 0;
    while ((next = tokens.nextToken()) !=
        tokens.TT_EOF) {
      switch (next) {
        case StreamTokenizer.TT_WORD:
          break;
        case StreamTokenizer.TT_NUMBER:
          data[num] = (double) tokens.nval;
          System.out.println(num + ": " +
                             data[num]);
          num = num + 1;
          break;
        case StreamTokenizer.TT_EOL:
          break;
      }
    }
    close(fr);
  }

  /** Prompts the user for a file and counts the tokens.
   *
   * @return returns the number of tokens in a file
   */
  public static int countTokens(BufferedReader br) {
    String line = null;
    int k = 0;
    try {
      while ((line =
          br.readLine()) != null) {
        k = k + ReplaceString.addTokens(line);
      }
    } catch (IOException e) {
    }
    return k;
  }

  public static void listFilteredHrefFile(File file) {
    System.out.println("processing:\t" + file);
    try {
      FileReader fr = getFileReader(file);
      StreamTokenizer tokens = new
          StreamTokenizer(fr);
      int next = 0;
      tokens.resetSyntax();
      tokens.wordChars(0, 255);
      tokens.quoteChar('"');
      while ((next = tokens.nextToken()) != tokens.TT_EOF) {
        switch (next) {
          case '"':
            System.out.print('"');
            StringTokenizer st =
                new StringTokenizer(tokens.sval, " ");
            while (st.hasMoreTokens()) {
              System.out.print(st.nextToken());
              if (st.countTokens() > 1) {
                System.out.print("%20");
              }
            }
            System.out.print('"');
            break;
          case StreamTokenizer.TT_WORD:
            System.out.print(tokens.sval + " ");
            break;
          case StreamTokenizer.TT_NUMBER:
            System.out.print(tokens.nval + " ");
            break;
          case StreamTokenizer.TT_EOL:
            System.out.println();
            break;
        }
      }
      System.out.println();
      fr.close();
    } catch (Exception exe) {
      System.out.println("listFilteredHrefFile:er!");
    }
  }

  public static boolean parseBoolean(String s)
      throws BooleanException {
    if (s.equals("true")) return true;
    if (s.equals("false")) return false;
    throw new BooleanException();
  }

  public static boolean getBoolean(
      String prompt) {
    String s = getString(prompt);
    return parseBoolean(s);

  }

  public static int getInt(String prompt) {
    String s = getString(prompt);
    int i = 0;
    try {
      i = Integer.parseInt(s);
    } catch (NumberFormatException e) {
      System.out.println(
          s + " is not a valid int, try again");
      return getInt(prompt);
    }
    return i;

  }
   public static double getDouble(String prompt) {
    String s = getString(prompt);
    double d = 0;
    try {
      d = Double.parseDouble(s);
    } catch (NumberFormatException e) {
      System.out.println(
          s + " is not a valid double, try again");
      return getDouble(prompt);
    }
    return d;

  }
}