/*
 * 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.Iterator;
import java.util.Vector;

import org.gnu.glib.EventMap;
import org.gnu.glib.EventType;
import org.gnu.glib.Type;
import org.gnu.gtk.event.CellRendererToggleEvent;
import org.gnu.gtk.event.CellRendererToggleListener;
import org.gnu.glib.Handle;

/**
 * The CellRendererToggle is a {@link CellRenderer} for boolean data.
 *
 * @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.CellRendererToggle</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 CellRendererToggle extends CellRenderer {
    private static EventMap evtMap = new EventMap();

    static {
        addEvents(evtMap);
    }

    // we use a set so we don't have repeated elements on the list
    private Vector listeners = null;

    /**
     * Constructs a new Cell Renderer.
     * @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 CellRendererToggle() {
        super(gtk_cell_renderer_toggle_new());
    }

    /**
     * If radio is TRUE, the cell renderer renders a radio toggle (ie a toggle
     * in a group of mutually-exclusive toggles). If FALSE, it renders a check
     * toggle (a standalone boolean option). This can be set globally for the
     * cell renderer, or changed just before rendering each cell in the model
     * (for {@link TreeView}, you set up a per-row setting using {@link
     * TreeViewColumn} to associate model columns with cell renderer
     * properties).
     * 
     * @param radio
     *            TRUE to make the toggle look like a radio button
     * @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 setRadio(boolean radio) {
        gtk_cell_renderer_toggle_set_radio(getHandle(), radio);
    }

    /**
     * Sets whether all cells are toggled. You will usually want to do this
     * based on data in the model, using {@link
     * TreeViewColumn#addAttributeMapping(CellRenderer, CellRendererAttribute,
     * DataColumn)} with the {@link CellRendererToggle.Attribute#ACTIVE}
     * attribute.
     * 
     * @param toggled
     *            If true, all cells will be toggled, or cheked.
     * @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 setToggled(boolean toggled) {
        gtk_cell_renderer_toggle_set_active(getHandle(), toggled);
    }

    /**
     * Sets whether the user can change the toggled status of the cell. This
     * method will change the setting for all cells. It can be set on a cell by
     * cell basis by including the data in the model and attaching the {@link
     * CellRendererToggle.Attribute#ACTIVATABLE} property, using the {@link
     * TreeViewColumn#addAttributeMapping(CellRenderer, CellRendererAttribute,
     * DataColumn)} property
     * 
     * @param setting
     *            If true, the value of all cells may be changed.
     * @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 setUserEditable(boolean setting) {
        setActivatable(getHandle(), setting);
    }

    /** Attributes for mapping to data in the TreeModel */
    public static class Attribute extends CellRenderer.Attribute {
        private Attribute(String attr) {
            super(attr);
        }

        /** The state of the toggle */
        public static final Attribute ACTIVE = new Attribute("active");

        /** Whether the user can change the state of the toggle */
        public static final Attribute ACTIVATABLE = new Attribute("activatable");

        /** The inconsistent state of the button. */
        public static final Attribute INCONSISTENT = new Attribute(
                "inconsistent");

        /** Draw the toggle button as a radio button. */
        public static final Attribute RADIO = new Attribute("radio");
    }

    /**
     * Retrieve the runtime type used by the GLib library.
     * @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 Type getType() {
        return new Type(gtk_cell_renderer_toggle_get_type());
    }

    private static void addEvents(EventMap anEvtMap) {
        anEvtMap.addEvent("toggled", "handleToggled",
                CellRendererToggleEvent.Type.TOGGLED,
                CellRendererToggleListener.class);
    }

    private void handleToggled(String arg) {
        fireCellRendererToggleEvent(new CellRendererToggleEvent(this, arg));
    }

    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;
    }

    public void fireCellRendererToggleEvent(CellRendererToggleEvent evt) {
        final Iterator i = listeners.iterator();
        while (i.hasNext())
            ((CellRendererToggleListener) i.next())
                    .cellRendererToggleEvent(evt);
    }

    /**
     * Register an object to handle CellRendererToggle events.
     * 
     * @see org.gnu.gtk.event.CellRendererTextListener
     * @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(CellRendererToggleListener l) {
        int i = Widget.findListener(listeners, l);
        if (i == -1) {
            if (null == listeners) {
                evtMap.initialize(this, CellRendererToggleEvent.Type.TOGGLED);
                listeners = new Vector();
            }
            listeners.addElement(l);
        }
    }

    /**
     * Removes a listener.
     * 
     * @see #addListener(CellRendererToggleListener)
     * @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(CellRendererToggleListener l) {
        int i = Widget.findListener(listeners, l);
        if (i > -1)
            listeners.remove(i);
        if (0 == listeners.size()) {
            evtMap.uninitialize(this, CellRendererToggleEvent.Type.TOGGLED);
            listeners = null;
        }
    }

    native static final protected void setActivatable(Handle toggle,
            boolean setting);

    native static final protected int gtk_cell_renderer_toggle_get_type();

    native static final protected Handle gtk_cell_renderer_toggle_new();

    native static final protected boolean gtk_cell_renderer_toggle_get_radio(
            Handle toggle);

    native static final protected void gtk_cell_renderer_toggle_set_radio(
            Handle toggle, boolean radio);

    native static final protected boolean gtk_cell_renderer_toggle_get_active(
            Handle toggle);

    native static final protected void gtk_cell_renderer_toggle_set_active(
            Handle toggle, boolean setting);

}
