package iDSS.beans2;



import java.beans.*;
import java.sql.Timestamp;
import java.util.*;
import java.awt.image.*;



import iDSS.math.*;
import iDSS.xyGraph.*;
import iDSS.disp.*;
import iDSS.utils.*;
import iDSS.tidalData.*;


public class DataManagerJBean implements PropertyChangeListener {


    private Hashtable dataSetHashtable,tidalModelsHashtable,xyGraphsHashtable;
    private String currentDataSet;

    private Vector superimposeVector;


    private Vector currentRow;
    private String tidalModelKey;

    private PropertyChangeSupport pcs;






    public DataManagerJBean() {

        dataSetHashtable = new Hashtable();
        xyGraphsHashtable = new Hashtable();
        tidalModelsHashtable = new Hashtable();

        pcs = new PropertyChangeSupport(this);

    } //public DataManagerJBean();






    public void addPropertyChangeListener(PropertyChangeListener l) {

        pcs.addPropertyChangeListener(l);

    } //public void addPropertyChangeListener(PropertyChangeListener l)




    public void removePropertyChangeListener(PropertyChangeListener l) {

        pcs.removePropertyChangeListener(l);

    } //public void removePropertyChangeListener(PropertyChangeListener l)




    public void setCurrentRow(Vector row) {

        currentRow = row;

    } //public void setCurrentRow(Vector row)



    public Vector getCurrentRow() {

        return currentRow;

    } //public Vector getCurrentRow()





    public boolean addToDataSet(ClientDataSet aDataSet) {

        boolean success = false;

        if (!dataSetHashtable.containsKey(aDataSet.getSqlString())) {

            dataSetHashtable.put(aDataSet.getSqlString(),aDataSet);
            success = true;

        } //if (!dataSetHashtable.containsKey(aDataSet.getSqlString()))

        return success;


    } //public boolean addToDataSet(aDataSet)








    public void removeFromDataSet(String key) {

        if(dataSetHashtable.containsKey(key)) {

            dataSetHashtable.remove(key);
            //System.out.println("Hashtable size = " + dataSetHashtable.size());

        }//if(dataSetHashtable.contains(key))

    } //public void removeFromDataSet()




    public Hashtable getDataSets() {

        return dataSetHashtable;

    } //public hashtable getDataSets()





    public Hashtable getXyGraphsHashtable() {

        return xyGraphsHashtable;

    } //public Hashtable getXyGraphsHashtable()





    public Hashtable getTidalModelsHashtable() {

        return tidalModelsHashtable;

    } //public Hashtable getTidalModelsHashtable()






    public void setTidalModel(String tidalModelKey) {

        TidalModel currentModel = (TidalModel)tidalModelsHashtable.get(tidalModelKey);

        if(currentModel != null) {

            Vector v = new Vector();
            v.add(tidalModelKey);
            v.add(currentModel);

            pcs.firePropertyChange(IDSSAppConstants.setTidalModel,null,v);

        } //if(currentModel != null)

    } //public void setTidalModel(String tidalModelKey)







    public Vector makeTidalModel(String key,Timestamp start,Timestamp end,int numberOfFourierIterations) {

        Vector aVector = null;
        ClientDataSet ds = (ClientDataSet) dataSetHashtable.get(key);

        if(ds != null) {

            Calendar c = Calendar.getInstance();
            c.setTime(start);
            String startDateString = c.get(Calendar.YEAR) + "/" +
                                     String.valueOf(c.get(Calendar.MONTH)+1) + "/" +
                                     c.get(Calendar.DATE);

            c.setTime(end);
            String endDateString = c.get(Calendar.YEAR) + "/" +
                                     String.valueOf(c.get(Calendar.MONTH)+1) + "/" +
                                     c.get(Calendar.DATE);

            String tmKey = ds.getStationName() + "," +
                             startDateString + "-" +
                             endDateString + "," +
                             numberOfFourierIterations;


            Vector columnsOfData = ds.getColumnsOfDataVector(start,end);
            Vector datesVector = (Vector) columnsOfData.elementAt(0);

            Fourier fourier = new Fourier(columnsOfData,numberOfFourierIterations);

            Vector columns = new Vector();
            columns.add("Date/Time");
            columns.add("Computed Observation");

            Vector rows = new Vector();

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

                Timestamp date = (Timestamp)datesVector.elementAt(i);
                long longVal = date.getTime();
                double doubleVal = (double) longVal;
                double computedY = fourier.getComputedY(doubleVal);

                Vector currentRow = new Vector();
                currentRow.add(date);
                currentRow.add(new Double(computedY));

                rows.add(currentRow);

            } //for(int i=0;i<datesVector;i++)

            ClientDataSet fourierDataSet = new ClientDataSet(tmKey,
                                                "x:"+ds.getStationName()+":"+numberOfFourierIterations,
                                                start,end,columns,rows);


            //adding fourier dataset to the table
            addToDataSet(fourierDataSet);

            TidalModel aTidalModel = new TidalModel(fourier.getFourierA(),fourier.getFourierB(),fourier.getFourierC(),
                                                    fourier.getFourierIterations(),ds.getStationName(),
                                                    start,end,fourier.getFourierPeriod());

            tidalModelsHashtable.put(tmKey,aTidalModel);
            aVector = fourierDataSet.getDataSetVector();

        } //if(ds != null)

