package org.mbari.swing;

import java.awt.*;
import java.io.*;
import java.awt.event.*;
import java.util.Arrays;
import java.util.EventObject;
import java.util.TreeSet;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.*;
import javax.swing.tree.*;
import org.mbari.swing.DirectoryTree1;
import org.mbari.swing.tree.*;
import org.mbari.awt.layout.VerticalFlowLayout;
import javax.swing.border.*;

/**
 * Title:        Seep Search Analysis project
 * Description:
 * Copyright:    Copyright (c) 2001
 * Company:      MBARI
 * @author Brian Schlining
 * @version 1.0
 *
 * This class allows a user to select multiple files from multiple directories.
 * The selected files are stoed in a java.swing.DefaultListModel. You can construct
 * this either by supplying a DefaultListModel which will be modified by this class
 * or you can use the default constructor and retrieve a reference to the
 * DefaultListModel that this class will create.
 */

/**
 * <p>This class allows a user to select multiple files from multiple directories.
 * The selected files are stoed in a java.swing.DefaultListModel. You can construct
 * this either by supplying a DefaultListModel which will be modified by this class
 * or you can use the default constructor and retrieve a reference to the
 * DefaultListModel that this class will create.</p><hr><br>
 *
 * <p>MBARI provides this documentation and code &quot;as is&quot;, with no
 * warranty, express or implied, of its quality or consistency. It is provided
 * without support and without obligation on the part of the Monterey Bay
 * Aquarium Research Institute to assist in its use, correction, modification,
 * or enhancement. This information should not be published or distributed to
 * third parties without specific written permission from MBARI.</p><br>
 *
 * Copyright 2002 MBARI.<br>
 * MBARI Proprietary Information. All rights reserved.<br><hr><br>
 *
 * $Log: MultiFileSelectPanel1.java,v $
 * Revision 1.9  2002/01/30 00:23:56  brian
 * Added comments to all classes and methods. Tested the accuracy of AsciiRasterGridReader and AsciiRasterGridWriter. Also checked the the GridUtil was populating the spatial grids correctly and accurately. The data files generated matched up perfectly with the orginal text files. Also implemented an RovAltitudeFilter class to encapsulate different filtering methods.
 *<br><hr><br>
 *
 * @author  : $Author: brian $
 * @version : $Revision: 1.9 $
 */
