package iDSS.tidalData;

import java.util.*;
import java.sql.*;
import java.lang.Double;
import java.awt.*;
import java.awt.image.*;
import java.io.*;


import iDSS.*;
import iDSS.utils.*;
import iDSS.disp.*;
import iDSS.tables.*;
import iDSS.xyGraph.*;


public class ClientDataSet implements Serializable {

  private String sqlString;
  private Timestamp startOfData;
  private Timestamp endOfData;
  private Vector columnNames,rowsOfData;
  private String stationName;

  private String dateColumnName = "date";
  private String dataColumnName = "observation";

  private double valueMin,valueMax;






  public ClientDataSet() {

    sqlString = "noSQL";
    startOfData = new Timestamp(System.currentTimeMillis());
    endOfData = new Timestamp(System.currentTimeMillis());
    columnNames = new Vector();
    rowsOfData = new Vector();

    stationName = "noStation";

    getMinMax();

  } //public ClientDataSet()














  public ClientDataSet(String sql,Timestamp start,Timestamp end,
                  Vector columns,Vector rows) {

    sqlString = sql;
    startOfData = start;
    endOfData = end;
    columnNames = columns;
    rowsOfData = rows;

    stationName = "Unknown";

    getMinMax();

  } //public ClientDataSet()





  public ClientDataSet(String sql,String station,Timestamp start,Timestamp end,
                  Vector columns,Vector rows) {

    sqlString = sql;
    startOfData = start;
    endOfData = end;
    columnNames = columns;
    rowsOfData = rows;

    stationName = station;

    getMinMax();

  } //public ClientDataSet()




  private void getMinMax() {

    System.out.println(stationName + ", " + startOfData.toString() + " to " + endOfData.toString());

    valueMin = 99999.9;
    valueMax = -99999.9;

    for(int i=0;i<rowsOfData.size();i++) {

        Vector currentRow = (Vector) rowsOfData.elementAt(i);
        String aString = currentRow.elementAt(1).toString();
        double value = Double.parseDouble(aString);

        if (value < valueMin)
            valueMin = value;

        if (value > valueMax)
            valueMax = value;

    } //for(int i=0;i<rowsOfData.size();i++)


  } //private void getMinMax()




    public Timestamp getTimeMin() {
        return startOfData;
    }





    public Timestamp getTimeMax() {
        return endOfData;
    }




    public double getValueMin() {
        return valueMin;
    }




    public double getValueMax() {
        return valueMax;
    }




  public Vector getColumnNamesVector() {

    return columnNames;
  }



  public Vector getRowsOfDataVector() {

    return rowsOfData;
  }



  public Vector getRowsOfDataVector(Timestamp startDate,Timestamp endDate) {

    Vector vector = new Vector();

    for(int i=0;i<rowsOfData.size();i++) {

        Vector currentRow = (Vector) rowsOfData.elementAt(i);

        Timestamp currentDate = (Timestamp) currentRow.elementAt(0);
        if ((currentDate.after(startDate)) && (currentDate.before(endDate))) {

            Double value = (Double) currentRow.elementAt(1);
            Vector oneRow = new Vector();
            oneRow.add(currentDate);
            oneRow.add(value);

            vector.add(oneRow);

        } //if ((currentDate.after(startDate)) && (currentDate.before(endDate)))

    } //for(int i=0;i<rowsOfData.size();i++)

    return vector;

  } //public Vector getRowsOfDataVector(Timestamp startDate,Timestamp endDate)







  public Vector getColumnsOfDataVector(Timestamp startDate,Timestamp endDate) {

    Vector dateVector = new Vector();
    Vector valueVector = new Vector();

    for(int i=0;i<rowsOfData.size();i++) {

        Vector currentRow = (Vector) rowsOfData.elementAt(i);

        Timestamp currentDate = (Timestamp) currentRow.elementAt(0);
        if ((currentDate.after(startDate)) && (currentDate.before(endDate))) {

            Double value = (Double) currentRow.elementAt(1);

            dateVector.add(currentDate);
            valueVector.add(value);

        } //if ((currentDate.after(startDate)) && (currentDate.before(endDate)))

    } //for(int i=0;i<rowsOfData.size();i++)


    Vector columnsOfDataVector = new Vector();
    columnsOfDataVector.add(dateVector);
    columnsOfDataVector.add(valueVector);

    return columnsOfDataVector;

  } //public Vector getColumnsOfDataVector(Timestamp startDate,Timestamp endDate)








  public Vector getColumnsOfDataVector() {

    Vector dateVector = new Vector();
    Vector valueVector = new Vector();

    for(int i=0;i<rowsOfData.size();i++) {

        Vector currentRow = (Vector) rowsOfData.elementAt(i);

        Timestamp currentDate = (Timestamp) currentRow.elementAt(0);
        Double value = (Double) currentRow.elementAt(1);

        dateVector.add(currentDate);
        valueVector.add(value);

    } //for(int i=0;i<rowsOfData.size();i++)

    Vector columnsOfDataVector = new Vector();
    columnsOfDataVector.add(dateVector);
    columnsOfDataVector.add(valueVector);

    return columnsOfDataVector;

  } //public Vector getColumnsOfDataVector()















