package ucar.nc2.util;

import ucar.nc2.station.StationObsDataset;

import java.io.*;
import java.util.*;
import java.net.URL;

import edu.wisc.ssec.mcidas.adde.AddePointDataReader;
import edu.wisc.ssec.mcidas.adde.AddeException;
import edu.wisc.ssec.mcidas.McIDASUtil;

/**
 * Utility class to read and parse a fixed length table
 */
public class TableParser {
  static private boolean debugCall = false, debugParse = false;

  static public ArrayList readTable(String urlString, String format, int maxLines) throws IOException, NumberFormatException {

    InputStream ios = null;
    if (urlString.startsWith("http:")) {
      URL url = new URL(urlString);
      ios = url.openStream();
    } else {
      ios = new FileInputStream(urlString);
     }
    
    return readTable( ios, format, maxLines);
  }

  static public ArrayList readTable(InputStream ios, String format, int maxLines) throws IOException, NumberFormatException {
    ArrayList fields = new ArrayList();

    int start = 0;
    StringTokenizer stoker = new StringTokenizer( format, " ,");
    while (stoker.hasMoreTokens()) {
      String tok = stoker.nextToken();
      // see what type
      Class type = String.class;
      char last = tok.charAt(tok.length()-1);
      if (last == 'i') type = int.class;
      if (last == 'd') type = double.class;
      if (type!= String.class) tok = tok.substring(0, tok.length()-1);

      int end = Integer.parseInt( tok);
      fields.add( new Field( start, end, type));
      start = end+1;
    }

    ArrayList records = new ArrayList();

    BufferedReader dataIS = new BufferedReader(new InputStreamReader(ios));
    int count = 0;
    while (true && (count < maxLines)) {
      String line = dataIS.readLine();
      if (line == null) break;
      records.add(new Record( line, fields));
      count++;
    }

    dataIS.close();
    return records;
  }

  static public class Field {
    int start, end;
    Class type;

    public Field (int start, int end, Class type) {
      this.start = start;
      this.end = end;
      this.type = type;
    }

    Object parse( String line) throws NumberFormatException {
      String svalue = line.substring(start, end).trim();

      if (type == String.class)
        return svalue;

      try {
        if (type == double.class)
          return new Double( svalue);
        if (type == int.class)
          return new Integer( svalue);
      } catch (NumberFormatException e) {
        e.printStackTrace();

      }
      return null;
    }

  }

  static public class Record {
    private ArrayList values = new ArrayList();

    Record( String line, List fields) {
      Iterator iter = fields.iterator();
      while (iter.hasNext()) {
        Field f =  (Field) iter.next();
        values.add( f.parse( line));
      }
    }

    public Object get(int k) { return values.get(k); }
  }

  static String testName = "C:/data/station/adde/STNDB.TXT";
  //static String testName = "M:/temp/STNDB.TXT";
  static String testName2 = "http://localhost:8080/test/STNDB.TXT";
  static String testName3 = "C:/dev/netcdf-java-2.2/resources/resources/tables/nexrad.tbl";

  static public void main( String[] args) throws IOException {
    List recs = TableParser.readTable(testName3, "3,15,54,60d,67d,73d", 50000);
    for (int i = 0; i < recs.size(); i++) {
      Record record = (Record) recs.get(i);
      for (int j = 0; j < record.values.size(); j++) {
        Object s = (Object) record.values.get(j);
        System.out.print(" "+s.toString());
      }
      System.out.println();
    }
  }
}
