/*
 * 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.Vector;

import org.gnu.glib.EventMap;
import org.gnu.glib.EventType;
import org.gnu.glib.GObject;
import org.gnu.gtk.event.EntryCompletionEvent;
import org.gnu.gtk.event.EntryCompletionListener;
import org.gnu.glib.Handle;

/**
 * EntryCompletion is an auxiliary object to be used in conjunction with Entry
 * to provide the completion functionality. To add completion functionality to
 * an Entry, use setCompletion(). In addition to regular completion matches,
 * which will be inserted into the entry when they are selected, EntryCompletion
 * also allows to display "actions" in the popup window. Their appearance is
 * similar to menuitems, to differentiate them clearly from completion strings.
 * When an action is selected, the ::action-activated signal is emitted.
 *
 * @deprecated This class is part of the java-gnome 2.x family of libraries,
 *             which, due to their inefficiency and complexity, are no longer
 *             being maintained and have been abandoned by the java-gnome
 *             project. This class may in the future have an equivalent in
 *             java-gnome 4.0, try looking for
 *             <code>org.gnome.gtk.EntryCompletion</code>.
 *             You should be aware that there is a considerably different API
 *             in the new library: the architecture is completely different
 *             and most notably internals are no longer exposed to public view.
 */
public class EntryCompletion extends GObject {

    /**
     * Creates a new EntryCompletion object.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public EntryCompletion() {
        super(gtk_entry_completion_new());
    }

    public EntryCompletion(Handle nativeHandle) {
        super(nativeHandle);
    }

    /**
     * Internal static factory method to be used by Java-Gnome only.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public static EntryCompletion getEntryCompletion(Handle handle) {
        if (handle == null)
            return null;

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

        return obj;
    }

    /**
     * Returns the Entry this completion is attached to.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public Entry getEntry() {
        Handle hndl = gtk_entry_completion_get_entry(getHandle());
        return Entry.getEntry(hndl);
    }

    /**
     * Sets the model for this EntryCompletion. If there is already a model set
     * it will remove it before setting the new mode.
     * 
     * @param model
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setModel(TreeModel model) {
        gtk_entry_completion_set_model(getHandle(), model.getHandle());
    }

    /**
     * Returns the model that the EntryCompletion is using as a data source.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public TreeModel getModel() {
        Handle hndl = gtk_entry_completion_get_model(getHandle());
        return TreeModel.getTreeModel(hndl);
    }

    /**
     * Requires the length of the search key for the EntryCompletion to be at
     * least <i>length</i>. This is useful for long lists where completing
     * using a small key takes a lot of time and will come up with meaningless
     * results.
     * 
     * @param length
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setMinimumKeyLength(int length) {
        gtk_entry_completion_set_minimum_key_length(getHandle(), length);
    }

    /**
     * Returns the minimum key length as set for completion.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public int getMinimumKeyLength() {
        return gtk_entry_completion_get_minimum_key_length(getHandle());
    }

    /**
     * Requests a completion operation, or in other words a refiltering of the
     * current list with completions, using the current key.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void complete() {
        gtk_entry_completion_complete(getHandle());
    }

    /**
     * Request a prefix insertion.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void insertPrefix() {
        gtk_entry_completion_insert_prefix(getHandle());
    }

    /**
     * Inserts an action in the EntryCompletion's action list with the position
     * and text provided. If this item is selected an event will be triggered of
     * type ACTION_ACTIVATED. You can get the index value from the
     * EntryCompletionEvent object.
     * 
     * @param index
     * @param text
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void insertActionText(int index, String text) {
        gtk_entry_completion_insert_action_text(getHandle(), index, text);
    }

    /**
     * Inserts an action in the EntryCompletion's action list with the position
     * and text provided. If this item is selected an event will be triggered of
     * type ACTION_ACTIVATED. You can get the index value from the
     * EntryCompletionEvent object.
     * 
     * @param index
     * @param markup
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void insertActionMarkup(int index, String markup) {
        gtk_entry_completion_insert_action_markup(getHandle(), index, markup);
    }

    /**
     * Remove an action for the EntryCompletions action list.
     * 
     * @param index
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void deleteAction(int index) {
        gtk_entry_completion_delete_action(getHandle(), index);
    }

    /**
     * Sets whether the common prefix of the possible completion should be
     * automatically inserted into the entry.
     * 
     * @param inlineCompletion
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setInlineCompletion(boolean inlineCompletion) {
        gtk_entry_completion_set_inline_completion(getHandle(),
                inlineCompletion);
    }

    /**
     * Returns whether the common prefix of the possible completion should be
     * automatically inserted into the entry.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public boolean getInlineCompletion() {
        return gtk_entry_completion_get_inline_completion(getHandle());
    }

    /**
     * Sets whether the completion should be presented in a popup window.
     * 
     * @param popupCompletion
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setPopupCompletion(boolean popupCompletion) {
        gtk_entry_completion_set_popup_completion(getHandle(), popupCompletion);
    }

    /**
     * Returns whether the completion should be presented in a popup window.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public boolean getPopupCompletion() {
        return gtk_entry_completion_get_popup_completion(getHandle());
    }

    /**
     * Specify which column in the model to use to display the strings.
     * 
     * @param column
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void setTextColumn(int column) {
        gtk_entry_completion_set_text_column(getHandle(), column);
    }

    /**
     * Returns the column in the model of completion to get strings from.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public int getTextColumn() {
        return gtk_entry_completion_get_text_column(getHandle());
    }

    public void setPopupSetWidth(boolean setWidth) {
        gtk_entry_completion_set_popup_set_width(getHandle(), setWidth);
    }

    public boolean getPopupSetWidth() {
        return gtk_entry_completion_get_popup_set_width(getHandle());
    }

    /***************************************************************************
     * EVENT LISTENERS
     **************************************************************************/

