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

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

/**
 * The CellRendererToggle is a {@link CellRenderer} for boolean data. 
 */
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 Set listeners = new java.util.HashSet();

	/**
	 * Constructs a new Cell Renderer.
	 */
	public CellRendererToggle() {
		super(gtk_cell_renderer_toggle_new());
		initializeEventHandlers();
	}

	/**
	 * If radio is TRUE, the cell renderer renders a radio toggle (i.e. 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
	 */
	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,
	 * int)} with the {@link CellRendererToggle.Attribute#ACTIVE} attribute.
	 * @param toggled If true, all cells will be toggled, or cheked.
	 */
	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,
	 * int)} property
	 * @param setting If true, the value of all cells may be changed.
	 */
	public void setUserEditable(boolean setting) {
		setActivatable(getHandle(), setting);
	}

	/** Attributes for mapping to data in the TreeModel */
	public static class Attribute extends CellRendererAttribute {
		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.
	 */
	public static Type getType() {
		return new Type(gtk_cell_renderer_toggle_get_type());
	}

	protected void initializeEventHandlers() {
		if (!eventsInitialized) {
			evtMap.initialize(this);
			eventsInitialized = true;
		}
	}

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

	private void handleTogled(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 GtkEventType getEventType(String signal) {
		GtkEventType 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
	 */
	public void addListener(CellRendererToggleListener l) {
		listeners.add(l);
	}
	/**
	 * Removes a listener
	 * @see #addCellRendererToggleListener(CellRendererToggleListener)
	 */
	public void removeListener(CellRendererToggleListener l) {
		listeners.remove(l);
	}

	native static final protected void setActivatable(int toggle, boolean setting);
	/****************************************
	 * BEGINNING OF GENERATED CODE
	 ****************************************/
	native static final protected int gtk_cell_renderer_toggle_get_type();
	native static final protected int gtk_cell_renderer_toggle_new();
	native static final protected boolean gtk_cell_renderer_toggle_get_radio(int toggle);
	native static final protected void gtk_cell_renderer_toggle_set_radio(int toggle, boolean radio);
	native static final protected boolean gtk_cell_renderer_toggle_get_active(int toggle);
	native static final protected void gtk_cell_renderer_toggle_set_active(int toggle, boolean setting);
	/****************************************
	 * END OF GENERATED CODE
	 ****************************************/
}
