package edu.sc.seis.gee.task.dataSetBrowser;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import edu.sc.seis.fissuresUtil.dataset.DataSetChangeEvent;
import edu.sc.seis.fissuresUtil.dataset.DataSetChangeListener;
import edu.sc.seis.fissuresUtil.dataset.Organizer;
import edu.sc.seis.fissuresUtil.xml.DataSet;
import edu.sc.seis.gee.CommonAccess;


public class DataSetTreeModel implements TreeModel {

    public DataSetTreeModel() {
        this(false);
    }

    public DataSetTreeModel(boolean showParams) {
        this.showParams = showParams;
        commonAccess = CommonAccess.getCommonAccess();

        Organizer organizer = commonAccess.getOrganizer();
        organizer.addDataSetChangeListener(new DataSetChangeListener() {
                public void datasetChanged(DataSetChangeEvent e) {
                    logger.debug("  datasetChanged");
                    if (tmListen != null) {
                        Object[] tmp = new Object[1];
                        tmp[0] = getRoot();
                        TreeModelEvent tme = new TreeModelEvent(DataSetTreeModel.this,
                                                                tmp);
                        tmListen.treeStructureChanged(tme);
                    }
                }

                public void datasetAdded(DataSetChangeEvent e) {

                    String[] names = ((DataSet)getRoot()).getDataSetNames();
                    logger.debug("  datasetAdded names.length="+names.length);
                    for (int i=0;i<names.length;i++) {
                        logger.debug("names["+i+"] = "+names[i]);
                    }
                    if (tmListen != null) {
                        logger.debug("sending notice to tmListen");
                        Object[] tmp = new Object[1];
                        tmp[0] = getRoot();
                        TreeModelEvent tme = new TreeModelEvent(DataSetTreeModel.this,
                                                                tmp);
                        tmListen.treeNodesInserted(tme);
                    }
                }

                public void datasetRemoved(DataSetChangeEvent e) {
                    logger.debug("  datasetRemoved");
                    if (tmListen != null) {
                        Object[] tmp = new Object[1];
                        tmp[0] = getRoot();
                        TreeModelEvent tme = new TreeModelEvent(DataSetTreeModel.this,
                                                                tmp);
                        tmListen.treeNodesRemoved(tme);
                    }
                }
            });
    }

    public Object getRoot() {
        return commonAccess.getDataSetRoot();
    }

    public Object getChild(Object parent,
                           int index) {
        if (parent instanceof DataSet ) {
            DataSet ds = (DataSet)parent;
            String[] childDataSets = ds.getDataSetNames();

            if (index < childDataSets.length) {
                return ds.getDataSet(childDataSets[index]);
            }

            String[] dseismogramNames;

            dseismogramNames = ds.getDataSetSeismogramNames();

            if (index < dseismogramNames.length + childDataSets.length) {
                return new SeismogramTreeNode(ds.getDataSetSeismogram(dseismogramNames[index-childDataSets.length]));
            }

            if ( showParams ) {
                String[] params = ds.getParameterNames();
                if (index < childDataSets.length +
                    params.length +
                    dseismogramNames.length)  {
                    return new ParameterTreeNode(ds,
                                                 params[index-
                                                        childDataSets.length-
                                                        dseismogramNames.length]);
                }
            } // end of if ()

        }

        return "BUG: can't find index "+index;
    }

    public int getChildCount(Object parent) {
        if (parent instanceof DataSet) {
            DataSet ds = (DataSet)parent;
            String[] childDataSets = ds.getDataSetNames();
            String[] dseismogramNames =  ds.getDataSetSeismogramNames();
            if ( showParams ) {
                String[] params = ds.getParameterNames();
                return childDataSets.length + params.length + dseismogramNames.length;
            } else {
                return childDataSets.length + dseismogramNames.length;
            } // end of else

        } // end of if (parent instanceof DataSet)
        return 0;
    }

    public boolean isLeaf(Object node) {
        if (node instanceof DataSet) {
            return false;
        }
        return true;
    }

    public void valueForPathChanged(TreePath path,
                                    Object newValue) {
        // ?????
    }

    public int getIndexOfChild(Object parent,
                               Object child) {
        if (parent instanceof DataSet) {
            DataSet ds = (DataSet)parent;
            String[] childDataSets = ds.getDataSetNames();
            if (child instanceof DataSet) {
                for (int i=0; i<childDataSets.length; i++) {
                    if (child.equals(childDataSets[i])) {
                        return i;
                    } // end of if (childDS == childDataSets[i])
                } // end of for (int i=0; i<childDataSets.length; i++)
            } // end of if (child instanceof Dataset)

            String[] dseismogramNames = ds.getDataSetSeismogramNames();

            String[] params = ds.getParameterNames();
            for (int i=0; i<params.length; i++) {
                if (child.equals(params[i])) {
                    return childDataSets.length+ dseismogramNames.length +i;
                } // end of if (child.equals(seismograms[i]))
            } // end of for (int i=0; i<seismograms.length; i++)

        } // end of if (parent instanceof DataSet)
        return -1;
    }

    public void addTreeModelListener(TreeModelListener l) {
        tmListen = l;
    }

    public void removeTreeModelListener(TreeModelListener l) {

    }


    CommonAccess commonAccess;

    TreeModelListener tmListen = null;

    boolean showParams = false;

    static org.apache.log4j.Logger logger =
        org.apache.log4j.Logger.getLogger(DataSetTreeModel.class);

}