    /**
     * Listeners for handling dialog events
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    private Vector ecListeners = null;

    /**
     * Register an object to handle dialog events.
     * 
     * @see EntryCompletionListener
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void addListener(EntryCompletionListener listener) {
        // Don't add the listener a second time if it is in the Vector.
        int i = findListener(ecListeners, listener);
        if (i == -1) {
            if (null == ecListeners) {
                evtMap.initialize(this,
                        EntryCompletionEvent.Type.ACTION_ACTIVATED);
                evtMap.initialize(this,
                        EntryCompletionEvent.Type.MATCH_SELECTED);
                ecListeners = new Vector();
            }
            ecListeners.addElement(listener);
        }
    }

    /**
     * Removes a listener
     * 
     * @see #addListener(EntryCompletionListener)
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    public void removeListener(EntryCompletionListener listener) {
        int i = findListener(ecListeners, listener);
        if (i > -1) {
            ecListeners.remove(i);
        }
        if (0 == ecListeners.size()) {
            evtMap.uninitialize(this,
                    EntryCompletionEvent.Type.ACTION_ACTIVATED);
            evtMap.uninitialize(this, EntryCompletionEvent.Type.MATCH_SELECTED);
            ecListeners = null;
        }
    }

    protected void fireEntrySelectionEvent(EntryCompletionEvent event) {
        if (null == ecListeners) {
            return;
        }
        int size = ecListeners.size();
        int i = 0;
        while (i < size) {
            EntryCompletionListener ecl = (EntryCompletionListener) ecListeners
                    .elementAt(i);
            ecl.entryCompletionEvent(event);
            i++;
        }
    }

    private boolean handleMatchSelected(Handle model, Handle iter) {
        EntryCompletionEvent evt = new EntryCompletionEvent(this,
                EntryCompletionEvent.Type.MATCH_SELECTED);
        TreeModelFilter tm = TreeModelFilter.getTreeModelFilter(model);
        evt.setModel(tm);
        evt.setIter(TreeIter.getTreeIter(iter, tm));
        fireEntrySelectionEvent(evt);
        return true;
    }

    private void handleActionActivated(int index) {
        EntryCompletionEvent evt = new EntryCompletionEvent(this,
                EntryCompletionEvent.Type.ACTION_ACTIVATED);
        evt.setIndex(index);
        fireEntrySelectionEvent(evt);
    }

    public Class getEventListenerClass(String signal) {
        Class cls = evtMap.getEventListenerClass(signal);
        if (cls == null)
            cls = super.getEventListenerClass(signal);
        return cls;
    }

    public EventType getEventType(String signal) {
        EventType et = evtMap.getEventType(signal);
        if (et == null)
            et = super.getEventType(signal);
        return et;
    }

    private static EventMap evtMap = new EventMap();
    static {
        addEvents(evtMap);
    }

    /**
     * Implementation method to build an EventMap for this widget class. Not
     * useful (or supported) for application use.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    private static void addEvents(EventMap anEvtMap) {
        anEvtMap.addEvent("match_selected", "handleMatchSelected",
                EntryCompletionEvent.Type.MATCH_SELECTED,
                EntryCompletionListener.class);
        anEvtMap.addEvent("action_activated", "handleActionActivated",
                EntryCompletionEvent.Type.ACTION_ACTIVATED,
                EntryCompletionListener.class);
    }

    /**
     * Give us a way to locate a specific listener in a Vector.
     * 
     * @param list
     *            The Vector of listeners to search.
     * @param listener
     *            The object that is to be located in the Vector.
     * @return Returns the index of the listener in the Vector, or -1 if the
     *         listener is not contained in the Vector.
     * @deprecated Superceeded by java-gnome 4.0; a method along these lines
     *             may well exist in the new bindings, but if it does it likely
     *             has a different name or signature due to the shift to an
     *             algorithmic mapping of the underlying native libraries.
     */
    protected int findListener(Vector list, Object listener) {
        if (null == list || null == listener)
            return -1;
        return list.indexOf(listener);
    }

