/*
 * ******************************************************************************
 * Copyright (C) 2007, International Business Machines Corporation and others.
 * All Rights Reserved.
 * ******************************************************************************
 */
package com.ibm.icu.dev.tool.tzu;

import java.awt.Component;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextField;

/**
 * The path list GUI component.
 */
public class PathComponent extends JComponent {
    /**
     * The serializable UID.
     */
    public static final long serialVersionUID = 1340;

    /**
     * A menu item for <code>pathPopup</code> to add all drives to the path
     * model.
     */
    private JMenuItem pathAddAllDrivesItem = new JMenuItem(
            "Add All Drives to List");

    /**
     * The browse button where the user can browse for a particular path.
     */
    private JButton pathBrowseButton = new JButton("Browse...");

    /**
     * A menu item that copies the selected filenames to the clipboard.
     */
    private JMenuItem pathCopyItem = new JMenuItem("Copy selected");

    /**
     * The browse dialog that pops up when the browse button is clicked.
     */
    private JFileChooser pathChooser = new JFileChooser();

    /**
     * The field where the user can enter a path.
     */
    private JTextField pathField = new JTextField(30);

    /**
     * The label for path input field.
     */
    private JLabel pathInputLabel = new JLabel(
            "Include/exclude a directory or a file:");

    /**
     * The label for the path list.
     */
    private JLabel pathListLabel = new JLabel(
            "Directories to search and ICU4J jar files to check:");

    /**
     * The panel to hold the input components.
     */
    private JPanel pathInputPanel = new JPanel();

    /**
     * The JList that holds the path model.
     */
    private JList pathList = new JList();

    /**
     * The path model that stores all the paths.
     */
    private PathModel pathModel;

    /**
     * The panel to hold the output components.
     */
    private JPanel pathOptionPanel = new JPanel();

    /**
     * The context menu for extra options.
     */
    private JPopupMenu pathPopup = new JPopupMenu();

    /**
     * A menu item for <code>pathPopup</code> to remove all paths from the
     * path model.
     */
    private JMenuItem pathRemoveAllItem = new JMenuItem("Remove All");

    /**
     * A menu item for <code>pathPopup</code> to remove the selected paths
     * from the path model.
     */
    private JMenuItem pathRemoveSelectedItem = new JMenuItem(
            "Remove Selected Items");

    /**
     * A menu item for <code>pathPopup</code> to begin a search on the
     * selected paths in the path model.
     */
    private JMenuItem pathSearchAllItem = new JMenuItem("Search All");

    /**
     * The search button that starts the search on the selected paths (or all
     * the paths if none are selected).
     */
    private JButton pathSearchButton = new JButton("Search");

    /**
     * The panel to hold the search components.
     */
    private JPanel pathSearchPanel = new JPanel();

    /**
     * A menu item for <code>pathPopup</code> to begin a search on all paths
     * in the path model.
     */
    private JMenuItem pathSearchSelectedItem = new JMenuItem(
            "Search Selected Items");

    /**
     * The combobox where a user specifies whether to include or to exclude an
     * entered path.
     */
    private JComboBox pathSignBox = new JComboBox(new Object[] { "Include",
            "Exclude" });

    /**
     * The checkbox where the user can specify whether or not to search
     * subdirectories. Set to true by default.
     */
    private JCheckBox pathSubdirOption = new JCheckBox("Search Subdirectories",
            true);

    /**
     * Constructs the path list GUI component.
     * 
     * @param owner
     *            The GUILoader object that ownes this component.
     */
    public PathComponent(final GUILoader owner) {
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        add(pathInputPanel);
        add(pathListLabel);
        add(new JScrollPane(pathList));
        add(pathOptionPanel);
        add(pathSearchPanel);

        JPanel pathInputSubPanel = new JPanel();
        pathInputPanel
                .setLayout(new BoxLayout(pathInputPanel, BoxLayout.Y_AXIS));
        pathInputPanel.add(pathInputLabel);
        pathInputPanel.add(pathInputSubPanel);
        pathInputSubPanel.add(pathSignBox);
        pathInputSubPanel.add(pathField);
        pathInputSubPanel.add(pathBrowseButton);

        pathOptionPanel.add(pathSubdirOption);
        pathSearchPanel.add(pathSearchButton);

        pathChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);

