/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2005/11/17, 17:58
!  AUTHOR(S): KOGA, Junichiro
!  File : DataSetManipulator.java
!  
!  Contact address :  Phase System Consortium
!                     E-mail: phase_system@nims.go.jp URL https://azuma.nims.go.jp
!
!
!   Since 2002, this program set had been intensively developed as a part of the following 
!  national projects supported by the Ministry of Education, Culture, Sports, Science and
!  Technology (MEXT) of Japan; "Frontier Simulation Software for Industrial Science
!  (FSIS)" from 2002 to 2005, "Revolutionary Simulation Software (RSS21)" from 2006 to
!  2008. "Research and Development of Innovative Simulation Software (RISS)" from 2008
!  to 2013. These projects is lead by the Center for Research on Innovative Simulation 
!  Software (CISS), the Institute of Industrial Science (IIS), the University of Tokyo.
!   Since 2013, this program set has been further developed centering on PHASE System
!  Consortium. 
!   The activity of development of this program set has been supervised by Takahisa Ohno.
!
!=======================================================================
 */

package ciss.phase_viewer.graph.dataset;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.ListSelectionModel;
import javax.swing.border.TitledBorder;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import org.apache.log4j.Logger;

import ciss.phase_viewer.common.ChaseFileChooser;
import ciss.phase_viewer.common.Resources;
import ciss.phase_viewer.graph.GraphPanel;
import ciss.phase_viewer.mainpanel.InternalFrameChase;

/**
 * "データセット"を制御するクラス.
 * 
 * @author
 */
public class DataSetManipulator extends InternalFrameChase {
    private Logger logger = Logger
            .getLogger(DataSetManipulator.class.getName());

    private DataSet[] dset;

    private PlotSelectionPanel plot;
    private DataSetManipulator manipulator;

    private PlotProperties props;

    private int initialDir;

    public DataSetManipulator() {
        super("data sets", true, true, true, true, new Dimension(700, 560));
        this.manipulator = this;
        init();
    }

    /** Creates a new instance of DataSetManipulator */
    public DataSetManipulator(DataSet[] dset) {
        super("data sets", true, true, true, true, new Dimension(700, 560));
        this.dset = dset;
        this.manipulator = this;
        init();
    }

    private DataSetBrowser browserX;
    private DataSetBrowser browserY;

    private void init() {
        Container container = getContentPane();
        container.removeAll();
        props = new PlotProperties();
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.weightx = 1;
        constraints.weighty = 0;

        constraints.gridx = 0;
        constraints.gridy = 0;

        browserX = new DataSetBrowser("domain", dset,
                javax.swing.tree.TreeSelectionModel.SINGLE_TREE_SELECTION);
        browserY = new DataSetBrowser("range", dset);

        JSplitPane splitpane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                browserX, browserY);
        splitpane.setDividerLocation(0.5);
        splitpane.setResizeWeight(0.5);
        panel.add(splitpane, BorderLayout.NORTH);

        plot = new PlotSelectionPanel("plot");
        panel.add(plot, BorderLayout.CENTER);

        constraints.gridx = 0;
        constraints.gridy = 1;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.weighty = 0;
        constraints.weightx = 1;

        JPanel btnpanel = new JPanel();
        btnpanel.setLayout(new GridBagLayout());
        GridBagConstraints gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 0;
        JButton btnplot = new JButton("plot");
        btnpanel.add(btnplot, gc);
        //
        // JButton btnpref = new JButton("preferences");
        // gc.gridx = 1;
        // btnpanel.add(btnpref,gc);
        JButton btnimport = new JButton("import dataset");
        JButton btnexport = new JButton("export dataset");
        gc.gridx = 1;
        btnpanel.add(btnimport);
        gc.gridx = 2;
        btnpanel.add(btnexport);

        JButton btnclose = new JButton("close");
        gc.gridx = 3;
        gc.fill = GridBagConstraints.NONE;
        btnpanel.add(btnclose, gc);

