/*
 * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package com.sun.java.swing.plaf.gtk;

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.filechooser.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.BasicDirectoryModel;
import javax.swing.table.*;
import javax.accessibility.*;

import sun.swing.SwingUtilities2;

import sun.swing.plaf.synth.*;
import sun.swing.FilePane;
import sun.awt.shell.ShellFolder;

/**
 * GTK FileChooserUI.
 *
 * @author Leif Samuelsson
 * @author Jeff Dinkins
 */
class GTKFileChooserUI extends SynthFileChooserUI {

    // The accessoryPanel is a container to place the JFileChooser accessory component
    private JPanel accessoryPanel = null;

    private String newFolderButtonText = null;
    private String newFolderErrorSeparator = null;
    private String newFolderErrorText = null;
    private String newFolderDialogText = null;
    private String newFolderNoDirectoryErrorTitleText = null;
    private String newFolderNoDirectoryErrorText = null;

    private String deleteFileButtonText = null;
    private String renameFileButtonText = null;

    private String newFolderButtonToolTipText = null;
    private String deleteFileButtonToolTipText = null;
    private String renameFileButtonToolTipText = null;

    private int newFolderButtonMnemonic = 0;
    private int deleteFileButtonMnemonic = 0;
    private int renameFileButtonMnemonic = 0;
    private int foldersLabelMnemonic = 0;
    private int filesLabelMnemonic = 0;

    private String renameFileDialogText = null;
    private String renameFileErrorTitle = null;
    private String renameFileErrorText = null;

    private JComboBox filterComboBox;
    private FilterComboBoxModel filterComboBoxModel;

    // From Motif

    private JPanel rightPanel;
    private JList directoryList;
    private JList fileList;

    private JLabel pathField;
    private JTextField fileNameTextField;

    private static final Dimension hstrut3 = new Dimension(3, 1);
    private static final Dimension vstrut10 = new Dimension(1, 10);

    private static final Insets insets = new Insets(10, 10, 10, 10);

    private static Dimension prefListSize = new Dimension(75, 150);

    private static Dimension PREF_SIZE = new Dimension(435, 360);
    private static Dimension MIN_SIZE = new Dimension(200, 300);

    private static Dimension PREF_ACC_SIZE = new Dimension(10, 10);
    private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1);

    private static Dimension MAX_SIZE = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);

    private static final Insets buttonMargin = new Insets(3, 3, 3, 3);

    private String filesLabelText = null;
    private String foldersLabelText = null;
    private String pathLabelText = null;
    private String filterLabelText = null;

    private int pathLabelMnemonic = 0;
    private int filterLabelMnemonic = 0;

    private JComboBox directoryComboBox;
    private DirectoryComboBoxModel directoryComboBoxModel;
    private Action directoryComboBoxAction = new DirectoryComboBoxAction();
    private JPanel bottomButtonPanel;
    private GTKDirectoryModel model = null;
    private Action newFolderAction;
    private JPanel interior;
    private boolean readOnly;
    private boolean showDirectoryIcons;
    private boolean showFileIcons;
    private GTKFileView fileView = new GTKFileView();
    private PropertyChangeListener gtkFCPropertyChangeListener;
    private Action approveSelectionAction = new GTKApproveSelectionAction();
    private GTKDirectoryListModel directoryListModel;

    public GTKFileChooserUI(JFileChooser filechooser) {
        super(filechooser);
    }

    public String getFileName() {
        JFileChooser fc = getFileChooser();
        String typedInName = fileNameTextField != null ?
            fileNameTextField.getText() : null;

        if (!fc.isMultiSelectionEnabled()) {
            return typedInName;
        }

        int mode = fc.getFileSelectionMode();
        JList list = mode == JFileChooser.DIRECTORIES_ONLY ?
            directoryList : fileList;
        Object[] files = list.getSelectedValues();
        int len = files.length;
        Vector result = new Vector(len + 1);

        // we return all selected file names
        for (int i = 0; i < len; i++) {
            File file = (File)files[i];
            result.add(file.getName());
        }
        // plus the file name typed into the text field, if not already there
        if (typedInName != null && !result.contains(typedInName)) {
            result.add(typedInName);
        }

        StringBuffer buf = new StringBuffer();
        len = result.size();

        // construct the resulting string
        for (int i=0; i<len; i++) {
            if (len > 1) {
                buf.append(" \"");
            }
            buf.append(result.get(i));
            if (len > 1) {
                buf.append("\"");
            }
        }
        return buf.toString();
    }

    public void setFileName(String fileName) {
        if (fileNameTextField != null) {
            fileNameTextField.setText(fileName);
        }
    }

