package iDSS;

import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.util.*;



import iDSS.utils.*;
import iDSS.disp.*;
import iDSS.grids.*;
import iDSS.tidalData.*;
import iDSS.sm.*;
import iDSS.slr.*;
import iDSS.sim.*;
import iDSS.beans.*;
import iDSS.beans2.*;





public class ModelSetupTree extends JFrame implements PropertyChangeListener {


    private DefaultTreeModel treeModel;
    private DisplayFrame rootPanel;
    private JScrollPane panelView, treeView;
    private JSplitPane splitPane;

    //Optionally play with line styles.  Possible values are
    //"Angled", "Horizontal", and "None" (the default).
    private boolean playWithLineStyle = false;
    private String lineStyle = "Angled"; 
    private DefaultMutableTreeNode top;


    private DefaultMutableTreeNode dem;
    private DefaultMutableTreeNode landcover;
    private DefaultMutableTreeNode tidalData;
    private DefaultMutableTreeNode isostaticMovement;
    private DefaultMutableTreeNode vegetationModel;
    private DefaultMutableTreeNode slrScenario;
    private DefaultMutableTreeNode modelStatus;
    private DefaultMutableTreeNode simStatus;


    private CustomVector visibleVector;
    private CustomVector demRemoteVector;
    private CustomVector landcoverRemoteVector;
    //private CustomVector tidalDataRemoteStationsVector;
    private CustomVector tidalDataLocalStationsVector;
    //private CustomVector vmLocalVector;
    private CustomVector vmRemoteVector;
    private CustomVector isostaticVector;
    //private CustomVector slrLocalVector;
    private CustomVector slrRemoteVector;
    private CustomVector tidalModelsListVector;
    private CustomVector statusVector;
    private CustomVector simVector;



    private GridManager demRemoteGM;
    private LCGridManager landcoverRemoteGM;

    //private TidalStationsRemote tidalDataRemoteStations;
    private TidalStationsLocal tidalDataLocalStations;
    private TidalModelsList tidalModelsList;

    private VerticalSlider isostaticMovementSlider;

    private SurvivalModelsList smList;

    private ScenarioList scenarioList;

    private Status status;
    private StatusJBean statusJBean;

    private Simulation simulation;



    private DefaultMutableTreeNode demRemote;
    private DefaultMutableTreeNode landcoverRemote;
    //private DefaultMutableTreeNode tidalDataRemote;
    private DefaultMutableTreeNode tidalDataLocal;
    private DefaultMutableTreeNode vegetationModelRemote;
    //private DefaultMutableTreeNode vegetationModelLocal;
    private DefaultMutableTreeNode isostaticMovementLocal;
    //private DefaultMutableTreeNode slrLocal;
    private DefaultMutableTreeNode slrRemote;
    private DefaultMutableTreeNode tidalModels;
    private DefaultMutableTreeNode statusLocal;
    private DefaultMutableTreeNode simLocal;




