package iDSS.beans2;

import java.sql.Timestamp;
import java.util.*;
import java.io.*;
import java.beans.*;




import iDSS.*;
import iDSS.utils.*;
import iDSS.grids.*;
import iDSS.tidalData.*;
import iDSS.sm.*;



public class SimulationJBean implements PropertyChangeListener {



    private Thread simulationThread;


    private Grid demGrid;
    private LCGrid2 lcGrid2;
    private Hashtable tidalModelHashtable;

    private String simulationName;
    private File saveLocationDir;

    private int simulateUntil,timestepMinutes,resultsTimestepYears;
    private int isostaticMovement;
    private ClientDataSet slrDataSet;
    private boolean viewFG,saveFG,viewDD,saveDD;

    private Vector floodStartVector;

    private int currentYear;
    private int currentMonth;
    private int currentDate;

    private PropertyChangeSupport pcs;



    public SimulationJBean () {

        pcs = new PropertyChangeSupport(this);

    } //public SimulationJBean ()




    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 setDem(Grid g) {

        if(g != null)
            demGrid = g;

    } //public void setDem(Grid g)



    public Grid getDem() {

        return demGrid;

    } //public Grid getDem()



    public void setLcGrid2(LCGrid2 lc) {

        if(lc != null)
            lcGrid2 = lc;

    } //public void setLcGrid2(LCGrid2 lc)



    public LCGrid2 getLcGrid2() {

        return lcGrid2;

    } //public LCGrid2 getLcGrid2()




    public void setTidalModelHashtable(Hashtable tm) {

        if(tm != null) {
            tidalModelHashtable = tm;

            Enumeration keysEnum = tidalModelHashtable.keys();

            while(keysEnum.hasMoreElements()) {

                String s = (String) keysEnum.nextElement();
                TidalModel tm2 = (TidalModel) tidalModelHashtable.get(s);
                int wt = tm2.getWeightage();

                System.out.println("In SimulationJBean.run()");
                System.out.println(s + ", " + wt);

            } //while(keysEnum.hasMoreElement())


        } //

    } //public void setTidalModelHashtable(Hashtable tm)





    public Hashtable getTidalModelHashtable() {

        return tidalModelHashtable;

    } //public Hashtable getTidalModelHashtable()



    public Vector getSimUntilYears() {

        Vector years = new Vector();

        if(tidalModelHashtable != null) {

            int startYear = 1999;
            int maxModelYear = 1900;

            Enumeration enum = tidalModelHashtable.elements();
            while(enum.hasMoreElements()) {
                TidalModel aModel = (TidalModel) enum.nextElement();
                Timestamp time = aModel.getBasisStart();
                Calendar aCalendar = Calendar.getInstance();
                aCalendar.setTime(time);
                int year = aCalendar.get(Calendar.YEAR);

                if (year < maxModelYear)
                    maxModelYear = year;

            } //while(enum.hasMoreElements())


            if (startYear < maxModelYear)
                startYear = maxModelYear;


            while(startYear < 2100) {

                startYear++;
                years.add(new Integer(startYear));

            } //while(startYear <= 2100)

        } //if(tidalModelHashtable != null)

        else {

            Vector messageVector = new Vector();
            messageVector.add("Error");
            messageVector.add("No tidalModelHashtable defined in SimulationJBean");
            messageVector.add(new Integer(IDSSAppConstants.errorMessage));

            pcs.firePropertyChange(IDSSAppConstants.showMessage,null,messageVector);

        } //

        return years;

    } //public Vector getSimUntilYears()









    public void setIsostaticMovement(int iso) {

        isostaticMovement = iso;

    } //public void setIsostaticMovement(int iso)



    public int getIsostaticMovement() {

        return isostaticMovement;

    } //public int getIsostaticMovement()



    public void setSlrDataSet(ClientDataSet slr) {

        slrDataSet = slr;

    } //public void setSlrDataSet(ClientDataSet slr)



    public ClientDataSet getSlrDataSet() {

        return slrDataSet;

    } //public ClientDataSet getSlrDataSet()



    public void setViewFG(boolean b) {

        viewFG = b;

    } //public void setViewFG(boolean b)