public class MultiFileSelectPanel1 extends JPanel {
    final JPanel topPanel = new JPanel();
    final VerticalFlowLayout verticalFlowLayout1 = new VerticalFlowLayout();
    final JTree tree = new DirectoryTree1();
    final JScrollPane treePanel = new JScrollPane(tree);
    final JSplitPane splitPanel = new JSplitPane();
    final JPanel addRemovePanel = new JPanel();
    final JList availableFileList = new JList();
    final JPanel addRemoveBtnPanel = new JPanel();
    final JList selectedFileList = new JList();
    final JButton btnAdd = new JButton();
    final JButton btnRemove = new JButton();
    final VerticalFlowLayout verticalFlowLayout2 = new VerticalFlowLayout();
    final JScrollPane jScrollPane1 = new JScrollPane(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    final JScrollPane jScrollPane2 = new JScrollPane(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

    public MultiFileSelectPanel1(DefaultListModel model) {
        this.selectedListModel = model;
        try {
            jbInit();
            initComponents();
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
    }

    public MultiFileSelectPanel1() {
        this(new DefaultListModel());
    }

    void jbInit() throws Exception {
        border1 = BorderFactory.createEtchedBorder(Color.white,new Color(142, 142, 142));
        titledBorder1 = new TitledBorder(border1,"Directories");
        border2 = BorderFactory.createEtchedBorder(Color.white,new Color(178, 178, 178));
        titledBorder2 = new TitledBorder(border2,"Available Files");
        border3 = BorderFactory.createEtchedBorder(Color.white,new Color(142, 142, 142));
        titledBorder3 = new TitledBorder(border3,"Available Files");
        border4 = BorderFactory.createEtchedBorder(Color.white,new Color(142, 142, 142));
        titledBorder4 = new TitledBorder(border4,"Selected Files");
        this.setLayout(verticalFlowLayout1);
        btnAdd.setPreferredSize(new Dimension(70, 27));
        btnAdd.setText("Add >>");
        btnAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                btnAdd_actionPerformed(e);
            }
        });
        btnRemove.setText(" Remove");
        btnRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                btnRemove_actionPerformed(e);
            }
        });
        addRemoveBtnPanel.setLayout(verticalFlowLayout2);
        //availableFileList.setPreferredSize(new Dimension(150, 300));
        //selectedFileList.setPreferredSize(new Dimension(150, 300));
        tree.setDoubleBuffered(true);
        splitPanel.setPreferredSize(new Dimension(580, 365));
        splitPanel.setLastDividerLocation(160);
        topPanel.setPreferredSize(new Dimension(590, 375));
        treePanel.setBorder(titledBorder1);
        treePanel.setPreferredSize(new Dimension(160, 355));
        jScrollPane1.setBorder(titledBorder3);
        jScrollPane1.setPreferredSize(new Dimension(140, 355));
        jScrollPane2.setBorder(titledBorder4);
        jScrollPane2.setPreferredSize(new Dimension(140, 355));
        this.setPreferredSize(new Dimension(640, 385));
        addRemoveBtnPanel.setPreferredSize(new Dimension(105, 69));
        addRemoveBtnPanel.setToolTipText("");
        this.add(topPanel, null);
        topPanel.add(splitPanel, null);
        splitPanel.add(treePanel, JSplitPane.LEFT);
        splitPanel.add(addRemovePanel, JSplitPane.RIGHT);
        addRemovePanel.add(jScrollPane1, null);
        jScrollPane1.getViewport().add(availableFileList, null);
        addRemovePanel.add(addRemoveBtnPanel, null);
        addRemoveBtnPanel.add(btnAdd, null);
        addRemoveBtnPanel.add(btnRemove, null);
        addRemovePanel.add(jScrollPane2, null);
        jScrollPane2.getViewport().add(selectedFileList, null);
        splitPanel.setDividerLocation(160);
    }

    void initComponents() throws Exception {
        selectedFileList.setModel(selectedListModel);
        tree.addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged(TreeSelectionEvent e) {

                TreePath path = e.getNewLeadSelectionPath();
                DirNode selectedNode = (DirNode) path.getLastPathComponent();
                //System.out.println("Node Path:" + path);
                if (path != null) {
                    File selectedDir = selectedNode.getFile();
                    File[] dirContents = selectedDir.listFiles();
                    TreeSet contents = new TreeSet();
                    for (int i = 0; i < dirContents.length; i++) {
                        if (!dirContents[i].isDirectory()) {
                            contents.add(dirContents[i].getName());
                        }
                    }
                    String[] filenames = (String[]) contents.toArray(
                            new String[contents.size()]);
                    DefaultListModel model = new DefaultListModel();
                    for (int i = 0; i < filenames.length; i++) {
                        model.addElement(filenames[i]);
                    }
                    availableFileList.setModel(model);

                    //availableFileList.setListData(filenames);

                    selectedDir = null;
                    dirContents = null;
                    contents = null;
                }
                path = null;
                selectedNode = null;
            }
        });
    }

    public static void main(String[] args) {
        JFrame f = new JFrame("MultiFileSelectPanel1 test");
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e){
                System.exit(0);
            }
        });
        MultiFileSelectPanel1 panel = new MultiFileSelectPanel1();

        f.getContentPane().add(panel);
        //f.setSize(600, 395);
        f.pack();
        f.setVisible(true);
        f.show();
    }

    void btnAdd_actionPerformed(ActionEvent e) {

        // Get the directory selected in the tree
        TreePath path = tree.getSelectionPath();
        DirNode selectedNode = (DirNode) path.getLastPathComponent();

        File currentDir = null;
        if (selectedNode != null) {
            currentDir = selectedNode.getFile();
        }

        // Get a list of the files selected and add them to the selected list
        if (currentDir != null) {
            Object[] selectedValues = availableFileList.getSelectedValues();
            if (selectedValues != null) {

                File file = null;
                for (int i = 0; i < selectedValues.length; i++) {
                    file = new File(currentDir, (String) selectedValues[i]);
                    selectedListModel.addElement(file);
                }
            }
            selectedValues = null;
        }
        path = null;
        selectedNode = null;

    }

    void btnRemove_actionPerformed(ActionEvent e) {
        int[] removeThese = selectedFileList.getSelectedIndices();

        // Must remove the items with hihest indices first. Otherwise the Vector
        // storing the data will resize on the fly and remove the wrong items.
        Arrays.sort(removeThese);
        for (int i = removeThese.length; i > 0; i--) {
            selectedListModel.removeElementAt(removeThese[i - 1]);
        }
    }

    /**
     *
     * @return The list model used by this component
     */
    public DefaultListModel getDefaultListModel() {
        return selectedListModel;
    }

    /**
     *
     * @param model The list model to be sed by this component.
     */
    public void setDefaultListModel(DefaultListModel model) {
        selectedListModel = model;
        selectedFileList.setModel(model);
    }

    // Need to hold on to the model so that we can remove items.
    DefaultListModel selectedListModel;
    Border border1;
    TitledBorder titledBorder1;
    Border border2;
    TitledBorder titledBorder2;
    Border border3;
    TitledBorder titledBorder3;
    Border border4;
    TitledBorder titledBorder4;
}