package yi.util.io;

import java.util.Vector;
import java.io.*;
import java.util.*;

/**
 * read the arguments of a program from a file
 */
public final class ReadArgu
{
    /**
     * Gets an option indicated by a flag "-Char" from the given array
     * of strings. When an option is just a flag, return "true" when the flag is
     * specified.  Return null if the option indicated by the flag can't be
     * found.
     *
     * @param flag the character indicating the option.
     * @param options the array of strings containing all the options.
     * @return the indicated option or null
     */
    public static String getOption(char flag, String [] options)
    {

      String newString;

      if (options == null)
        return "";
      for (int i = 0; i < options.length; i++) {
        if ((options[i].length() > 0) && (options[i].charAt(0) == '-')) {

          // Check if it is a negative number
          try {
            Double dummy = Double.valueOf(options[i]);
          } catch (NumberFormatException e) {
            if (options[i].charAt(1) == flag) {
              if (options[i].length() > 2) return options[i].substring(2);
              if (i + 1 == options.length || options[i + 1].charAt(0) == '-') {
                return "true";
              }
              return options[i + 1];
            }
          }
        }
      }
      return null;
    }

    public static String getOption(char flag, String [] options, String default_value) {
      String value = getOption(flag, options);
      if (value == null) value = default_value;
      return value;
    }

    public static int getIntegerOption(char flag, String [] options, int default_value) {
      String int_str = getOption(flag, options);
      if (int_str == null) return default_value;
      return Integer.parseInt(int_str);
    }

    /**
     * Read a file and return a string array containing the content of the file
     *
     * @param filename file name
     * @return a String array containing every line of the file
     */
    public static String[] readStrings(String filename) throws java.io.IOException
    {
        return readStrings(new java.io.File(filename));
    }

    public static String[] readStrings(java.io.File file) throws java.io.IOException
    {
        // read the file to a string vector first
        Vector rst=new Vector();

        BufferedReader f= new BufferedReader( new FileReader(file));
        String str;
        while ((str=f.readLine())!=null) {
            if (str.startsWith("#")) continue;
            if (str.length()==0) continue;
            rst.addElement(str);
        }
        f.close();

        // if there are at less 1 string, convert them into a string array
        if (rst.size()==0) return null;
        String ss[]= new String[rst.size()];
        for (int i=0;i<rst.size();i++) {
            ss[i]= (String)rst.elementAt(i);
        }
        return ss;
    }

    /**
     * To determine whether a flag is set or not, which is combined in a flag
     * set.  For example, for a flag set 001101, the flags on position 0, 2, and
     * 3 are set.  The position is counted from right to left beginning from 0.
     *
     * @param flags
     * @param pos
     *
     * @return
     */
    public static boolean getCombinedFlag(int flags, int pos) {
      return ((flags >> pos) & 1) == 1 ? true : false;
    }

    /**
     * Same thing as setCombinedFlag(int flags, int pos).  The only difference
     * is this one takes a string as the flag set
     *
     * @param flags
     * @param pos
     *
     * @return
     */
    public static boolean getCombinedFlag(String flags, int pos) {
      int flags_num = Integer.parseInt(flags);
      return getCombinedFlag(flags_num, pos);
    }

    public static double[][] loadMatlab(String filename) throws java.io.IOException
    {
        String[] lines = readStrings(filename);
        double[][] rst = new double[lines.length][];
        for (int i=0; i<lines.length; i++) {
          StringTokenizer tokenizer = new StringTokenizer(lines[i], " \t");
          int len = tokenizer.countTokens();
          rst[i] = new double[len];
          for (int j=0; j<len; j++) {
            String str = tokenizer.nextToken();
            rst[i][j] = Double.parseDouble(str);
          }
        }
        return rst;
    }

    public static double[][] readMatrix(String filename, boolean ignore_first_line) throws java.io.IOException
    {
        String[] lines = readStrings(filename);

        // how many rows
        int rows = lines.length;
        if (ignore_first_line) rows --;

        double[][] rst = new double[rows][];
        for (int i=0; i<lines.length; i++) {
          if (ignore_first_line && i==0) continue;
          int dest_index = i;
          if (ignore_first_line) dest_index--;
          StringTokenizer tokenizer = new StringTokenizer(lines[i], " \t ");
          int len = tokenizer.countTokens();
          rst[dest_index] = new double[len];
          for (int j=0; j<len; j++) {
            String str = tokenizer.nextToken();
            rst[dest_index][j] = Double.parseDouble(str);
          }
        }
        return rst;
    }

}