    public ModelSetupTree(String title,int width,int height) {

        super(title);

        //Hashtable modelDataHashtable = new Hashtable();
        //visibleVector = new CustomVector("");

        //Create the nodes.
        top = new DefaultMutableTreeNode("Model Setup Tree");
        treeModel = new DefaultTreeModel(top);

        createNodes();

        //Create a tree that allows one selection at a time.
        final JTree tree = new JTree(treeModel);
        tree.getSelectionModel().setSelectionMode
                (TreeSelectionModel.SINGLE_TREE_SELECTION);

        //Listen for when the selection changes.
        tree.addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged(TreeSelectionEvent e) {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode)
                                   tree.getLastSelectedPathComponent();

                if (node == null) return;

                Object nodeInfo = node.getUserObject();

                if (node.isLeaf()) {

                    CustomVector v = (CustomVector)nodeInfo;
                    removeAllFromModelView();
                    addToModelView(v);
                    visibleVector = v;

/**
                    DisplayFrame panel = (DisplayFrame)nodeInfo;
                    removeAllFromModelView();
                    addToModelView(panel);

                    if (IDSSAppConstants.debug) {
                        System.out.print(panel.toString() + ":  \n    ");
                    }

**/

                } else {
                    removeAllFromModelView();
                    addToModelView(rootPanel);
                }

                if (IDSSAppConstants.debug) {
                    System.out.println(nodeInfo.toString());
                }
            }
        });

        if (playWithLineStyle) {
            tree.putClientProperty("JTree.lineStyle", lineStyle);
        }

        //Create the scroll pane and add the tree to it. 
        treeView = new JScrollPane(tree);

        //Create JPanel for the right panel.





        //panelView = new JScrollPane(baseFrame);
        panelView = new JScrollPane();

        //Add the scroll panes to a split pane.
        splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        splitPane.setTopComponent(treeView);
        splitPane.setBottomComponent(panelView);

        Dimension minimumSize = new Dimension(100, 50);
        panelView.setMinimumSize(minimumSize);
        treeView.setMinimumSize(minimumSize);
        splitPane.setDividerLocation(100); //XXX: ignored in some releases
                                           //of Swing. bug 4101306
        //workaround for bug 4101306:
        //treeView.setPreferredSize(new Dimension(100, 100)); 

        //splitPane.setPreferredSize(new Dimension(500, 300));
        splitPane.setPreferredSize(new Dimension(width,height));

        //Add the split pane to this frame.
        getContentPane().add(splitPane, BorderLayout.CENTER);

        initialize();

        setSize(new Dimension(width,height));
        setVisible(true);


    } //public ModelSetupTree(String title,int width,int height)






    public void createNodes() {


        rootPanel = new DisplayFrame("Text : rootPanel",true,true,true,true,null);

        demRemoteVector = new CustomVector(IDSSAppConstants.modelSetupDemRemote);


        demRemoteGM = new GridManager();

        demRemoteVector.add(demRemoteGM);
        demRemote = new DefaultMutableTreeNode(demRemoteVector);

        landcoverRemoteVector = new CustomVector(IDSSAppConstants.modelSetupLandcoverRemote);
        landcoverRemoteGM = new LCGridManager();

        landcoverRemoteVector.add(landcoverRemoteGM);
        landcoverRemote = new DefaultMutableTreeNode(landcoverRemoteVector);


        tidalDataLocalStationsVector = new CustomVector(IDSSAppConstants.modelSetupTidalDataLocal);
        tidalDataLocalStations = new TidalStationsLocal(IDSSAppConstants.modelSetupTidalDataLocal);
        tidalDataLocalStationsVector.add(tidalDataLocalStations);
        tidalDataLocal = new DefaultMutableTreeNode(tidalDataLocalStationsVector);


        tidalModelsListVector = new CustomVector(IDSSAppConstants.tmListTitle);
        tidalModelsList = new TidalModelsList(IDSSAppConstants.tmListTitle);
        tidalModelsListVector.add(tidalModelsList);
        tidalModels = new DefaultMutableTreeNode(tidalModelsListVector);


        vmRemoteVector = new CustomVector(IDSSAppConstants.modelSetupVegetationModelRemote);
        smList = new SurvivalModelsList(IDSSAppConstants.smListTitle);

        vmRemoteVector.add(smList);
        vegetationModelRemote = new DefaultMutableTreeNode(vmRemoteVector);


        isostaticVector = new CustomVector(IDSSAppConstants.modelSetupIsostaticLocal);
        isostaticMovementSlider = new VerticalSlider("Select Isostatic Movement",-50,50,0, "mm/year",null);
        isostaticVector.add(isostaticMovementSlider);
        isostaticMovementLocal = new DefaultMutableTreeNode(isostaticVector);


        slrRemoteVector = new CustomVector(IDSSAppConstants.modelSetupSlrRemote);
        scenarioList = new ScenarioList(IDSSAppConstants.slrBean);
        slrRemoteVector.add(scenarioList);
        slrRemote = new DefaultMutableTreeNode(slrRemoteVector);

        statusVector = new CustomVector(IDSSAppConstants.modelSetupStatus);
        status = new Status();
        statusVector.add(status);
        statusLocal = new DefaultMutableTreeNode(statusVector);

/** Taken to method setStatusBean() further below

        statusJBean = new StatusJBean();
        statusJBean.addPropertyChangeListener(status);
        statusJBean.getStatus();

**/

        dem = new DefaultMutableTreeNode(IDSSAppConstants.modelSetupDigitalElevationModel);
        top.add(dem);

        landcover = new DefaultMutableTreeNode(IDSSAppConstants.modelSetupLandcoverTypes);
        top.add(landcover);

        tidalData = new DefaultMutableTreeNode(IDSSAppConstants.modelSetupTidalData);
        top.add(tidalData);

        isostaticMovement = new DefaultMutableTreeNode(IDSSAppConstants.modelSetupIsostaticMovement);
        top.add(isostaticMovement);

        vegetationModel = new DefaultMutableTreeNode(IDSSAppConstants.modelSetupVegetationModels);
        top.add(vegetationModel);

        slrScenario = new DefaultMutableTreeNode(IDSSAppConstants.modelSetupSlrScenario);
        top.add(slrScenario);


        modelStatus = new DefaultMutableTreeNode(IDSSAppConstants.modelSetupStatus);
        top.add(modelStatus);


        dem.add(demRemote);
        landcover.add(landcoverRemote);
        tidalData.add(tidalDataLocal);
        tidalData.add(tidalModels);
        vegetationModel.add(vegetationModelRemote);
        isostaticMovement.add(isostaticMovementLocal);
        slrScenario.add(slrRemote);
        modelStatus.add(statusLocal);


    } //private void createNodes(DefaultMutableTreeNode top)







    public void createSimNode(Grid dem,LCGrid2 lc,Hashtable tm,int isostatic,ClientDataSet slr) {


        System.out.println("ModelSetupTree.createSimNode(), Checking contents of model parameters");

        if(dem == null)
            System.out.println("dem is null");

        if(lc == null)
            System.out.println("lc is null");

        if(tm == null)
            System.out.println("tm is null");

        System.out.println("isostatic = " + isostatic);

        if(slr == null)
            System.out.println("slr is null");



        JOptionPane.showMessageDialog(null,"ModelSetupTree.createSimNode(), " +
                                        IDSSAppConstants.proceedWithSimulation,
                                        "Information",JOptionPane.INFORMATION_MESSAGE);

        simVector = new CustomVector(IDSSAppConstants.modelSetupSimulation);
        simulation = new Simulation(dem,lc,tm,isostatic,slr);

        Thread simPanelThread = new Thread(simulation);
        simPanelThread.start();


        simVector.add(simulation);

        simLocal = new DefaultMutableTreeNode(simVector);

        simStatus = new DefaultMutableTreeNode(IDSSAppConstants.modelSetupSimulation);
        //simStatus.add(simLocal);
        

        //top.add(simStatus);

        treeModel.insertNodeInto(simStatus,top,top.getChildCount());
        treeModel.reload(top);

        treeModel.insertNodeInto(simLocal,simStatus,simStatus.getChildCount());
        treeModel.reload(simStatus);

        treeModel.reload(simLocal);

        simulation.removePropertyChangeListener(this);
        simulation.addPropertyChangeListener(this);


    } //public void createSimNode(Grid dem,LCGrid2 lc,Hashtable tm,int isostatic,ClientDataSet slr)

















