/*
 * Java-Gnome Bindings Library
 * 
 * Copyright 1998-2004 the Java-Gnome Team, all rights reserved.
 * 
 * The Java-Gnome bindings library is free software distributed under the terms
 * of the GNU Library General Public License version 2.
 */

package org.gnu.gtk;

import java.util.ArrayList;
import java.util.List;

import org.gnu.glib.EventMap;
import org.gnu.glib.Handle;
import org.gnu.gtk.event.FileChooserEvent;
import org.gnu.gtk.event.FileChooserListener;

/**
 * 
 */
public class FileChooserDialog extends Dialog implements FileChooser {

    private List listeners;

    private static EventMap eventMap = new EventMap();

    static {
        addEvents(eventMap);
    }

    public FileChooserDialog(Handle handle) {
        super(handle);
    }

    /**
     * Internal static factory method to be used by Java-Gnome only.
     */
    public static FileChooserDialog getFileChooserDialog(Handle handle) {
        if (handle == null)
            return null;

        FileChooserDialog obj = (FileChooserDialog) getGObjectFromHandle(handle);
        if (obj == null)
            obj = new FileChooserDialog(handle);

        return obj;
    }

    public FileChooserDialog(String title, Window parent,
            FileChooserAction action) {
        super(init(title, parent, action));
    }

    /**
     * Works similarly to {@link Dialog#run()}. The only difference is that it
     * also adds the {@link GtkStockItem#CANCEL} and the {@link GtkStockItem#OK}
     * buttons to the FileChooserDialog.
     * 
     * @return The response that indicates which button the user pressed or
     *         {@link ResponseType#NONE} if the window was destroyed.
     */
    public int open() {
        addButton(GtkStockItem.CANCEL, ResponseType.CANCEL.getValue());
        addButton(GtkStockItem.OK, ResponseType.OK.getValue());
        return run();
    }