        return aVector;

    } //public Vector makeTidalModel(ClientDataSet ds)





    public TidalModel getTidalModel(String tmKey) {

        TidalModel tm = (TidalModel)tidalModelsHashtable.get(tmKey);
        return tm;

    } //public TidalModel getTidalModel(String tmKey)





    public TabularDisplay getTable(String key,Timestamp start,Timestamp end) {

        ClientDataSet ds = (ClientDataSet)dataSetHashtable.get(key);
        TabularDisplay tabularDisplay = null;

        if(ds != null) {

            tabularDisplay = ds.makeTable(start,end);

        }//if(ds != null)

        return tabularDisplay;

    } //public TabularDisplay getTable(String key,Timestamp start,Timestamp end)






    public Vector getTableRowsVector(String key,Timestamp start,Timestamp end) {

        ClientDataSet cds = (ClientDataSet)dataSetHashtable.get(key);
        Vector rows = new Vector();
        Vector cols = new Vector();

        if(cds != null) {

            rows = cds.getRowsOfDataVector(start,end);
            cols = cds.getColumnNamesVector();

        } //if(cds != null)

        Vector v = new Vector();
        v.add(cols);
        v.add(rows);

        return v;


    } //public Vector getTableRowsVector(String key,Timestamp start,Timestamp end)







    public GraphicalDisplay2 drawXYGraph(String key,String graphKey,Timestamp start,
                                            Timestamp end,String selectedGraph) {

        ClientDataSet ds = (ClientDataSet)dataSetHashtable.get(key);
        //GraphicalDisplay2 gDisp = null;
        Graph graph = null;
        GraphicalDisplay2 gDisp = null;

        Graph superimposeGraph = (Graph)xyGraphsHashtable.get(selectedGraph);


        if(ds != null) {

            graph = ds.drawXYGraph(graphKey,start,end,superimposeGraph);

            if(graph != null) {

                xyGraphsHashtable.put(graphKey,graph);
                gDisp = graph.getDisplay();

            } //if(graph != null)

        }//if(ds != null)

        return gDisp;

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








    public Vector getXYGraphImg(String key,String graphKey,Timestamp start,Timestamp end,String selectedGraph) {

        Vector v = new Vector();


        ClientDataSet ds = (ClientDataSet)dataSetHashtable.get(key);
        Graph graph = null;
        GraphicalDisplay2 gDisp = null;

        Graph superimposeGraph = null;

        if(selectedGraph != null && selectedGraph != IDSSAppConstants.none) {

            Object o = xyGraphsHashtable.get(selectedGraph);

            if(o instanceof Graph) {

                superimposeGraph = (Graph)o;

            } //if(o instanceof Graph)

        } //if(selectedGraph != null && selectedGraph != IDSSAppConstants.none)

        if(ds != null) {

            graph = ds.drawXYGraph(graphKey,start,end,superimposeGraph);

            if(graph != null) {

                xyGraphsHashtable.put(graphKey,graph);
                gDisp = graph.getDisplay();

                BufferedImage bi = gDisp.getCanvas();

                v = ImageRW.writeImgFile(bi);
                v.add(graphKey);

            } //if(graph != null)

            else {

                if(superimposeGraph != null) {

                    gDisp = superimposeGraph.getDisplay();

                    BufferedImage bi = gDisp.getCanvas();

                    v = ImageRW.writeImgFile(bi);
                    v.add(graphKey);

                } //if(superimposeGraph != null)

            } //else

        }//if(ds != null)

        //BufferedImage bi = gDisp.getCanvas();

        //v = ImageRW.writeImgFile(bi);
        //v.add(graphKey);

        return v;


    } //public Vector getXYGraphImg(...)








    public BufferedImage getXYGraphImg2(String key,String graphKey,Timestamp start,Timestamp end,String selectedGraph) {

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


        ClientDataSet ds = (ClientDataSet)dataSetHashtable.get(key);
        Graph graph = null;
        GraphicalDisplay2 gDisp = null;

        Graph superimposeGraph = null;

        if(selectedGraph != null && selectedGraph != IDSSAppConstants.none) {

            Object o = xyGraphsHashtable.get(selectedGraph);

            if(o instanceof Graph) {

                superimposeGraph = (Graph)o;

            } //if(o instanceof Graph)

        } //if(selectedGraph != null && selectedGraph != IDSSAppConstants.none)

        if(ds != null) {

            graph = ds.drawXYGraph(graphKey,start,end,superimposeGraph);

            if(graph != null) {

                xyGraphsHashtable.put(graphKey,graph);
                gDisp = graph.getDisplay();

                bi = gDisp.getCanvas();

                //v = ImageRW.writeImgFile(bi);
                //v.add(graphKey);

            } //if(graph != null)

            else {

                if(superimposeGraph != null) {

                    gDisp = superimposeGraph.getDisplay();

                    bi = gDisp.getCanvas();

                    //v = ImageRW.writeImgFile(bi);
                    //v.add(graphKey);

                } //if(superimposeGraph != null)

            } //else

        }//if(ds != null)

        //BufferedImage bi = gDisp.getCanvas();

        //v = ImageRW.writeImgFile(bi);
        //v.add(graphKey);

        return bi;


    } //public BufferedImage getXYGraphImg2(...)








    public boolean containsSql(String sqlString) {

        boolean contains = dataSetHashtable.containsKey(sqlString);
        return contains;

    } //public boolean containsSql(String sqlString)






    public void propertyChange(PropertyChangeEvent evt) {

        if(evt.getPropertyName().equals(IDSSAppConstants.tidalData)) {

            ClientDataSet cds = (ClientDataSet)evt.getNewValue();

            if(cds != null) {

                addToDataSet(cds);

            } //if(cds != null)

        } //if(evt.getPropertyName().equals(IDSSAppConstants.tidalData))


    } //public void propertyChange(PropertyChangeEvent evt)




} //public class DataManagerJBean implements PropertyChangeListener