//     public String getDirectoryName() {
//      return pathField.getText();
//     }

    public void setDirectoryName(String dirname) {
        pathField.setText(dirname);
    }

    public void ensureFileIsVisible(JFileChooser fc, File f) {
        // PENDING
    }

    public void rescanCurrentDirectory(JFileChooser fc) {
        getModel().validateFileCache();
    }

    public JPanel getAccessoryPanel() {
        return accessoryPanel;
    }

    // ***********************
    // * FileView operations *
    // ***********************

    public FileView getFileView(JFileChooser fc) {
        return fileView;
    }

    private class GTKFileView extends BasicFileView {
        public GTKFileView() {
            iconCache = null;
        }

        public void clearIconCache() {
        }

        public Icon getCachedIcon(File f) {
            return null;
        }

        public void cacheIcon(File f, Icon i) {
        }

        public Icon getIcon(File f) {
            return (f != null && f.isDirectory()) ? directoryIcon : fileIcon;
        }
    }


    private void updateDefaultButton() {
        JFileChooser filechooser = getFileChooser();
        JRootPane root = SwingUtilities.getRootPane(filechooser);
        if (root == null) {
            return;
        }

        if (filechooser.getControlButtonsAreShown()) {
            if (root.getDefaultButton() == null) {
                root.setDefaultButton(getApproveButton(filechooser));
                getCancelButton(filechooser).setDefaultCapable(false);
            }
        } else {
            if (root.getDefaultButton() == getApproveButton(filechooser)) {
                root.setDefaultButton(null);
            }
        }
    }

    protected void doSelectedFileChanged(PropertyChangeEvent e) {
        super.doSelectedFileChanged(e);
        File f = (File) e.getNewValue();
        if (f != null) {
            setFileName(getFileChooser().getName(f));
        }
    }

    protected void doDirectoryChanged(PropertyChangeEvent e) {
        directoryList.clearSelection();
        ListSelectionModel sm = directoryList.getSelectionModel();
        if (sm instanceof DefaultListSelectionModel) {
            ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0);
            ((DefaultListSelectionModel)sm).setAnchorSelectionIndex(0);
        }
        fileList.clearSelection();
        sm = fileList.getSelectionModel();
        if (sm instanceof DefaultListSelectionModel) {
            ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0);
            ((DefaultListSelectionModel)sm).setAnchorSelectionIndex(0);
        }

        File currentDirectory = getFileChooser().getCurrentDirectory();
        if (currentDirectory != null) {
            try {
                setDirectoryName(ShellFolder.getNormalizedFile((File)e.getNewValue()).getPath());
            } catch (IOException ioe) {
                setDirectoryName(((File)e.getNewValue()).getAbsolutePath());
            }
            if ((getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) && !getFileChooser().isMultiSelectionEnabled()) {
                setFileName(pathField.getText());
            }
            directoryComboBoxModel.addItem(currentDirectory);
            directoryListModel.directoryChanged();
        }
        super.doDirectoryChanged(e);
    }

    protected void doAccessoryChanged(PropertyChangeEvent e) {
        if (getAccessoryPanel() != null) {
            if (e.getOldValue() != null) {
                getAccessoryPanel().remove((JComponent)e.getOldValue());
            }
            JComponent accessory = (JComponent)e.getNewValue();
            if (accessory != null) {
                getAccessoryPanel().add(accessory, BorderLayout.CENTER);
                getAccessoryPanel().setPreferredSize(accessory.getPreferredSize());
                getAccessoryPanel().setMaximumSize(MAX_SIZE);
            } else {
                getAccessoryPanel().setPreferredSize(ZERO_ACC_SIZE);
                getAccessoryPanel().setMaximumSize(ZERO_ACC_SIZE);
            }
        }
    }

    protected void doFileSelectionModeChanged(PropertyChangeEvent e) {
        directoryList.clearSelection();
        rightPanel.setVisible(((Integer)e.getNewValue()).intValue() != JFileChooser.DIRECTORIES_ONLY);

        super.doFileSelectionModeChanged(e);
    }

    protected void doMultiSelectionChanged(PropertyChangeEvent e) {
        if (getFileChooser().isMultiSelectionEnabled()) {
            fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        } else {
            fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            fileList.clearSelection();
        }

        super.doMultiSelectionChanged(e);
    }

    protected void doControlButtonsChanged(PropertyChangeEvent e) {
        super.doControlButtonsChanged(e);

        JFileChooser filechooser = getFileChooser();
        if (filechooser.getControlButtonsAreShown()) {
            filechooser.add(bottomButtonPanel, BorderLayout.SOUTH);
        } else {
            filechooser.remove(bottomButtonPanel);
        }
        updateDefaultButton();
    }

    protected void doAncestorChanged(PropertyChangeEvent e) {
        if (e.getOldValue() == null && e.getNewValue() != null) {
            // Ancestor was added, set initial focus
            fileNameTextField.selectAll();
            fileNameTextField.requestFocus();
            updateDefaultButton();
        }

        super.doAncestorChanged(e);
    }



    // ********************************************
    // ************ Create Listeners **************
    // ********************************************

    public ListSelectionListener createListSelectionListener(JFileChooser fc) {
        return new SelectionListener();
    }

    class DoubleClickListener extends MouseAdapter {
        JList list;
        public  DoubleClickListener(JList list) {
            this.list = list;
        }

        public void mouseClicked(MouseEvent e) {
            if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
                int index = list.locationToIndex(e.getPoint());
                if (index >= 0) {
                    File f = (File) list.getModel().getElementAt(index);
                    try {
                        // Strip trailing ".."
                        f = ShellFolder.getNormalizedFile(f);
                    } catch (IOException ex) {
                        // That's ok, we'll use f as is
                    }
                    if (getFileChooser().isTraversable(f)) {
                        list.clearSelection();
                        if (getFileChooser().getCurrentDirectory().equals(f)){
                            rescanCurrentDirectory(getFileChooser());
                        } else {
                            getFileChooser().setCurrentDirectory(f);
                        }
                    } else {
                        getFileChooser().approveSelection();
                    }
                }
            }
        }

        public void mouseEntered(MouseEvent evt) {
            if (list != null) {
                TransferHandler th1 = getFileChooser().getTransferHandler();
                TransferHandler th2 = list.getTransferHandler();
                if (th1 != th2) {
                    list.setTransferHandler(th1);
                }
                if (getFileChooser().getDragEnabled() != list.getDragEnabled()) {
                    list.setDragEnabled(getFileChooser().getDragEnabled());
                }
            }
        }
    }

    protected MouseListener createDoubleClickListener(JFileChooser fc, JList list) {
        return new DoubleClickListener(list);
    }



    protected class SelectionListener implements ListSelectionListener {
        public void valueChanged(ListSelectionEvent e) {
            if (!e.getValueIsAdjusting()) {
                JFileChooser chooser = getFileChooser();
                JList list = (JList) e.getSource();

                if (chooser.isMultiSelectionEnabled()) {
                    File[] files = null;
                    Object[] objects = list.getSelectedValues();
                    if (objects != null) {
                        if (objects.length == 1
                            && ((File)objects[0]).isDirectory()
                            && chooser.isTraversable(((File)objects[0]))
                            && (chooser.getFileSelectionMode() != chooser.DIRECTORIES_ONLY
                                || !chooser.getFileSystemView().isFileSystem(((File)objects[0])))) {
                            setDirectorySelected(true);
                            setDirectory(((File)objects[0]));
                        } else {
                            ArrayList fList = new ArrayList(objects.length);
                            for (int i = 0; i < objects.length; i++) {
                                File f = (File)objects[i];
                                if ((chooser.isFileSelectionEnabled() && f.isFile())
                                    || (chooser.isDirectorySelectionEnabled() && f.isDirectory())) {
                                    fList.add(f);
                                }
                            }
                            if (fList.size() > 0) {
                                files = (File[])fList.toArray(new File[fList.size()]);
                            }
                            setDirectorySelected(false);
                        }
                    }
                    chooser.setSelectedFiles(files);
                } else {
                    File file = (File)list.getSelectedValue();
                    if (file != null
                        && file.isDirectory()
                        && chooser.isTraversable(file)
                        && (chooser.getFileSelectionMode() == chooser.FILES_ONLY
                            || !chooser.getFileSystemView().isFileSystem(file))) {

                        setDirectorySelected(true);
                        setDirectory(file);
                    } else {
                        setDirectorySelected(false);
                        if (file != null) {
                            chooser.setSelectedFile(file);
                        }
                    }
                }
            }
        }
    }


    //
    // ComponentUI Interface Implementation methods
    //
    public static ComponentUI createUI(JComponent c) {
        return new GTKFileChooserUI((JFileChooser)c);
    }

    public void installUI(JComponent c) {
        accessoryPanel = new JPanel(new BorderLayout(10, 10));
        accessoryPanel.setName("GTKFileChooser.accessoryPanel");

        super.installUI(c);
    }

    public void uninstallUI(JComponent c) {
        c.removePropertyChangeListener(filterComboBoxModel);
        super.uninstallUI(c);

        if (accessoryPanel != null) {
            accessoryPanel.removeAll();
        }
        accessoryPanel = null;
        getFileChooser().removeAll();
    }

    public void installComponents(JFileChooser fc) {
        super.installComponents(fc);

        boolean leftToRight = fc.getComponentOrientation().isLeftToRight();

        fc.setLayout(new BorderLayout());
        fc.setAlignmentX(JComponent.CENTER_ALIGNMENT);

        // Top row of buttons
        JPanel topButtonPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
        topButtonPanel.setBorder(new EmptyBorder(10, 10, 0, 10));
        topButtonPanel.setName("GTKFileChooser.topButtonPanel");

        if (!UIManager.getBoolean("FileChooser.readOnly")) {
            JButton newFolderButton = new JButton(getNewFolderAction());
            newFolderButton.setName("GTKFileChooser.newFolderButton");
            newFolderButton.setMnemonic(newFolderButtonMnemonic);
            newFolderButton.setToolTipText(newFolderButtonToolTipText);
            newFolderButton.setText(newFolderButtonText);
            topButtonPanel.add(newFolderButton);
        }
        JButton deleteFileButton = new JButton(deleteFileButtonText);
        deleteFileButton.setName("GTKFileChooser.deleteFileButton");
        deleteFileButton.setMnemonic(deleteFileButtonMnemonic);
        deleteFileButton.setToolTipText(deleteFileButtonToolTipText);
        deleteFileButton.setEnabled(false);
        topButtonPanel.add(deleteFileButton);

        RenameFileAction rfa = new RenameFileAction();
        JButton renameFileButton = new JButton(rfa);
        if (readOnly) {
            rfa.setEnabled(false);
        }
        renameFileButton.setText(renameFileButtonText);
        renameFileButton.setName("GTKFileChooser.renameFileButton");
        renameFileButton.setMnemonic(renameFileButtonMnemonic);
        renameFileButton.setToolTipText(renameFileButtonToolTipText);
        topButtonPanel.add(renameFileButton);

        fc.add(topButtonPanel, BorderLayout.NORTH);


        JPanel interior = new JPanel();
        interior.setBorder(new EmptyBorder(0, 10, 10, 10));
        interior.setName("GTKFileChooser.interiorPanel");
        align(interior);
        interior.setLayout(new BoxLayout(interior, BoxLayout.PAGE_AXIS));

        fc.add(interior, BorderLayout.CENTER);

        JPanel comboBoxPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,
                                                         0, 0) {
            public void layoutContainer(Container target) {
                super.layoutContainer(target);
                JComboBox comboBox = directoryComboBox;
                if (comboBox.getWidth() > target.getWidth()) {
                    comboBox.setBounds(0, comboBox.getY(), target.getWidth(),
                                       comboBox.getHeight());
                }
            }
        });
        comboBoxPanel.setBorder(new EmptyBorder(0, 0, 4, 0));
        comboBoxPanel.setName("GTKFileChooser.directoryComboBoxPanel");
        // CurrentDir ComboBox
        directoryComboBoxModel = createDirectoryComboBoxModel(fc);
        directoryComboBox = new JComboBox(directoryComboBoxModel);
        directoryComboBox.setName("GTKFileChooser.directoryComboBox");
        directoryComboBox.putClientProperty( "JComboBox.lightweightKeyboardNavigation", "Lightweight" );
        directoryComboBox.addActionListener(directoryComboBoxAction);
        directoryComboBox.setMaximumRowCount(8);
        comboBoxPanel.add(directoryComboBox);
        interior.add(comboBoxPanel);


        // CENTER: left, right, accessory
        JPanel centerPanel = new JPanel(new BorderLayout());
        centerPanel.setName("GTKFileChooser.centerPanel");

        // SPLIT PANEL: left, right
        JSplitPane splitPanel = new JSplitPane();
        splitPanel.setName("GTKFileChooser.splitPanel");
        splitPanel.setDividerLocation((PREF_SIZE.width-8)/2);

        // left panel - Filter & directoryList
        JPanel leftPanel = new JPanel(new GridBagLayout());
        leftPanel.setName("GTKFileChooser.directoryListPanel");

        // Add the Directory List
        // Create a label that looks like button (should be a table header)
        TableCellRenderer headerRenderer = new JTableHeader().getDefaultRenderer();
        JLabel directoryListLabel =
            (JLabel)headerRenderer.getTableCellRendererComponent(null, foldersLabelText,
                                                                     false, false, 0, 0);
        directoryListLabel.setName("GTKFileChooser.directoryListLabel");
        leftPanel.add(directoryListLabel, new GridBagConstraints(
                          0, 0, 1, 1, 1, 0, GridBagConstraints.WEST,
                          GridBagConstraints.HORIZONTAL,
                          new Insets(0, 0, 0, 0), 0, 0));
        leftPanel.add(createDirectoryList(), new GridBagConstraints(
                          0, 1, 1, 1, 1, 1, GridBagConstraints.EAST,
                          GridBagConstraints.BOTH,
                          new Insets(0, 0, 0, 0), 0, 0));
        directoryListLabel.setDisplayedMnemonic(foldersLabelMnemonic);
        directoryListLabel.setLabelFor(directoryList);

        // create files list
        rightPanel = new JPanel(new GridBagLayout());
        rightPanel.setName("GTKFileChooser.fileListPanel");

        headerRenderer = new JTableHeader().getDefaultRenderer();
        JLabel fileListLabel =
            (JLabel)headerRenderer.getTableCellRendererComponent(null, filesLabelText,
                                                                     false, false, 0, 0);
        fileListLabel.setName("GTKFileChooser.fileListLabel");
        rightPanel.add(fileListLabel, new GridBagConstraints(
                          0, 0, 1, 1, 1, 0, GridBagConstraints.WEST,
                          GridBagConstraints.HORIZONTAL,
                          new Insets(0, 0, 0, 0), 0, 0));
        rightPanel.add(createFilesList(), new GridBagConstraints(
                          0, 1, 1, 1, 1, 1, GridBagConstraints.EAST,
                          GridBagConstraints.BOTH,
                          new Insets(0, 0, 0, 0), 0, 0));
        fileListLabel.setDisplayedMnemonic(filesLabelMnemonic);
        fileListLabel.setLabelFor(fileList);

        splitPanel.add(leftPanel,  leftToRight ? JSplitPane.LEFT : JSplitPane.RIGHT);
        splitPanel.add(rightPanel, leftToRight ? JSplitPane.RIGHT : JSplitPane.LEFT);
        centerPanel.add(splitPanel, BorderLayout.CENTER);

        JComponent accessoryPanel = getAccessoryPanel();
        JComponent accessory = fc.getAccessory();
        if (accessoryPanel != null) {
            if (accessory == null) {
                accessoryPanel.setPreferredSize(ZERO_ACC_SIZE);
                accessoryPanel.setMaximumSize(ZERO_ACC_SIZE);
            } else {
                getAccessoryPanel().add(accessory, BorderLayout.CENTER);
                accessoryPanel.setPreferredSize(accessory.getPreferredSize());
                accessoryPanel.setMaximumSize(MAX_SIZE);
            }
            align(accessoryPanel);
            centerPanel.add(accessoryPanel, BorderLayout.AFTER_LINE_ENDS);
        }
        interior.add(centerPanel);
        interior.add(Box.createRigidArea(vstrut10));

        JPanel pathFieldPanel = new JPanel(new FlowLayout(FlowLayout.LEADING,
                                                          0, 0));
        pathFieldPanel.setBorder(new EmptyBorder(0, 0, 4, 0));
        JLabel pathFieldLabel = new JLabel(pathLabelText);
        pathFieldLabel.setName("GTKFileChooser.pathFieldLabel");
        pathFieldLabel.setDisplayedMnemonic(pathLabelMnemonic);
        align(pathFieldLabel);
        pathFieldPanel.add(pathFieldLabel);
        pathFieldPanel.add(Box.createRigidArea(hstrut3));

        File currentDirectory = fc.getCurrentDirectory();
        String curDirName = null;
        if (currentDirectory != null) {
            curDirName = currentDirectory.getPath();
        }
        pathField = new JLabel(curDirName) {
            public Dimension getMaximumSize() {
                Dimension d = super.getMaximumSize();
                d.height = getPreferredSize().height;
                return d;
            }
        };
        pathField.setName("GTKFileChooser.pathField");
        align(pathField);
        pathFieldPanel.add(pathField);
        interior.add(pathFieldPanel);

        // add the fileName field
        fileNameTextField = new JTextField() {
            public Dimension getMaximumSize() {
                Dimension d = super.getMaximumSize();
                d.height = getPreferredSize().height;
                return d;
            }
        };

        pathFieldLabel.setLabelFor(fileNameTextField);

        Set forwardTraversalKeys = fileNameTextField.getFocusTraversalKeys(
            KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
        forwardTraversalKeys = new HashSet(forwardTraversalKeys);
        forwardTraversalKeys.remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
        fileNameTextField.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardTraversalKeys);

        fileNameTextField.setName("GTKFileChooser.fileNameTextField");
        fileNameTextField.getActionMap().put("fileNameCompletionAction", getFileNameCompletionAction());
        fileNameTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "fileNameCompletionAction");
        interior.add(fileNameTextField);

        // Add the filter combo box
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));
        panel.setBorder(new EmptyBorder(0, 0, 4, 0));
        JLabel filterLabel = new JLabel(filterLabelText);
        filterLabel.setName("GTKFileChooser.filterLabel");
        filterLabel.setDisplayedMnemonic(filterLabelMnemonic);
        panel.add(filterLabel);

        filterComboBoxModel = createFilterComboBoxModel();
        fc.addPropertyChangeListener(filterComboBoxModel);
        filterComboBox = new JComboBox(filterComboBoxModel);
        filterComboBox.setRenderer(createFilterComboBoxRenderer());
        filterLabel.setLabelFor(filterComboBox);

        interior.add(Box.createRigidArea(vstrut10));
        interior.add(panel);
        interior.add(filterComboBox);

        // Add buttons
        bottomButtonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
        bottomButtonPanel.setName("GTKFileChooser.bottomButtonPanel");
        align(bottomButtonPanel);

        JButton cancelButton = getCancelButton(fc);
        align(cancelButton);
        cancelButton.setMargin(buttonMargin);
        bottomButtonPanel.add(cancelButton);

        JButton approveButton = getApproveButton(fc);;
        align(approveButton);
        approveButton.setMargin(buttonMargin);
        bottomButtonPanel.add(approveButton);

        if (fc.getControlButtonsAreShown()) {
            fc.add(bottomButtonPanel, BorderLayout.SOUTH);
        }
    }

    protected void installListeners(JFileChooser fc) {
        super.installListeners(fc);

        gtkFCPropertyChangeListener = new GTKFCPropertyChangeListener();
        fc.addPropertyChangeListener(gtkFCPropertyChangeListener);
    }

    private int getMnemonic(String key, Locale l) {
        return SwingUtilities2.getUIDefaultsInt(key, l);
    }

    protected void uninstallListeners(JFileChooser fc) {
        super.uninstallListeners(fc);

        if (gtkFCPropertyChangeListener != null) {
            fc.removePropertyChangeListener(gtkFCPropertyChangeListener);
        }
    }

    private class GTKFCPropertyChangeListener implements PropertyChangeListener {
        public void propertyChange(PropertyChangeEvent e) {
            String prop = e.getPropertyName();
            if (prop.equals("GTKFileChooser.showDirectoryIcons")) {
                showDirectoryIcons = Boolean.TRUE.equals(e.getNewValue());
            } else if (prop.equals("GTKFileChooser.showFileIcons")) {
                showFileIcons      = Boolean.TRUE.equals(e.getNewValue());
            }
        }
    }

    protected void installDefaults(JFileChooser fc) {
        super.installDefaults(fc);
        readOnly = UIManager.getBoolean("FileChooser.readOnly");
        showDirectoryIcons =
            Boolean.TRUE.equals(fc.getClientProperty("GTKFileChooser.showDirectoryIcons"));
        showFileIcons =
            Boolean.TRUE.equals(fc.getClientProperty("GTKFileChooser.showFileIcons"));
    }

    protected void installIcons(JFileChooser fc) {
        directoryIcon    = UIManager.getIcon("FileView.directoryIcon");
        fileIcon         = UIManager.getIcon("FileView.fileIcon");
    }

    protected void installStrings(JFileChooser fc) {
        super.installStrings(fc);

        Locale l = fc.getLocale();

        newFolderDialogText = UIManager.getString("FileChooser.newFolderDialogText", l);
        newFolderErrorText = UIManager.getString("FileChooser.newFolderErrorText",l);
        newFolderErrorSeparator = UIManager.getString("FileChooser.newFolderErrorSeparator",l);
        newFolderButtonText = UIManager.getString("FileChooser.newFolderButtonText", l);
        newFolderNoDirectoryErrorTitleText = UIManager.getString("FileChooser.newFolderNoDirectoryErrorTitleText", l);
        newFolderNoDirectoryErrorText = UIManager.getString("FileChooser.newFolderNoDirectoryErrorText", l);
        deleteFileButtonText = UIManager.getString("FileChooser.deleteFileButtonText", l);
        renameFileButtonText = UIManager.getString("FileChooser.renameFileButtonText", l);

        newFolderButtonMnemonic = getMnemonic("FileChooser.newFolderButtonMnemonic", l);
        deleteFileButtonMnemonic = getMnemonic("FileChooser.deleteFileButtonMnemonic", l);
        renameFileButtonMnemonic = getMnemonic("FileChooser.renameFileButtonMnemonic", l);

        newFolderButtonToolTipText = UIManager.getString("FileChooser.newFolderButtonToolTipText", l);
        deleteFileButtonToolTipText = UIManager.getString("FileChooser.deleteFileButtonToolTipText", l);
        renameFileButtonToolTipText = UIManager.getString("FileChooser.renameFileButtonToolTipText", l);

        renameFileDialogText = UIManager.getString("FileChooser.renameFileDialogText", l);
        renameFileErrorTitle = UIManager.getString("FileChooser.renameFileErrorTitle", l);
        renameFileErrorText = UIManager.getString("FileChooser.renameFileErrorText", l);

        foldersLabelText = UIManager.getString("FileChooser.foldersLabelText",l);
        foldersLabelMnemonic = getMnemonic("FileChooser.foldersLabelMnemonic", l);

        filesLabelText = UIManager.getString("FileChooser.filesLabelText",l);
        filesLabelMnemonic = getMnemonic("FileChooser.filesLabelMnemonic", l);

        pathLabelText = UIManager.getString("FileChooser.pathLabelText",l);
        pathLabelMnemonic = getMnemonic("FileChooser.pathLabelMnemonic", l);

        filterLabelText = UIManager.getString("FileChooser.filterLabelText", l);
        filterLabelMnemonic = UIManager.getInt("FileChooser.filterLabelMnemonic");
    }

    protected void uninstallStrings(JFileChooser fc) {
        super.uninstallStrings(fc);

        newFolderButtonText = null;
        deleteFileButtonText = null;
        renameFileButtonText = null;

        newFolderButtonToolTipText = null;
        deleteFileButtonToolTipText = null;
        renameFileButtonToolTipText = null;

        renameFileDialogText = null;
        renameFileErrorTitle = null;
        renameFileErrorText = null;

        foldersLabelText = null;
        filesLabelText = null;

        pathLabelText = null;

        newFolderDialogText = null;
        newFolderErrorText = null;
        newFolderErrorSeparator = null;
    }

    protected JScrollPane createFilesList() {
        fileList = new JList();
        fileList.setName("GTKFileChooser.fileList");
        fileList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesLabelText);

        if (getFileChooser().isMultiSelectionEnabled()) {
            fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        } else {
            fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        }

        fileList.setModel(new GTKFileListModel());
        fileList.getSelectionModel().removeSelectionInterval(0, 0);
        fileList.setCellRenderer(new FileCellRenderer());
        fileList.addListSelectionListener(createListSelectionListener(getFileChooser()));
        fileList.addMouseListener(createDoubleClickListener(getFileChooser(), fileList));
        align(fileList);
        JScrollPane scrollpane = new JScrollPane(fileList);
    scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scrollpane.setName("GTKFileChooser.fileListScrollPane");
        scrollpane.setPreferredSize(prefListSize);
        scrollpane.setMaximumSize(MAX_SIZE);
        align(scrollpane);
        return scrollpane;
    }

    protected JScrollPane createDirectoryList() {
        directoryList = new JList();
        directoryList.setName("GTKFileChooser.directoryList");
        directoryList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, foldersLabelText);
        align(directoryList);

        directoryList.setCellRenderer(new DirectoryCellRenderer());
        directoryListModel = new GTKDirectoryListModel();
        directoryList.getSelectionModel().removeSelectionInterval(0, 0);
        directoryList.setModel(directoryListModel);
        directoryList.addMouseListener(createDoubleClickListener(getFileChooser(), directoryList));
        directoryList.addListSelectionListener(createListSelectionListener(getFileChooser()));

        JScrollPane scrollpane = new JScrollPane(directoryList);
    scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scrollpane.setName("GTKFileChooser.directoryListScrollPane");
        scrollpane.setMaximumSize(MAX_SIZE);
        scrollpane.setPreferredSize(prefListSize);
        align(scrollpane);
        return scrollpane;
    }

    protected void createModel() {
        model = new GTKDirectoryModel();
    }

    public BasicDirectoryModel getModel() {
        return model;
    }

    public Action getApproveSelectionAction() {
        return approveSelectionAction;
    }

    private class GTKDirectoryModel extends BasicDirectoryModel {
        FileSystemView fsv;
        private Comparator fileComparator = new Comparator() {
            public int compare(Object o, Object o1) {
                return fsv.getSystemDisplayName((File) o).compareTo
                      (fsv.getSystemDisplayName((File) o1));
            }
        };

        public GTKDirectoryModel() {
            super(getFileChooser());
        }

        protected void sort(Vector<? extends File> v) {
            fsv = getFileChooser().getFileSystemView();
            Collections.sort(v, fileComparator);
        }
    }

    protected class GTKDirectoryListModel extends AbstractListModel implements ListDataListener {
        File curDir;
        public GTKDirectoryListModel() {
            getModel().addListDataListener(this);
            directoryChanged();
        }

        public int getSize() {
            return getModel().getDirectories().size() + 1;
        }

        public Object getElementAt(int index) {
            return index > 0 ? getModel().getDirectories().elementAt(index - 1):
                    curDir;
        }

        public void intervalAdded(ListDataEvent e) {
            fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
        }

        public void intervalRemoved(ListDataEvent e) {
            fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
        }

        // PENDING - this is inefficient - should sent out
        // incremental adjustment values instead of saying that the
        // whole list has changed.
        public void fireContentsChanged() {
            fireContentsChanged(this, 0, getModel().getDirectories().size()-1);
        }

        // PENDING - fire the correct interval changed - currently sending
        // out that everything has changed
        public void contentsChanged(ListDataEvent e) {
            fireContentsChanged();
        }

        private void directoryChanged() {
            curDir = getFileChooser().getFileSystemView().createFileObject(
                    getFileChooser().getCurrentDirectory(), ".");
        }
    }

    protected class GTKFileListModel extends AbstractListModel implements ListDataListener {
        public GTKFileListModel() {
            getModel().addListDataListener(this);
        }

        public int getSize() {
            return getModel().getFiles().size();
        }

        public boolean contains(Object o) {
            return getModel().getFiles().contains(o);
        }

        public int indexOf(Object o) {
            return getModel().getFiles().indexOf(o);
        }

        public Object getElementAt(int index) {
            return getModel().getFiles().elementAt(index);
        }

        public void intervalAdded(ListDataEvent e) {
            fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
        }

        public void intervalRemoved(ListDataEvent e) {
            fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
        }

        // PENDING - this is inefficient - should sent out
        // incremental adjustment values instead of saying that the
        // whole list has changed.
        public void fireContentsChanged() {
            fireContentsChanged(this, 0, getModel().getFiles().size()-1);
        }

        // PENDING - fire the interval changed
        public void contentsChanged(ListDataEvent e) {
            fireContentsChanged();
        }
    }


    protected class FileCellRenderer extends DefaultListCellRenderer  {
        public Component getListCellRendererComponent(JList list, Object value, int index,
                                                      boolean isSelected, boolean cellHasFocus) {

            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            setText(getFileChooser().getName((File) value));
            if (showFileIcons) {
                setIcon(getFileChooser().getIcon((File)value));
            }
            return this;
        }
    }

    protected class DirectoryCellRenderer extends DefaultListCellRenderer  {
        public Component getListCellRendererComponent(JList list, Object value, int index,
                                                      boolean isSelected, boolean cellHasFocus) {

            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

            if (showDirectoryIcons) {
                setIcon(getFileChooser().getIcon((File)value));
                setText(getFileChooser().getName((File)value));
            } else {
                setText(getFileChooser().getName((File)value) + "/");
            }
            return this;
        }
    }

    public Dimension getPreferredSize(JComponent c) {
        Dimension prefSize = new Dimension(PREF_SIZE);
        JComponent accessory = getFileChooser().getAccessory();
        if (accessory != null) {
            prefSize.width += accessory.getPreferredSize().width + 20;
        }
        Dimension d = c.getLayout().preferredLayoutSize(c);
        if (d != null) {
            return new Dimension(d.width < prefSize.width ? prefSize.width : d.width,
                                 d.height < prefSize.height ? prefSize.height : d.height);
        } else {
            return prefSize;
        }
    }

    public Dimension getMinimumSize(JComponent x)  {
        return new Dimension(MIN_SIZE);
    }

    public Dimension getMaximumSize(JComponent x) {
        return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
    }

    protected void align(JComponent c) {
        c.setAlignmentX(JComponent.LEFT_ALIGNMENT);
        c.setAlignmentY(JComponent.TOP_ALIGNMENT);
    }

    public Action getNewFolderAction() {
        if (newFolderAction == null) {
            newFolderAction = new NewFolderAction();
            newFolderAction.setEnabled(!readOnly);
        }
        return newFolderAction;
    }

    //
    // DataModel for DirectoryComboxbox
    //
    protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) {
        return new DirectoryComboBoxModel();
    }

    /**
     * Data model for a type-face selection combo-box.
     */
    protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel {
        Vector directories = new Vector();
        File selectedDirectory = null;
        JFileChooser chooser = getFileChooser();
        FileSystemView fsv = chooser.getFileSystemView();

        public DirectoryComboBoxModel() {
            // Add the current directory to the model, and make it the
            // selectedDirectory
            File dir = getFileChooser().getCurrentDirectory();
            if (dir != null) {
                addItem(dir);
            }
        }

        /**
         * Adds the directory to the model and sets it to be selected,
         * additionally clears out the previous selected directory and
         * the paths leading up to it, if any.
         */
        private void addItem(File directory) {

            if (directory == null) {
                return;
            }

            int oldSize = directories.size();
            directories.clear();
            if (oldSize > 0) {
                fireIntervalRemoved(this, 0, oldSize);
            }

            // Get the canonical (full) path. This has the side
            // benefit of removing extraneous chars from the path,
            // for example /foo/bar/ becomes /foo/bar
            File canonical = null;
            try {
                canonical = fsv.createFileObject(ShellFolder.getNormalizedFile(directory).getPath());
            } catch (IOException e) {
                // Maybe drive is not ready. Can't abort here.
                canonical = directory;
            }

            // create File instances of each directory leading up to the top
            File f = canonical;
            do {
                directories.add(f);
            } while ((f = f.getParentFile()) != null);
            int newSize = directories.size();
            if (newSize > 0) {
                fireIntervalAdded(this, 0, newSize);
            }
            setSelectedItem(canonical);
        }

        public void setSelectedItem(Object selectedDirectory) {
            this.selectedDirectory = (File)selectedDirectory;
            fireContentsChanged(this, -1, -1);
        }

        public Object getSelectedItem() {
            return selectedDirectory;
        }

        public int getSize() {
            return directories.size();
        }

        public Object getElementAt(int index) {
            return directories.elementAt(index);
        }
    }

    /**
     * Acts when DirectoryComboBox has changed the selected item.
     */
    protected class DirectoryComboBoxAction extends AbstractAction {
        protected DirectoryComboBoxAction() {
            super("DirectoryComboBoxAction");
        }

        public void actionPerformed(ActionEvent e) {
            File f = (File)directoryComboBox.getSelectedItem();
            getFileChooser().setCurrentDirectory(f);
        }
    }

    /**
     * Creates a new folder.
     */
    private class NewFolderAction extends AbstractAction {
        protected NewFolderAction() {
            super(FilePane.ACTION_NEW_FOLDER);
        }
        public void actionPerformed(ActionEvent e) {
            if (readOnly) {
                return;
            }
            JFileChooser fc = getFileChooser();
            File currentDirectory = fc.getCurrentDirectory();
            String dirName = JOptionPane.showInputDialog(fc,
                    newFolderDialogText, newFolderButtonText,
                    JOptionPane.PLAIN_MESSAGE);

            if (dirName != null) {
                if (!currentDirectory.exists()) {
                    JOptionPane.showMessageDialog(fc,
                            MessageFormat.format(newFolderNoDirectoryErrorText, dirName),
                            newFolderNoDirectoryErrorTitleText, JOptionPane.ERROR_MESSAGE);
                    return;
                }

                File newDir = fc.getFileSystemView().createFileObject
                        (currentDirectory, dirName);
                if (newDir == null || !newDir.mkdir()) {
                    JOptionPane.showMessageDialog(fc,
                            newFolderErrorText + newFolderErrorSeparator + " \"" +
                            dirName + "\"",
                            newFolderErrorText, JOptionPane.ERROR_MESSAGE);
                }
                fc.rescanCurrentDirectory();
            }
        }
    }

    private class GTKApproveSelectionAction extends ApproveSelectionAction {
        public void actionPerformed(ActionEvent e) {
            if (isDirectorySelected()) {
                File dir = getDirectory();
                try {
                    // Strip trailing ".."
                    if (dir != null) {
                        dir = ShellFolder.getNormalizedFile(dir);
                    }
                } catch (IOException ex) {
                    // Ok, use f as is
                }
                if (getFileChooser().getCurrentDirectory().equals(dir)) {
                    directoryList.clearSelection();
                    fileList.clearSelection();
                    ListSelectionModel sm = fileList.getSelectionModel();
                    if (sm instanceof DefaultListSelectionModel) {
                        ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0);
                        ((DefaultListSelectionModel)sm).setAnchorSelectionIndex(0);
                    }
                    rescanCurrentDirectory(getFileChooser());
                    return;
                }
            }
            super.actionPerformed(e);
        }
    }

    /**
     * Renames file
     */
    private class RenameFileAction extends AbstractAction {
        protected RenameFileAction() {
            super(FilePane.ACTION_EDIT_FILE_NAME);
        }
        public void actionPerformed(ActionEvent e) {
            if (getFileName().equals("")) {
                return;
            }
            JFileChooser fc = getFileChooser();
            File currentDirectory = fc.getCurrentDirectory();
            String newFileName = (String) JOptionPane.showInputDialog
                   (fc, new MessageFormat(renameFileDialogText).format
                           (new Object[] { getFileName() }),
                           renameFileButtonText, JOptionPane.PLAIN_MESSAGE, null, null,
                           getFileName());

            if (newFileName != null) {
                File oldFile = fc.getFileSystemView().createFileObject
                        (currentDirectory, getFileName());
                File newFile = fc.getFileSystemView().createFileObject
                        (currentDirectory, newFileName);
                if (oldFile == null || newFile == null ||
                        !getModel().renameFile(oldFile, newFile)) {
                    JOptionPane.showMessageDialog(fc,
                            new MessageFormat(renameFileErrorText).
                            format(new Object[] { getFileName(), newFileName}),
                            renameFileErrorTitle, JOptionPane.ERROR_MESSAGE);
                } else {
                    setFileName(getFileChooser().getName(newFile));
                    fc.rescanCurrentDirectory();
                }
            }
        }
    }

    //
    // Renderer for Filter ComboBox
    //
    protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
        return new FilterComboBoxRenderer();
    }

    /**
     * Render different filters
     */
    public class FilterComboBoxRenderer extends DefaultListCellRenderer implements UIResource {
        public String getName() {
            // As SynthComboBoxRenderer's are asked for a size BEFORE they
            // are parented getName is overriden to force the name to be
            // ComboBox.renderer if it isn't set. If we didn't do this the
            // wrong style could be used for size calculations.
            String name = super.getName();
            if (name == null) {
                return "ComboBox.renderer";
            }
            return name;
        }

        public Component getListCellRendererComponent(JList list, Object value,
                                                      int index, boolean isSelected,
                                                      boolean cellHasFocus) {

            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

            setName("ComboBox.listRenderer");

            if (value != null) {
                if (value instanceof FileFilter) {
                    setText(((FileFilter) value).getDescription());
                }
            } else {
                setText("");
            }

            return this;
        }
    }

    //
    // DataModel for Filter Combobox
    //
    protected FilterComboBoxModel createFilterComboBoxModel() {
        return new FilterComboBoxModel();
    }

    /**
     * Data model for filter combo-box.
     */
    protected class FilterComboBoxModel extends AbstractListModel
            implements ComboBoxModel, PropertyChangeListener {
        protected FileFilter[] filters;

        protected FilterComboBoxModel() {
            super();
            filters = getFileChooser().getChoosableFileFilters();
        }

        public void propertyChange(PropertyChangeEvent e) {
            String prop = e.getPropertyName();
            if (prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
                filters = (FileFilter[]) e.getNewValue();
                fireContentsChanged(this, -1, -1);
            } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
                fireContentsChanged(this, -1, -1);
            }
        }

        public void setSelectedItem(Object filter) {
            if (filter != null) {
                getFileChooser().setFileFilter((FileFilter) filter);
                fireContentsChanged(this, -1, -1);
            }
        }

        public Object getSelectedItem() {
            // Ensure that the current filter is in the list.
            // NOTE: we shouldnt' have to do this, since JFileChooser adds
            // the filter to the choosable filters list when the filter
            // is set. Lets be paranoid just in case someone overrides
            // setFileFilter in JFileChooser.
            FileFilter currentFilter = getFileChooser().getFileFilter();
            boolean found = false;
            if (currentFilter != null) {
                for (int i = 0; i < filters.length; i++) {
                    if (filters[i] == currentFilter) {
                        found = true;
                    }
                }
                if (found == false) {
                    getFileChooser().addChoosableFileFilter(currentFilter);
                }
            }
            return getFileChooser().getFileFilter();
        }

        public int getSize() {
            if (filters != null) {
                return filters.length;
            } else {
                return 0;
            }
        }

        public Object getElementAt(int index) {
            if (index > getSize() - 1) {
                // This shouldn't happen. Try to recover gracefully.
                return getFileChooser().getFileFilter();
            }
            if (filters != null) {
                return filters[index];
            } else {
                return null;
            }
        }
    }
}
