/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */
package net.sf.jaxodraw.gui.panel;

import java.awt.Component;

import java.io.File;

import java.util.HashSet;
import java.util.Locale;
import java.util.Set;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

import net.sf.jaxodraw.gui.JaxoDialogs;
import net.sf.jaxodraw.io.JaxoIO;
import net.sf.jaxodraw.util.JaxoPrefs;
import net.sf.jaxodraw.util.JaxoDictionary;


/** Opens a file chooser dialog that is used for opening, saving and exporting
 * files.
 * @since 2.0
 */
public class JaxoChooseFile {
    private static final JaxoDictionary LANGUAGE = new JaxoDictionary(JaxoChooseFile.class);
    private Component parent;
    private String approveText;
    private String dialogTitle;

    /**
     * Constructor.
     * @param parentc The parent component.
     */
    public JaxoChooseFile(final Component parentc) {
        this(parentc, null);
    }

    /**
     * Constructor.
     * @param parentc The parent component.
     * @param text The text to use as a dialog title.
     */
    public JaxoChooseFile(final Component parentc, final String text) {
        this.parent = parentc;
        this.approveText = text;
    }

    /**
     * Parent component for the dialog.
     * @return The parent component.
     */
    public final Component getComponentParent() {
        return parent;
    }

    /**
     * Sets the parent component.
     * @param value The parent component.
     */
    public void setComponentParent(final Component value) {
        parent = value;
    }

    /**
     * Text for the JFileChooser approve button. Must be set.
     * @return The approve button text.
     */
    public final String getApproveText() {
        return approveText;
    }

    /**
     * The text for the approve button.
     * @param value The approve button text.
     */
    public void setApproveText(final String value) {
        approveText = value;
    }

    /**
     * Title to be used for dialogs. If 'null' (the default),
     * a default will be created using the approve text, but this
     * is typically inferior to setting a custom one.
     * @return The dialog title.
     */
    public final String getDialogTitle() {
        // TODO: approveText may be null as well?
        return (dialogTitle == null ? approveText : dialogTitle);
    }

    /**
     * Sets the dialog title.
     * @param value The dialog title.
     */
    public void setDialogTitle(final String value) {
        dialogTitle = value;
    }

    /** Brings up a file chooser dialog.
     * @return A string with the absolute path of the chosen file, or an empty
     * string, if no file was selected.
     * @param selectedFile A file that should be marked as pre-selected.
     * @param allowedExtensions Files with these extensions (and directories) will
     * be shown. May be 'null' indication no filtering.
     * @param description A description of this dialog.
     */
    public final String chooseFile(final String[] allowedExtensions,
        final String description, final String selectedFile) {
        String fileName = "";

        final JFileChooser chooser =
            new JFileChooser(JaxoPrefs.getStringPref(JaxoPrefs.PREF_USER_DIR));
        if (allowedExtensions != null) {
            chooser.setFileFilter(new ExtensionFilter(allowedExtensions,
                    description));
        }
        chooser.setSelectedFile(new File(selectedFile));
        chooser.setApproveButtonText(approveText);
        chooser.setDialogTitle(JaxoDialogs.translatedWindowTitle((
                    dialogTitle == null
                )
                ? LANGUAGE.value("defaultTitle") : dialogTitle));

        // If approveButtonText is not null, the chooser will (usually) not
        // show a silly tooltip text on the approve button.
        final int returnVal =
            chooser.showDialog(parent, chooser.getApproveButtonText());

        if (returnVal == JFileChooser.APPROVE_OPTION) {
            fileName = chooser.getSelectedFile().getAbsolutePath();
            JaxoPrefs.setStringPref(
                JaxoPrefs.PREF_USER_DIR, chooser.getSelectedFile().getParent());
        }

        return fileName;
    }

    /** Filter out all non-directories that do not have given extensions. */
    private static class ExtensionFilter extends FileFilter {
        private final Set<String> extensions;
        private final String description;

        ExtensionFilter(final String[] ext, final String desc) {
            super();
            this.extensions = new HashSet<String>(ext.length);

            for (int i = 0; i < ext.length; i++) {
                this.extensions.add(ext[i].toLowerCase(Locale.ENGLISH));
            }

            this.description = desc;
        }

        public final boolean accept(final File f) {
            if (f != null) {
                if (f.isDirectory()) {
                    return true;
                }

                if (extensions.contains(JaxoIO.extension(f.getName())
                                                  .toLowerCase(Locale.ENGLISH))) {
                    return true;
                }
            }

            return false;
        }

        public final String getDescription() {
            return description;
        }
    }
}