    public boolean getViewFG() {

        return viewFG;

    } //public boolean getViewFG()



    public void setSaveFG(boolean b) {

        saveFG = b;

    } //public void setSaveFG(boolean b)


    public boolean getSaveFG() {

        return saveFG;

    } //public boolean getSaveFG()






    public void setViewDD(boolean b) {

        viewDD = b;

    } //public void setViewDD(boolean b)


    public boolean getViewDD() {

        return viewDD;

    } //public boolean getViewDD()






    public void setSaveDD(boolean b) {

        saveDD = b;

    } //public void setSaveDD(boolean b)



    public boolean getSaveDD() {

        return saveDD;

    } //public boolean getSaveDD()






    public void setSaveLocationDir(File dir) {

        if(dir != null)
            saveLocationDir = dir;

    } //public void setSaveLocationDir(File dir)



    public File getSaveLocationDir() {

        return saveLocationDir;

    } //public File getSaveLocationDir()






    public void setSimulationName(String s) {

        System.out.println("SimulationJBean.setSimulationName(), simulationName : " + s);

        if(s != null)
            simulationName = s.trim();

    } //public void setSimulationName(String s)



    public String getSimulationName() {

        return simulationName;

    } //public String getSimulationName()




    public void setTimestepMinutes(int t) {

        timestepMinutes = t;

    }//public void setTimestepMinutes(int t)


    public int getTimestepMinutes() {

        return timestepMinutes;

    }//public int getTimestepMinutes()



    public void setResultsTimestepYears(int r) {

        resultsTimestepYears = r;

    } //public void setResultsTimestepYears(int r)



    public int getResultsTimestepYears() {

        return resultsTimestepYears;

    } //public int getResultsTimestepYears()




    public void setFloodStartVector(Vector v) {

        if(v != null)
            floodStartVector = v;

    } //public void setFloodStartVector(Vector v)




    public void setFloodStartVector(String s) {

        floodStartVector = getCoords(s);

        if(floodStartVector.size() == 0) {

            Vector messageVector = new Vector();
            messageVector.add("Missing flood start points");
            messageVector.add("Flood start points not specified");
            messageVector.add(new Integer(IDSSAppConstants.errorMessage));

            pcs.firePropertyChange(IDSSAppConstants.showMessage,null,messageVector);

        } //

    } //public void setFloodStartVector(String s)



    public Vector getFloodStartVector() {

        return floodStartVector;

    } //public Vector getFloodStartVector()






    public void setSimulateUntil(int y) {

        simulateUntil = y;

    }//public void setSimulateUntil(int y)




    public int getSimulateUntil() {

        return simulateUntil;

    }//public int getSimulateUntil()