/**

    private void addToPanelView(DisplayFrame panel) {


        baseDesktopPane.removeAll();
        baseDesktopPane.add(panel);
        baseFrame.setContentPane(baseDesktopPane);

        //splitPane.setDividerLocation(splitPane.getDividerLocation()-1);
        //splitPane.setDividerLocation(splitPane.getDividerLocation()+1);


        if(IDSSAppConstants.debug) {
            System.out.println("In display panel with " + panel.toString());
        }


    } //private void addToPanelView(DisplayFrame panel)

**/




    private void addToModelView(CustomVector v) {


        System.out.println("ModelSetupTree.addToModelView(v), " + v.toLongString());

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

            DisplayFrame panel = (DisplayFrame)v.elementAt(i);
            addToModelView(panel);

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

    } //private void addToModelView(Vector v)







    private void addToModelView(DisplayFrame panel) {

        firePropertyChange(IDSSAppConstants.addToModelView,null,panel);

    } //private void addToModelView(DisplayFrame panel)






    private void removeFromModelView(DisplayFrame panel) {

        firePropertyChange(IDSSAppConstants.removeFromModelView,null,panel);

    } //private void removeFromModelView(DisplayFrame panel)






    private void removeAllFromModelView() {

        firePropertyChange(IDSSAppConstants.removeAllFromModelView,new Integer(0),new Integer(1));

    } //private void removeAllFromModelView()









    public void propertyChange(PropertyChangeEvent evt) {

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

            DisplayFrame panel = (DisplayFrame) evt.getNewValue();
            addToModelView(panel);
            visibleVector.add(panel);

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


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

            DisplayFrame panel = (DisplayFrame) evt.getNewValue();
            removeFromModelView(panel);
            visibleVector.remove(panel);

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




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

            Vector v = (Vector)evt.getNewValue();
            firePropertyChange(evt.getPropertyName(),null,v);

/** moved to SetupControllerJBean

            String hashCode = (String)v.elementAt(0);
            Grid g = (Grid)v.elementAt(1);

            if(hashCode.equals(IDSSAppConstants.lcGridName)) {

                if(!g.isRead())
                    g.read();

                Vector landClassesVector = g.getClasses();
                smList.setClassTypes(landClassesVector);

                //status.setLcGridText(g.getGridVector().toString());
                statusJBean.setLcGrid(g.getGridVector().toString());

            } //if(hashCode.equals(IDSSAppConstants.lcGridName))


            else if(hashCode.equals(IDSSAppConstants.demGridName)) {

                //status.setDemText(g.getGridVector().toString());
                statusJBean.setDem(g.getGridVector().toString());

            } //else if(hashCode.equals(IDSSAppConstants.demGridName))


            Vector v2 = new Vector();
            v2.add(hashCode);
            v2.add(g);

            firePropertyChange(evt.getPropertyName(),null,v2);
**/

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


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

            //firePropertyChange(evt.getPropertyName(),evt.getOldValue(),evt.getNewValue());

            Vector tmVector = (Vector)evt.getNewValue();
            tidalModelsList.addTM(tmVector);

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



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

            String s = String.valueOf(((Hashtable)evt.getNewValue()).size());
            //status.setTidalModelsText(s);
            statusJBean.setTidalModels(s);

            firePropertyChange(evt.getPropertyName(),evt.getOldValue(),evt.getNewValue());

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





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

            String s = evt.getNewValue().toString();
            //status.setIsoMovText(s);
            statusJBean.setIsoMov(s);

            firePropertyChange(evt.getPropertyName(),evt.getOldValue(),evt.getNewValue());

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



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

            ClientDataSet ds = (ClientDataSet)evt.getNewValue();
            String s = ds.getStationName();
            //status.setSlrScenText(s);
            statusJBean.setSlrScen(s);

            firePropertyChange(evt.getPropertyName(),evt.getOldValue(),evt.getNewValue());

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


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

            //status.setVegModText(IDSSAppConstants.doneText);
            statusJBean.setVegMod(IDSSAppConstants.doneText);

            firePropertyChange(evt.getPropertyName(),evt.getOldValue(),evt.getNewValue());

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




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

            firePropertyChange(evt.getPropertyName(),evt.getOldValue(),evt.getNewValue());
            JOptionPane.showMessageDialog(null,"ModelSetupTree.propertyChange(), " +
                                            IDSSAppConstants.proceedWithSimulation,
                                            "Information",JOptionPane.INFORMATION_MESSAGE);


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


    } //public void propertyChangeEvent(PropertyChangeEvent evt)





    private void initialize() {

        demRemoteGM.removePropertyChangeListener(this);
        demRemoteGM.addPropertyChangeListener(this);

        landcoverRemoteGM.removePropertyChangeListener(this);
        landcoverRemoteGM.addPropertyChangeListener(this);

        tidalDataLocalStations.removePropertyChangeListener(this);
        tidalDataLocalStations.addPropertyChangeListener(this);

        tidalModelsList.removePropertyChangeListener(this);
        tidalModelsList.addPropertyChangeListener(this);

        isostaticMovementSlider.removePropertyChangeListener(this);
        isostaticMovementSlider.addPropertyChangeListener(this);

        smList.removePropertyChangeListener(this);
        smList.addPropertyChangeListener(this);

        scenarioList.removePropertyChangeListener(this);
        scenarioList.addPropertyChangeListener(this);

        status.removePropertyChangeListener(this);
        status.addPropertyChangeListener(this);


    } //private void initialize()




    public void setStatusBean(StatusJBean statusBean) {

        statusJBean = statusBean;
        statusJBean.addPropertyChangeListener(status);
        statusJBean.getStatus();

    } //public void setStatusBean(StatusJBean statusBean)






    public void setClassTypes(Vector v) {

        if(v != null) {

            smList.setClassTypes(v);

        } //if(v != null)

    } //public void setClassTypes(Vector v)




} //public class ModelSetupTree