    native static final protected int gtk_entry_completion_get_type();

    native static final protected Handle gtk_entry_completion_new();

    native static final protected Handle gtk_entry_completion_get_entry(
            Handle completion);

    native static final protected void gtk_entry_completion_set_model(
            Handle completion, Handle model);

    native static final protected Handle gtk_entry_completion_get_model(
            Handle completion);

    native static final protected void gtk_entry_completion_set_minimum_key_length(
            Handle completion, int length);

    native static final protected int gtk_entry_completion_get_minimum_key_length(
            Handle completion);

    native static final protected void gtk_entry_completion_complete(
            Handle completion);

    native static final protected void gtk_entry_completion_insert_prefix(
            Handle completion);

    native static final protected void gtk_entry_completion_insert_action_text(
            Handle completion, int index, String text);

    native static final protected void gtk_entry_completion_insert_action_markup(
            Handle completion, int index, String markup);

    native static final protected void gtk_entry_completion_delete_action(
            Handle completion, int index);

    native static final protected void gtk_entry_completion_set_inline_completion(
            Handle completion, boolean inline);

    native static final protected boolean gtk_entry_completion_get_inline_completion(
            Handle completion);

    native static final protected void gtk_entry_completion_set_popup_completion(
            Handle completion, boolean popup);

    native static final protected boolean gtk_entry_completion_get_popup_completion(
            Handle completion);

    native static final protected void gtk_entry_completion_set_text_column(
            Handle completion, int column);

    native static final protected int gtk_entry_completion_get_text_column(
            Handle completion);

    // New in 2.8
    native static final protected void gtk_entry_completion_set_popup_set_width(
            Handle completion, boolean popupSetWidth);

    native static final protected boolean gtk_entry_completion_get_popup_set_width(
            Handle completion);

}