    public boolean validateInput() {

        System.out.println("SimulationJBean.validateInput(), Validating input for simulation");
        boolean validInput = true;

        if (simulationName.length() < 1) {

            Vector messageVector = new Vector();
            messageVector.add("Missing simulation name");
            messageVector.add("Simulation name is not defined");
            messageVector.add(new Integer(IDSSAppConstants.errorMessage));

            pcs.firePropertyChange(IDSSAppConstants.showMessage,null,messageVector);

            validInput = false;
            return validInput;
        }



        if (timestepMinutes <= 0) {

            Vector messageVector = new Vector();
            messageVector.add("Time step error");
            messageVector.add("Time step must be a positive non-zero integer");
            messageVector.add(new Integer(IDSSAppConstants.errorMessage));

            pcs.firePropertyChange(IDSSAppConstants.showMessage,null,messageVector);

            validInput = false;
            return validInput;

        } //if (timestepMinutes <= 0)

        

        if (resultsTimestepYears <= 0) {

            Vector messageVector = new Vector();
            messageVector.add("Results time step error");
            messageVector.add("Results time step must be a positive non-zero integer");
            messageVector.add(new Integer(IDSSAppConstants.errorMessage));

            pcs.firePropertyChange(IDSSAppConstants.showMessage,null,messageVector);

            validInput = false;
            return validInput;

        } //if (resultsTimestepYears <= 0)



        if (tidalModelHashtable.size() <= 0) {

            Vector messageVector = new Vector();
            messageVector.add("No tidal model error");
            messageVector.add("No tidal model selected");
            messageVector.add(new Integer(IDSSAppConstants.errorMessage));

            pcs.firePropertyChange(IDSSAppConstants.showMessage,null,messageVector);

            validInput = false;
            return validInput;

        } //if (tidalModelHashtable.size() <= 0)



        System.out.println("TidalModelHashtable : " + tidalModelHashtable.size());
        Enumeration modelNames = tidalModelHashtable.keys();

        while(modelNames.hasMoreElements()) {
            String name = (String) modelNames.nextElement();
            TidalModel aTM = (TidalModel) tidalModelHashtable.get(name);
            int weightage = aTM.getWeightage();
            System.out.println(name + ", " + weightage);
        } //while(modelNames.hasMoreElements())



        if (slrDataSet == null) {

            Vector messageVector = new Vector();
            messageVector.add("SLR scenario error");
            messageVector.add("No sea level rise scenario selected");
            messageVector.add(new Integer(IDSSAppConstants.errorMessage));

            pcs.firePropertyChange(IDSSAppConstants.showMessage,null,messageVector);

            validInput = false;
            return validInput;

        } //if (slrDataSet == null)


        if (floodStartVector.size() <= 0) {

            Vector messageVector = new Vector();
            messageVector.add("Flood start point error");
            messageVector.add("No flood start point specified");
            messageVector.add(new Integer(IDSSAppConstants.errorMessage));

            pcs.firePropertyChange(IDSSAppConstants.showMessage,null,messageVector);

            validInput = false;
            return validInput;

        } //if (floodStartVector.size() <= 0)


        System.out.println("SimulationJBean.validateInput()");

        System.out.println("Simulation name      : " + simulationName);
        System.out.println("Simulate until       : " + simulateUntil);
        System.out.println("Simulation time step : " + timestepMinutes);
        System.out.println("Results time step    : " + resultsTimestepYears);
        System.out.println("View Flood Grid      : " + viewFG);
        System.out.println("Save Flood Grid      : " + saveFG);
        System.out.println("View Depth Duration  : " + viewDD);
        System.out.println("Save Depth Duration  : " + saveDD);

        return validInput;

    } //public void validateInput()






    private Vector getCoords(String s) {

        Vector coordsVector = new Vector();

        if(s != null) {

            if(s.length() <= 0)
                return coordsVector;

            StringTokenizer st = new StringTokenizer(s," \t\n\r\f,");

            Vector v = new Vector(); //to temporarily hold coords

            while(st.hasMoreTokens()) {

                String s2 = st.nextToken();
                double d = 0;

                try {
                    d = Double.parseDouble(s2);
                    v.add(new Double(d));
                }//try

                catch (NumberFormatException nfe) {

                    Vector messageVector = new Vector();
                    messageVector.add("Flood start coords error");
                    messageVector.add("Flood coord not a number" + nfe.toString());
                    messageVector.add(new Integer(IDSSAppConstants.errorMessage));

                    pcs.firePropertyChange(IDSSAppConstants.showMessage,null,messageVector);

                } //


            } //while(st.hasMoreTokens())

            int numOfCoords = v.size()/2;

            for(int i=0;i<numOfCoords;i++) {

                Vector oneRow = new Vector();
                oneRow.add(v.elementAt(i*2));
                oneRow.add(v.elementAt(i*2+1));

                coordsVector.add(oneRow);

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

        } //if(s != null)

        return coordsVector;

    } //private Vector getCoords(String s)






    public void setStatus(Timestamp t) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(t);
        currentYear = cal.get(Calendar.YEAR);
        currentMonth = cal.get(Calendar.MONTH);
        currentDate = cal.get(Calendar.DATE);

    } //public void setStatus(Timestamp t)




    public int getCurrentYear() {

        return currentYear;

    } //public int getCurrentYear()


    public int getCurrentMonth() {

        return currentMonth;

    } //public int getCurrentMonth()


    public int getCurrentDate() {

        return currentDate;

    } //public int getCurrentDate()




    public void propertyChange(PropertyChangeEvent evt) {

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

            Timestamp t = (Timestamp)evt.getNewValue();
            setStatus(t);

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

    } //public void propertyChange(PropertyChangeEvent evt)


} //public class simulationJBean