  public String getSqlString() {

    return sqlString;
  }



  public String getStationName() {

    return stationName;
  }





  public void setStationName(String name) {

    stationName = name;
  }










  public Timestamp getStartOfData() {

    return startOfData;

  } //public Timestamp getStartOfData()






  public Timestamp getEndOfData() {

    return endOfData;

  } //public Timestamp getEndOfData()




    public double getDataAt(Timestamp t) {

        boolean found = false;
        int rowNum = 0;
        double value = -9999;

        long tSeconds = t.getTime()/1000;

        while(!found) {

            Vector v = (Vector)rowsOfData.elementAt(rowNum);
            Timestamp time = (Timestamp) v.elementAt(0);
            long timeSeconds = time.getTime()/1000;

            //if(t.equals(time)) {
            if(tSeconds == timeSeconds) {
                found = true;
                Double d = (Double) v.elementAt(1);
                value = d.doubleValue();
            }
            else if(rowNum < (rowsOfData.size()-1))
                rowNum++;
            else
                break;

        } //while(!found)

        return value;

    } //public double getDataAt(Timestamp t)




  public Vector getDataSetVector() {

    Vector dataSetVector = new Vector();

    dataSetVector.add(sqlString);
    dataSetVector.add(stationName);
    dataSetVector.add(startOfData);
    dataSetVector.add(endOfData);

    return dataSetVector;

  } //public Vector getDataSetVector()







  public TabularDisplay makeTable(Timestamp startDate, Timestamp endDate) {


    int xColumn = 0;
    int yColumn = 0;

    for(int i=0;i<columnNames.size();i++) {

      String aString = (String) columnNames.elementAt(i);

      if (aString.equals(dateColumnName)) {
        xColumn = i;
        System.out.println("dateColumn is " + i);
      }

      else if (aString.equals(dataColumnName)) {
        yColumn = i;
        System.out.println("dataColumn is " + i);
      }

    } //for(int i=0;i<columnNames.size();i++)


    Vector dataVector = new Vector();
    Vector anyVector;
    Timestamp ts;

    for(int i=0;i<getRowsOfDataVector().size();i++) {

      anyVector = (Vector) getRowsOfDataVector().elementAt(i);
      ts = (Timestamp) anyVector.elementAt(xColumn);

      if ((ts.after(startDate)) && (ts.before(endDate)))
        dataVector.add(anyVector);
    }

    TabularDisplay aTable = null;

    if(dataVector.size() > 0) {

        GeneralTableModel tm = new GeneralTableModel(dataVector,getColumnNamesVector());
        aTable = new TabularDisplay(getStationName(),tm);

    }

    return aTable;

  } //public TabularDisplay makeTable()





    public Graph drawXYGraph(String key, Timestamp start,Timestamp end,Graph superimposeGraph) {

        Graph aGraph = null;
        GraphicalDisplay2 aGraphDisplay = null;


        if(superimposeGraph == null) {

            aGraphDisplay = new GraphicalDisplay2(key,600,300);

            aGraph = new Graph(aGraphDisplay,this,start,end,Color.black);

            aGraphDisplay.removePropertyChangeListener(aGraph);
            aGraphDisplay.addPropertyChangeListener(aGraph);

        } //if(superimposeGraph == null)

        else {

            superimposeGraph.addToGraph(this,start,end,Color.blue);
            //aGraph = superimposeGraph; //NEVER add this line, causes BIG problem

        } //else

        return aGraph;

    } //public Graph drawXYGraph(Timestamp start,Timestamp end,String selectedGraph)







    public Vector getXYGraphImg(String key, Timestamp start,Timestamp end,Graph superimposeGraph) {

        Graph aGraph = null;
        GraphicalDisplay2 aGraphDisplay = null;


        if(superimposeGraph == null) {

            aGraphDisplay = new GraphicalDisplay2(key,800,400);

            aGraph = new Graph(aGraphDisplay,this,start,end,Color.black);

            //aGraphDisplay.removePropertyChangeListener(aGraph);
            //aGraphDisplay.addPropertyChangeListener(aGraph);

        } //if(superimposeGraph == null)

        else {

            superimposeGraph.addToGraph(this,start,end,Color.blue);

        } //else

        BufferedImage bi = null;
        Vector v = new Vector();

        if(aGraphDisplay != null) {
            bi = aGraphDisplay.getCanvas();
            v = ImageRW.writeImgFile(bi);
            v.add(key);
        } //if(aGraphDisplay != null)

        return v;

    } //public Vector getXYGraphImg(String key, Timestamp start,Timestamp end,Graph superimposeGraph)




}//public class ClientDataSet implements Serializable