        panel.add(btnpanel, BorderLayout.SOUTH);

        container.add(panel);

        btnplot.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                doPlot();
            }
        });

        btnexport.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (dset != null && dset.length != 0) {
                    DataSetExporter exporter = new DataSetExporter(dset);
                } else {
                    logger.info("no data set to export");
                }
            }
        });

        btnimport.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                doImport();
            }
        });

        btnclose.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                dispose();
            }
        });

    }

    private void doImport() {
        ChaseFileChooser fdlg = new ChaseFileChooser(true);
        fdlg.setDialogType(JFileChooser.CUSTOM_DIALOG);
        fdlg.setDialogTitle("select");
        fdlg.setFileSelectionMode(JFileChooser.FILES_ONLY);
        if (fdlg.showDialog(this, "open") != JFileChooser.APPROVE_OPTION) {
            return;
        }
        String path = fdlg.getSelectedFile().getAbsolutePath();
        DataSetImporter dsi = new DataSetImporter(path);
        DataSet data = dsi.getDataSet();
        if (data == null) {
            logger.error("import failed.");
            return;
        }
        int newDsetLength = 1;
        if (dset != null) {
            newDsetLength = dset.length + 1;
        }
        DataSet[] newDataset = new DataSet[newDsetLength];
        if (dset != null) {
            for (int i = 0; i < dset.length; i++) {
                newDataset[i] = dset[i];
            }
        }
        newDataset[newDsetLength - 1] = data;
        dset = newDataset;
        init();
    }

    /**
     * 「プロット」を作成/選択するパネル.
     * 
     * @author
     */
    class PlotSelectionPanel extends JPanel {
        private Logger logger = Logger.getLogger(PlotSelectionPanel.class
                .getName());
        private JComboBox plotSelector;
        private JTextField tfnewplot;

        private Vector plotProperties = new Vector();

        /** Creates a new instance of PlotSelectionPanel */
        public PlotSelectionPanel(String title) {
            JPanel pplot = new JPanel();
            pplot.setLayout(new GridBagLayout());
            GridBagConstraints gc = new GridBagConstraints();
            gc.fill = GridBagConstraints.HORIZONTAL;
            gc.weightx = 1;
            gc.weighty = 0;

            String axis_type = AxisSelectionPanel.AXIS_TYPE_RANGE;
            pplot.setBorder(new TitledBorder("manipulate plot"));
            pplot.setLayout(new BoxLayout(pplot, BoxLayout.X_AXIS));
            plotSelector = new JComboBox(new String[] { title });
            SubPlotProperties spp = new SubPlotProperties();
            props.addSubPlotProperties(spp);

            tfnewplot = new JTextField(10);
            JButton btnnewplot = new JButton("create plot");
            JButton btnremplot = new JButton("remove plot");
            JButton btneditConfig = new JButton("edit configuration");

            pplot.add(plotSelector, gc);
            pplot.add(tfnewplot, gc);
            pplot.add(btnnewplot, gc);
            pplot.add(btnremplot);
            pplot.add(btneditConfig, gc);

            add(pplot);

            btnnewplot.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    newPlot();
                }
            });

            btnremplot.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    removePlot();
                }
            });

            plotSelector.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    plotSelected();
                }
            });

            btneditConfig.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    PlotPropertiesEditor editor = new PlotPropertiesEditor(
                            plotSelector.getSelectedItem().toString(), props,
                            plotSelector.getSelectedIndex());
                }
            });

            plotSelector.setSelectedIndex(0);
        }

        private void newPlot() {
            String newplotName = tfnewplot.getText();
            for (int i = 0; i < plotSelector.getItemCount(); i++) {
                if (plotSelector.getItemAt(i).toString().equals(newplotName)) {
                    logger.warn("duplicate plot name.");
                }
            }
            if (newplotName == null || newplotName.trim().length() == 0) {
                newplotName = plotSelector.getItemAt(0).toString()
                        + String.valueOf(plotSelector.getItemCount());
            }
            plotSelector.addItem(newplotName);
            plotSelector.setSelectedItem(newplotName);
            SubPlotProperties spp = new SubPlotProperties();
            props.addSubPlotProperties(spp);
        }

        private void removePlot() {
            if (plotSelector.getItemCount() == 1) {
                logger.warn("you need at least one plot.");
                return;
            }
            int remind = plotSelector.getSelectedIndex();
            SubPlotProperties spp = props.getSubPlotPropertiesAt(remind);
            props.removeSubPlotProperty(spp);

            Object ox = axisxCache.get(remind);
            axisxCache.remove(ox);
            Object oy = axisyCache.get(remind);
            axisyCache.remove(oy);

            Object o = plotSelector.getSelectedItem();
            plotSelector.removeItem(o);
        }

        private Vector axisxCache = new Vector();
        private Vector axisyCache = new Vector();

        private void plotSelected() {
            String ID = plotSelector.getSelectedItem().toString();
            AxisSelectionPanel axisx = null;
            AxisSelectionPanel axisy = null;
            for (int i = 0; i < axisxCache.size(); i++) {
                if (((AxisSelectionPanel) axisxCache.get(i)).getID().equals(ID)) {
                    axisx = (AxisSelectionPanel) axisxCache.get(i);
                    axisy = (AxisSelectionPanel) axisyCache.get(i);
                    break;
                }
            }
            if (axisx == null) {
                axisx = new AxisSelectionPanel(
                        AxisSelectionPanel.AXIS_TYPE_DOMAIN, ID);
                axisy = new AxisSelectionPanel(
                        AxisSelectionPanel.AXIS_TYPE_RANGE, ID);
                axisxCache.addElement(axisx);
                axisyCache.addElement(axisy);
            }
            browserX.setAxisPanel(axisx);
            browserY.setAxisPanel(axisy);
            manipulator.revalidate();
        }

        AxisSelectionPanel[] getAxisX() {
            return getArrayFrom(axisxCache);
        }

        AxisSelectionPanel[] getAxisY() {
            return getArrayFrom(axisyCache);
        }

        String getPlotTitle(int i) {
            return plotSelector.getItemAt(i).toString();
        }

        private AxisSelectionPanel[] getArrayFrom(Vector vec) {
            if (vec == null || vec.size() == 0) {
                return null;
            }

            AxisSelectionPanel[] p = new AxisSelectionPanel[vec.size()];
            vec.copyInto(p);
            return p;
        }

    }

    /**
     * データセットからJTreeを作成.
     * 
     * @author
     */
    class DataSetTree extends JPanel {
        private Logger logger = Logger.getLogger(DataSetTree.class.getName());
        private DataSet[] dset;

        private JTree tree;
        private DefaultTreeModel treeModel;

        private int selectionMode = TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION;

        /** Creates a new instance of DataSetTree */
        public DataSetTree(String title, DataSet[] dset) {
            this.dset = dset;
            setBorder(new TitledBorder(title));
            init();
            createGUI();
        }

        public DataSetTree(String title, DataSet[] dset, int selectionMode) {
            this.dset = dset;
            this.selectionMode = selectionMode;
            setBorder(new TitledBorder(title));
            init();
            createGUI();
        }

        private void init() {
            if (dset == null || dset.length == 0) {
                return;
            }
            DataSetBrowserNode rootNode = new DataSetBrowserNode("data set");
            treeModel = new DefaultTreeModel(rootNode);
            for (int i = 0; i < dset.length; i++) {
                DataSetBrowserNode dsetNode = new DataSetBrowserNode(dset[i]);
                rootNode.add(dsetNode);
                DataSetElement[] dsetElement = dset[i].getData();
                if (dsetElement != null && dsetElement.length != 0) {
                    for (int j = 0; j < dsetElement.length; j++) {
                        DataSetBrowserNode dsetENode = new DataSetBrowserNode(
                                dsetElement[j]);
                        dsetNode.add(dsetENode);
                    }
                }
            }
            tree = new JTree(treeModel);
            tree.setCellRenderer(new DataSetBrowserRenderer());
            tree.getSelectionModel().setSelectionMode(selectionMode);
        }

        private void createGUI() {
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            JScrollPane scr = new JScrollPane();
            scr.setPreferredSize(new Dimension(400, 150));
            scr.setSize(scr.getPreferredSize());
            scr.getViewport().setView(tree);
            add(scr);
        }

        public JTree getTree() {
            return tree;
        }

        /**
         * 選択されているDataSetElementの配列を取得.
         * 
         * @return 現在選択中の「データセットエレメント」
         */
        public DataSetElement[] getSelectedDataSetElement() {
            DataSetElement[] ret = null;
            TreePath[] path = tree.getSelectionPaths();
            if (path == null || path.length == 0) {
                logger.warn("no selection.");
                return null;
            }
            Vector dsetVector = new Vector();
            for (int i = 0; i < path.length; i++) {
                DataSetBrowserNode node = (DataSetBrowserNode) path[i]
                        .getLastPathComponent();
                if (!node.isLeaf()) {
                    continue;
                }
                DataSetElement dse = node.getDataSetElement();
                if (dse == null) {
                    continue;
                }
                dsetVector.addElement(dse);
            }
            if (dsetVector.size() == 0) {
                logger.warn("no data selected.");
                return null;
            }
            ret = new DataSetElement[dsetVector.size()];
            dsetVector.copyInto(ret);
            return ret;
        }

        class DataSetBrowserNode extends DefaultMutableTreeNode {
            DataSetBrowserNode() {
                super();
            }

            DataSetBrowserNode(Object obj) {
                super(obj);
            }

            DataSetBrowserNode(Object obj, boolean allowChild) {
                super(obj, allowChild);
            }

            DataSetElement getDataSetElement() {
                if (userObject instanceof DataSetElement) {
                    return (DataSetElement) userObject;
                }
                return null;
            }

        }

        class DataSetBrowserRenderer extends DefaultTreeCellRenderer {
            public Component getTreeCellRendererComponent(JTree tree,
                    Object value, boolean isSelected, boolean expanded,
                    boolean leaf, int row, boolean hasFocus) {
                return super.getTreeCellRendererComponent(tree, value,
                        isSelected, expanded, leaf, row, hasFocus);
            }
        }

    }

    /**
     * DataSetTree, PlotSelectionPanel, AxisSelectionPanelといったクラスをひとまとめに.
     * 
     * @author
     */
    class DataSetBrowser extends JPanel {
        private Logger logger = Logger
                .getLogger(DataSetBrowser.class.getName());
        private int treeSelectionMode = TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION;

        private String title;
        private DataSet[] dset;

        private DataSetTree tree;
        private AxisSelectionPanel axis;
        private DataSetBrowser browser;

        /** Creates a new instance of DataSetBrowser */
        public DataSetBrowser(String title, DataSet[] dset) {
            this.title = title;
            this.dset = dset;
            init();
        }

        public DataSetBrowser(String title, DataSet[] dset, int selectionMode) {
            this.title = title;
            this.dset = dset;
            this.treeSelectionMode = selectionMode;
            init();
        }

        public DataSetElement[][] getDataSetElements() {
            return axis.getDataSetElements();
        }

        public String[] getNames() {
            return axis.getNames();
        }

        private String axis_type;

        private void init() {
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            tree = new DataSetTree(title, dset, treeSelectionMode);
            JButton btndown = new JButton(Resources.getIcon(Resources.DOWN20));
            JButton btndele = new JButton(Resources.getIcon(Resources.DELETE20));
            JPanel panel = new JPanel();
            panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
            panel.add(btndown);
            panel.add(btndele);

            add(tree);
            add(panel);

            btndown.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    DataSetElement[] data = tree.getSelectedDataSetElement();
                    if (data == null || data.length == 0) {
                        return;
                    }
                    for (int i = 0; i < data.length; i++) {
                        axis.addData(data[i]);
                    }
                }
            });

            btndele.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    axis.removeSelectedData();
                }
            });

        }

        AxisSelectionPanel getAxisPanel() {
            return axis;
        }

        void setAxisPanel(AxisSelectionPanel ax) {
            int n = getComponentCount();
            for (int i = n - 1; i >= 0; i--) {
                Component comp = getComponent(i);
                if (comp instanceof AxisSelectionPanel) {
                    remove(comp);
                }
            }
            this.axis = ax;
            add(ax);
            revalidate();
        }

    }

    /**
     * 軸を作成したり選択したりする.
     */
    class AxisSelectionPanel extends JPanel {
        private Logger logger = Logger.getLogger(AxisSelectionPanel.class
                .getName());
        public static final String AXIS_TYPE_DOMAIN = "domain";
        public static final String AXIS_TYPE_RANGE = "range";

        private String axisType;

        private JComboBox selector;
        private int selectionType = ListSelectionModel.SINGLE_SELECTION;
        private JList listofaxis;
        private DefaultListModel listModel;
        private JTextField newaxisTextField;

        private JPanel plistOfData = new JPanel();
        private Vector listOfData = new Vector();

        private String ID = "";

        private JButton button;
        private JButton buttonrem;

        /**
         * Creates a new instance of AxisSelectionPanel
         * 
         * @param axisType
         *            the type of the axis to be created/selected(specify either
         *            AXIS_TYPE_DOMAIN or AXIS_TYPE_RANGE)
         */
        public AxisSelectionPanel(String axisType, String ID) {
            this.axisType = axisType;
            this.ID = ID;
            if (axisType.equals(AXIS_TYPE_RANGE)) {
                selectionType = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION;
            } else {
                selectionType = ListSelectionModel.SINGLE_SELECTION;
            }
            init();
        }

        void enableAxisManipulation(boolean enable) {
            button.setEnabled(enable);
            buttonrem.setEnabled(enable);
            newaxisTextField.setEnabled(enable);
        }

        String getID() {
            return ID;
        }

        JList getList() {
            return listofaxis;
        }

        int getAxisCount() {
            return selector.getItemCount();
        }

        private void init() {
            // setLayout(new GridBagLayout());
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            GridBagConstraints constraints = new GridBagConstraints();
            constraints.gridx = 0;
            constraints.gridy = 0;
            constraints.fill = GridBagConstraints.HORIZONTAL;
            constraints.weightx = 1;
            constraints.weighty = 0;

            // JPanel pselector = new JPanel();
            // pselector.setBorder(new TitledBorder("select axis"));
            selector = new JComboBox(new String[] { axisType + "-axis" });
            // pselector.add(selector);
            // add(pselector,constraints);

            plistOfData = new JPanel();
            plistOfData.setBorder(new TitledBorder("list of data"));
            plistOfData.setLayout(new BoxLayout(plistOfData, BoxLayout.X_AXIS));
            ListOfData list = new ListOfData(selectionType);
            listOfData.addElement(list);
            listModel = new DefaultListModel();
            constraints.gridy = 1;
            plistOfData.add(list);
            add(plistOfData, constraints);

            constraints.gridy = 2;
            // constraints.fill = GridBagConstraints.NONE;
            JPanel newaxispanel = new JPanel();
            newaxispanel
                    .setLayout(new BoxLayout(newaxispanel, BoxLayout.X_AXIS));
            newaxispanel.setBorder(new TitledBorder("manipulate axis"));
            button = new JButton("create");
            buttonrem = new JButton("remove");
            newaxisTextField = new JTextField(10);
            newaxispanel.add(selector);
            newaxispanel.add(newaxisTextField);
            newaxispanel.add(button);
            newaxispanel.add(buttonrem);
            add(newaxispanel, constraints);

            selector.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    selectList();
                }

            });

            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    createNewAxis();
                }
            });

            buttonrem.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    removeSelectedAxis();
                }
            });

        }

        public DataSetElement[][] getDataSetElements() {
            Vector retVec = new Vector();
            for (int i = 0; i < selector.getItemCount(); i++) {
                DataSetElement[] dse = ((ListOfData) listOfData.get(i))
                        .getData();
                retVec.addElement(dse);
            }
            if (retVec.size() == 0) {
                return null;
            }
            DataSetElement[][] ret = new DataSetElement[retVec.size()][];
            retVec.copyInto(ret);
            return ret;
        }

        public String[] getNames() {
            String[] ret = new String[selector.getItemCount()];
            for (int i = 0; i < ret.length; i++) {
                ret[i] = selector.getItemAt(i).toString();
            }
            return ret;
        }

        public void addData(DataSetElement data) {
            ListOfData list = getSelectedList();
            list.addNewData(data);
        }

        public void removeSelectedData() {
            ListOfData list = getSelectedList();
            list.removeSelectedData();
        }

        public DataSetElement[] getData() {
            ListOfData list = getSelectedList();
            return list.getData();
        }

        private ListOfData getSelectedList() {
            int indx = selector.getSelectedIndex();
            if (indx >= listOfData.size() || indx < 0) {
                logger.error("something is wrong!");
                return null;
            }

            return (ListOfData) listOfData.get(indx);
        }

        private void selectList() {
            int indx = selector.getSelectedIndex();
            if (indx < 0 || indx > listOfData.size()) {
                return;
            }

            if (indx >= listOfData.size() - 1) {
                ListOfData listofdata = new ListOfData(selectionType);
                listOfData.addElement(listofdata);
            }

            ListOfData list = (ListOfData) listOfData.get(indx);
            plistOfData.removeAll();
            plistOfData.setBorder(new TitledBorder("list of data"));
            plistOfData.setLayout(new BoxLayout(plistOfData, BoxLayout.X_AXIS));
            plistOfData.add(list);
        }

        private void createNewAxis() {
            String newAxisName = newaxisTextField.getText();
            for (int i = 0; i < selector.getItemCount(); i++) {
                if (selector.getItemAt(i).toString().equals(newAxisName)) {
                    logger.warn("duplicate axis name.");
                }
            }
            if (newAxisName == null || newAxisName.trim().length() == 0) {
                newAxisName = selector.getItemAt(0).toString()
                        + String.valueOf(selector.getItemCount());
            }
            selector.addItem(newAxisName);
            selector.setSelectedItem(newAxisName);
            manipulator.changeAxisState(this, selector.getItemCount());
        }

        private void removeSelectedAxis() {
            if (selector.getItemCount() == 1) {
                logger.warn("you need at least one axis.");
                return;
            }
            Object sele = selector.getSelectedItem();
            selector.removeItem(sele);
            manipulator.changeAxisState(this, selector.getItemCount());
        }

        class ListOfData extends JScrollPane {
            private Logger logger = Logger
                    .getLogger(ListOfData.class.getName());
            private JList listofdata;
            private DefaultListModel listModel;
            private int selectionType;
            private Vector dataVector = new Vector();

            protected ListOfData(int selectionType) {
                setPreferredSize(new Dimension(400, 150));
                this.selectionType = selectionType;
                init();
            }

            private void init() {
                listModel = new DefaultListModel();
                listofdata = new JList(listModel);
                super.viewport.add(listofdata);
            }

            void addNewData(DataSetElement data) {
                if (selectionType == ListSelectionModel.SINGLE_SELECTION) {
                    logger.debug("SINGLE_SELECTION");
                    listModel.removeAllElements();
                    dataVector.removeAllElements();
                } else {
                    logger.debug("MULTIPLE_SELECTION");
                }
                String listString = "data set: " + data.getParent().getName()
                        + " element: " + data.toString();
                for (int i = 0; i < listModel.size(); i++) {
                    String comp = listModel.get(i).toString();
                    if (comp.equals(listString)) {
                        logger.warn("duplicate data");
                        return;
                    }
                }
                listModel.addElement("data set: " + data.getParent().getName()
                        + " element: " + data);
                dataVector.addElement(data);
                listofdata.revalidate();
            }

            void removeSelectedData() {
                Object[] sele = listofdata.getSelectedValues();
                int[] indeces = listofdata.getSelectedIndices();
                if (sele == null) {
                    return;
                }
                for (int i = sele.length - 1; i >= 0; i--) {
                    listModel.removeElement(sele[i]);
                }
                for (int i = indeces.length - 1; i >= 0; i--) {
                    dataVector.removeElementAt(indeces[i]);
                }
                listofdata.revalidate();
            }

            DataSetElement[] getData() {
                int size = listModel.getSize();
                if (size <= 0) {
                    return null;
                }
                DataSetElement[] ele = new DataSetElement[size];
                for (int i = 0; i < size; i++) {
                    ele[i] = (DataSetElement) dataVector.get(i);
                }

                return ele;
            }
        }

    }

    private void doPlot() {
        Vector plotprops = new Vector();
        AxisSelectionPanel[] axisx = plot.getAxisX();
        AxisSelectionPanel[] axisy = plot.getAxisY();

        if (axisx == null || axisx.length == 0) {
            logger.error("no data.");
            return;
        }

        String dir = null;
        for (int i = 0; i < axisx.length; i++) {
            DataSetElement[][] dxa = axisx[i].getDataSetElements();
            String[] axisxnames = axisx[i].getNames();
            DataSetElement[][] dy = axisy[i].getDataSetElements();
            String[] axisynames = axisy[i].getNames();

            DataSetElement dx = null;
            String axisxname = "";
            try {
                dx = dxa[0][0];
                dir = new File(dx.getParent().getFileName()).getParent();
                axisxname = axisxnames[0];
            } catch (NullPointerException npe) {
                logger.error("invalid data.");
                return;
            }

            props.setTitle(dx.getParent().getName());
            DataSetCollection coll = new DataSetCollection(plot.getPlotTitle(i));
            int count = axisynames.length;
            if (count > axisxnames.length) {
                for (int j = 0; j < count; j++) {
                    coll.setRangeAxisName(j, axisynames[j]);
                    coll.setDomainAxisName(j, axisxname);
                    coll.setDomain(j, dx);
                    for (int k = 0; k < dy[j].length; k++) {
                        coll.addRange(j, dy[j][k]);
                    }
                }
            } else {
                for (int j = 0; j < axisxnames.length; j++) {
                    coll.setRangeAxisName(j, axisynames[0]);
                    coll.setDomainAxisName(j, axisxnames[j]);
                    coll.setDomain(j, dxa[j][0]);
                    for (int k = 0; k < dy[0].length; k++) {
                        coll.addRange(j, dy[0][k]);
                    }
                }
            }
            SubPlotProperties spp = props.getSubPlotPropertiesAt(i);
            spp.setDataSetCollection(coll);
            if (axisy[i].getAxisCount() >= 2) {
                spp.setMultipleAxisType(SubPlotProperties.MULTIPLE_AXIS_Y);
            } else if (axisx[i].getAxisCount() >= 2) {
                spp.setMultipleAxisType(SubPlotProperties.MULTIPLE_AXIS_X);
            }
        }
        GraphPanel gpanel = new GraphPanel(props.getTitle(), props, dir);
    }

    void changeAxisState(AxisSelectionPanel p, int numaxis) {
        boolean enable = false;
        if (numaxis <= 1) {
            enable = true;
        }
        if (p == browserX.getAxisPanel()) {
            browserY.getAxisPanel().enableAxisManipulation(enable);
        } else if (p == browserY.getAxisPanel()) {
            browserX.getAxisPanel().enableAxisManipulation(enable);
        }
    }

}