        pathPopup.add(pathCopyItem);
        pathPopup.add(new JSeparator());
        pathPopup.add(pathAddAllDrivesItem);
        pathPopup.add(pathRemoveSelectedItem);
        pathPopup.add(pathRemoveAllItem);
        pathPopup.add(new JSeparator());
        pathPopup.add(pathSearchSelectedItem);
        pathPopup.add(pathSearchAllItem);

        pathField.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                addFile(new File(pathField.getText().trim()));
                pathField.selectAll();
            }
        });

        pathList.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent event) {
                checkPopup(event);
            }

            public void mouseEntered(MouseEvent event) {
                checkPopup(event);
            }

            public void mouseExited(MouseEvent event) {
                checkPopup(event);
            }

            public void mousePressed(MouseEvent event) {
                checkPopup(event);
            }

            public void mouseReleased(MouseEvent event) {
                checkPopup(event);
            }

            private void checkPopup(MouseEvent event) {
                if (event.isPopupTrigger())
                    pathPopup.show((Component) event.getSource(), event.getX(),
                            event.getY());
            }
        });

        pathList.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent event) {
                if (event.getKeyCode() == KeyEvent.VK_DELETE)
                    pathModel.remove(pathList.getSelectedIndices());
            }
        });

        pathCopyItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                String selection = "";
                int[] rows = pathList.getSelectedIndices();
                for (int i = 0; i < rows.length; i++) {
                    String includePathString = pathModel.getElementAt(rows[i])
                            .toString();
                    // get rid of a + or - at the begining of includePathString
                    // if one exists
                    if (includePathString.length() > 0
                            && (includePathString.charAt(0) == '+' || includePathString
                                    .charAt(0) == '-'))
                        includePathString = includePathString.substring(1);
                    selection += includePathString + "\n";
                }
                getToolkit().getSystemClipboard().setContents(
                        new StringSelection(selection), null);
            }
        });

        pathRemoveSelectedItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                pathModel.remove(pathList.getSelectedIndices());
            }
        });

        pathRemoveAllItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                pathModel.removeAll();
            }
        });

        pathSearchSelectedItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                owner.search(pathList.getSelectedIndices(), pathSubdirOption
                        .isSelected());
            }
        });

        pathSearchAllItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                owner.searchAll(pathSubdirOption.isSelected());
            }
        });

        pathSearchButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                int[] indices = pathList.getSelectedIndices();
                if (indices.length > 0)
                    owner.search(indices, pathSubdirOption.isSelected());
                else
                    owner.searchAll(pathSubdirOption.isSelected());
            }
        });

        pathAddAllDrivesItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                pathModel.addAllDrives();
            }
        });

        pathBrowseButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                // set the chooser's intial path to be whatever is in the text
                // field
                File path = new File(pathField.getText().trim());
                if (path.exists())
                    pathChooser.setSelectedFile(path);

                // run the chooser dialog
                int returnVal = pathChooser.showOpenDialog(PathComponent.this);

                // on an accept, add the path to the model and set the text
                // field to it
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    path = pathChooser.getSelectedFile();
                    addFile(path);
                    pathField.setText(path.getPath());
                }
            }
        });
    }

    /**
     * Sets the path model.
     * 
     * @param pathModel
     *            The path model.
     */
    public void setPathModel(PathModel pathModel) {
        this.pathModel = pathModel;
        pathList.setModel(pathModel);
    }

    /**
     * Sets whether the search button should be enabled.
     * 
     * @param value
     *            Whether the search button should be enabled.
     */
    public void setSearchEnabled(boolean value) {
        pathSearchButton.setEnabled(value);
    }

    /**
     * Attempts to add a path to the path model.
     * 
     * @param file
     *            The path to add.
     */
    private void addFile(File file) {
        if (!pathModel.add(new IncludePath(file, isIncluded())))
            JOptionPane.showMessageDialog(PathComponent.this, "\""
                    + file.getPath() + "\" is not a valid file or path.",
                    "Cannot add path/file", JOptionPane.ERROR_MESSAGE);
    }

    /**
     * Returns whether the user has specified to include or to exclude the
     * entered path.
     * 
     * @return Whether the user has specified to include or to exclude the
     *         entered path.
     */
    private boolean isIncluded() {
        return ((String) pathSignBox.getSelectedItem()).equals("Include");
    }
}
