/*
 * ******************************************************************************
 * 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 pathSearchAllButton = new JButton("Search All");

    /**
     * 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);

    /**
     * Preferred starting number of rows in the table.
     */
    public static final int PATH_LIST_ROWS_PREFERRED = 5;

    /**
     * Constructs the path list GUI component.
     * 
     * @param owner
     *            The GUILoader object that ownes this component.
     */
    public PathComponent(final GUILoader owner) {
        pathList.setVisibleRowCount(PATH_LIST_ROWS_PREFERRED);

        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(pathSearchAllButton);

        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) {
                int code = event.getKeyCode();
                if (code == KeyEvent.VK_DELETE || code == KeyEvent.VK_BACK_SPACE)
                    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());
            }
        });

        pathSearchAllButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                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) {
        pathSearchAllButton.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");
    }
}