    private static Handle init(String title, Window parent,
            FileChooserAction action) {
        Handle hndl = getNullHandle();
        if (null != parent)
            hndl = parent.getHandle();
        return gtk_file_chooser_dialog_new(title, hndl, action.getValue());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setAction(org.gnu.gtk.FileChooserAction)
     */
    public void setAction(FileChooserAction action) {
        FileChooserHelper.gtk_file_chooser_set_action(getHandle(), action
                .getValue());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getAction()
     */
    public FileChooserAction getAction() {
        return FileChooserAction.intern(FileChooserHelper
                .gtk_file_chooser_get_action(getHandle()));
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setLocalOnly(boolean)
     */
    public void setLocalOnly(boolean localOnly) {
        FileChooserHelper.gtk_file_chooser_set_local_only(getHandle(),
                localOnly);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getLocalOnly()
     */
    public boolean getLocalOnly() {
        return FileChooserHelper.gtk_file_chooser_get_local_only(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setSelectMultiple(boolean)
     */
    public void setSelectMultiple(boolean selectMultiple) {
        FileChooserHelper.gtk_file_chooser_set_select_multiple(getHandle(),
                selectMultiple);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getSelectMultiple()
     */
    public boolean getSelectMultiple() {
        return FileChooserHelper
                .gtk_file_chooser_get_select_multiple(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setCurrentName(java.lang.String)
     */
    public void setCurrentName(String name) {
        FileChooserHelper.gtk_file_chooser_set_current_name(getHandle(), name);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getFilename()
     */
    public String getFilename() {
        return FileChooserHelper.gtk_file_chooser_get_filename(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setFilename(java.lang.String)
     */
    public boolean setFilename(String filename) {
        return FileChooserHelper.setFilename(getHandle(), filename);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#selectFilename(java.lang.String)
     */
    public boolean selectFilename(String filename) {
        return FileChooserHelper.gtk_file_chooser_select_filename(getHandle(),
                filename);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#unselectFilename(java.lang.String)
     */
    public void unselectFilename(String filename) {
        FileChooserHelper.gtk_file_chooser_unselect_filename(getHandle(),
                filename);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#selectAll()
     */
    public void selectAll() {
        FileChooserHelper.gtk_file_chooser_select_all(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#unselectAll()
     */
    public void unselectAll() {
        FileChooserHelper.gtk_file_chooser_unselect_all(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getFilenames()
     */
    public String[] getFilenames() {
        return FileChooserHelper.gtk_file_chooser_get_filenames(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setCurrentFolder(java.lang.String)
     */
    public boolean setCurrentFolder(String folder) {
        return FileChooserHelper.gtk_file_chooser_set_current_folder(
                getHandle(), folder);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getCurrentFolder()
     */
    public String getCurrentFolder() {
        return FileChooserHelper
                .gtk_file_chooser_get_current_folder(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getURI()
     */
    public String getURI() {
        return FileChooserHelper.gtk_file_chooser_get_uri(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setURI(java.lang.String)
     */
    public boolean setURI(String uri) {
        return FileChooserHelper.gtk_file_chooser_set_uri(getHandle(), uri);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#selectURI(java.lang.String)
     */
    public boolean selectURI(String uri) {
        return FileChooserHelper.gtk_file_chooser_select_uri(getHandle(), uri);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#unselectURI(java.lang.String)
     */
    public void unselectURI(String uri) {
        FileChooserHelper.gtk_file_chooser_unselect_uri(getHandle(), uri);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getURIs()
     */
    public String[] getURIs() {
        return FileChooserHelper.gtk_file_chooser_get_uris(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setCurrentFolderURI(java.lang.String)
     */
    public boolean setCurrentFolderURI(String folder) {
        return FileChooserHelper.gtk_file_chooser_set_current_folder_uri(
                getHandle(), folder);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getCurrentFolderURI()
     */
    public String getCurrentFolderURI() {
        return FileChooserHelper
                .gtk_file_chooser_get_current_folder_uri(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setPreviewWidget(org.gnu.gtk.Widget)
     */
    public void setPreviewWidget(Widget previewWidget) {
        FileChooserHelper.gtk_file_chooser_set_preview_widget(getHandle(),
                previewWidget.getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getPreviewWidget()
     */
    public Widget getPreviewWidget() {
        Handle hndl = FileChooserHelper
                .gtk_file_chooser_get_preview_widget(getHandle());
        return Widget.getWidget(hndl);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setUsePreviewLabel()
     */
    public void setUsePreviewLabel(boolean useLabel) {
        FileChooserHelper.gtk_file_chooser_set_use_preview_label(getHandle(),
                useLabel);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getUsePreviewLabel()
     */
    public boolean getUsePreviewLabel() {
        return FileChooserHelper
                .gtk_file_chooser_get_use_preview_label(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setPreviewWidgetActive(boolean)
     */
    public void setPreviewWidgetActive(boolean active) {
        FileChooserHelper.gtk_file_chooser_set_preview_widget_active(
                getHandle(), active);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getPreviewWidgetActive()
     */
    public boolean getPreviewWidgetActive() {
        return FileChooserHelper
                .gtk_file_chooser_get_preview_widget_active(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getPreviewFilename()
     */
    public String getPreviewFilename() {
        return FileChooserHelper
                .gtk_file_chooser_get_preview_filename(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getPreviewURI()
     */
    public String getPreviewURI() {
        return FileChooserHelper.gtk_file_chooser_get_preview_uri(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setExtraWidget(org.gnu.gtk.Widget)
     */
    public void setExtraWidget(Widget extraWidget) {
        FileChooserHelper.gtk_file_chooser_set_extra_widget(getHandle(),
                extraWidget.getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getExtraWidget()
     */
    public Widget getExtraWidget() {
        Handle hndl = FileChooserHelper
                .gtk_file_chooser_get_extra_widget(getHandle());
        return Widget.getWidget(hndl);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#addFilter(org.gnu.gtk.FileFilter)
     */
    public void addFilter(FileFilter filter) {
        FileChooserHelper.gtk_file_chooser_add_filter(getHandle(), filter
                .getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#removeFilter(org.gnu.gtk.FileFilter)
     */
    public void removeFilter(FileFilter filter) {
        FileChooserHelper.gtk_file_chooser_remove_filter(getHandle(), filter
                .getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#listFilters()
     */
    public FileFilter[] listFilters() {
        Handle[] hndls = FileChooserHelper
                .gtk_file_chooser_list_filters(getHandle());
        FileFilter[] filters = new FileFilter[hndls.length];
        for (int i = 0; i < hndls.length; i++) {
            filters[i] = FileFilter.getFileFilter(hndls[i]);
        }
        return filters;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#setFilter(org.gnu.gtk.FileFilter)
     */
    public void setFilter(FileFilter filter) {
        FileChooserHelper.gtk_file_chooser_set_filter(getHandle(), filter
                .getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#getFilter()
     */
    public FileFilter getFilter() {
        Handle hndl = FileChooserHelper
                .gtk_file_chooser_get_filter(getHandle());
        return FileFilter.getFileFilter(hndl);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#addShortcutFolder(java.lang.String)
     */
    public void addShortcutFolder(String folder) throws FileChooserException {
        FileChooserHelper.addShortcutFolder(getHandle(), folder);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#removeShortcutFolder(java.lang.String)
     */
    public void removeShortcutFolder(String folder) throws FileChooserException {
        FileChooserHelper.removeShortcutFolder(getHandle(), folder);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#listShortcutFolders()
     */
    public String[] listShortcutFolders() {
        return FileChooserHelper
                .gtk_file_chooser_list_shortcut_folders(getHandle());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#addShortCutURI(java.lang.String)
     */
    public void addShortcutURI(String uri) throws FileChooserException {
        FileChooserHelper.addShortcutURI(getHandle(), uri);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#removeShortcutURI(java.lang.String)
     */
    public void removeShortcutURI(String uri) throws FileChooserException {
        FileChooserHelper.removeShortcutURI(getHandle(), uri);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.gnu.gtk.FileChooser#listShortcutURIs()
     */
    public String[] listShortcutURIs() {
        return FileChooserHelper
                .gtk_file_chooser_list_shortcut_folder_uris(getHandle());
    }

    /**
     * Sets whether hidden files and folders are displayed in the file selector.
     * 
     * @param hidden
     *            <tt>true</tt> if hidden files and folders should be
     *            displayed.
     */
    public void setShowHidden(boolean hidden) {
        FileChooserHelper.gtk_file_chooser_set_show_hidden(getHandle(), hidden);
    }

    /**
     * Sets whether hidden files and folders are displayed in the file selector.
     * 
     * @return <tt>true</tt> if hidden files and folders should be displayed.
     */
    public boolean getShowHidden() {
        return FileChooserHelper.gtk_file_chooser_get_show_hidden(getHandle());
    }

    public void addListener(FileChooserListener listener) {
        if (listeners == null) {
            listeners = new ArrayList();
        }
        FileChooserHelper.addListener(listeners, listener, eventMap, this);
    }

    public void removeListener(FileChooserListener listener) {
        FileChooserHelper.removeListener(listeners, listener, eventMap, this);
        if (listeners.size() == 0) {
            listeners = null;
        }
    }

    private static void addEvents(EventMap eventMap) {
        FileChooserEvent.Type[] types = FileChooserEvent.Type.getTypes();
        for (int i = 0; i < types.length; ++i) {
            eventMap.addEvent(types[i], FileChooserDialog.class);
        }
    }

    private void handleCurrentFolderChanged() {
        FileChooserEvent event = new FileChooserEvent(this,
                FileChooserEvent.Type.CURRENT_FOLDER_CHANGED);
        FileChooserHelper.fireCurrentFolderChanged(listeners, event);
    }

    private void handleFileActivated() {
        FileChooserEvent event = new FileChooserEvent(this,
                FileChooserEvent.Type.CURRENT_FOLDER_CHANGED);

        FileChooserHelper.fireFileActivated(listeners, event);
    }

    private void handleSelectionChanged() {
        FileChooserEvent event = new FileChooserEvent(this,
                FileChooserEvent.Type.CURRENT_FOLDER_CHANGED);
        FileChooserHelper.fireSelectionChanged(listeners, event);
    }

    private void handleUpdatePreview() {
        FileChooserEvent event = new FileChooserEvent(this,
                FileChooserEvent.Type.CURRENT_FOLDER_CHANGED);
        FileChooserHelper.fireUpdatePreview(listeners, event);
    }

    native static final protected int gtk_file_chooser_dialog_get_type();

    native static final protected Handle gtk_file_chooser_dialog_new(
            String title, Handle parent, int action);
}
