/*
 * 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.gdk.Event;
import org.gnu.glib.EventMap;
import org.gnu.glib.EventType;
import org.gnu.glib.GObject;
import org.gnu.glib.Handle;
import org.gnu.glib.Type;
import org.gnu.gtk.event.CellEditableEvent;
import org.gnu.gtk.event.CellEditableListener;

public class CellEditable extends GObject 
{
	public CellEditable() {
		super(newObject());
	}
	
	/**
	 * Retrieve the runtime type used by the GLib library.
	 */
	public static Type getType() {
		return new Type(gtk_cell_editable_get_type());
	}
	
	public void startEditing(Event event) {
		gtk_cell_editable_start_editing(getHandle(), event.getHandle());
	}
	
	public void editingDone() {
		gtk_cell_editable_editing_done(getHandle());
	}
	
	public void removeWidget() {
		gtk_cell_editable_remove_widget(getHandle());
	}
	
	/***************************************
	 * Event Handler Related code
	 ****************************************/

	/**
	 * Listeners for handling toggle events
	 */
	private Vector listeners = null;
	/**
	 * Register an object to handle button events.
	 * @see org.gnu.gtk.event.CellEditableListener
	 */
	public void addListener(CellEditableListener listener) {
		// Don't add the listener a second time if it is in the Vector.
		int i = findListener(listeners, listener);
		if (i == -1) {
			if (null == listeners) {
				evtMap.initialize(this, CellEditableEvent.Type.EDITING_DONE);
				evtMap.initialize(this, CellEditableEvent.Type.REMOVE_WIDGET);
				listeners = new Vector();
			}
			listeners.addElement(listener);
		}
	}
	/**
	 * Removes a listener
	 * @see #addListener(CellEditableListener)
	 */
	public void removeListener(CellEditableListener listener) {
		int i = findListener(listeners, listener);
		if (i > -1) {
			listeners.remove(i);
		}
		if (0 == listeners.size()) {
			evtMap.uninitialize(this, CellEditableEvent.Type.EDITING_DONE);
			evtMap.uninitialize(this, CellEditableEvent.Type.REMOVE_WIDGET);
			listeners = null;
		}
	}

	/**
	 * 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.
	 */
	protected static int findListener(Vector list, Object listener) {
		if (null == list || null == listener)
			return -1;
		return list.indexOf(listener);
	}

	protected void fireCellEditableEvent(CellEditableEvent event) {
		if (null == listeners) {
			return;
		}
		int size = listeners.size();
		int i = 0;
		while (i < size) {
			CellEditableListener lis = (CellEditableListener)listeners.elementAt(i);
			lis.cellEditableEvent(event);
			i++;
		}
	}

	private void handleEditingDone() {
		CellEditableEvent event = new CellEditableEvent(this, CellEditableEvent.Type.EDITING_DONE);
		fireCellEditableEvent(event);
	}

	private void handleRemoveWidget() {
		CellEditableEvent event = new CellEditableEvent(this, CellEditableEvent.Type.REMOVE_WIDGET);
		fireCellEditableEvent(event);
	}

	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.
	*/
	private static void addEvents(EventMap anEvtMap) {
		anEvtMap.addEvent("editing_done", "handleEditingDone", CellEditableEvent.Type.EDITING_DONE, CellEditableListener.class);
		anEvtMap.addEvent("remove_widget", "handleRemoveWidget", CellEditableEvent.Type.REMOVE_WIDGET, CellEditableListener.class);
	}


	native static final protected Handle newObject();
    native static final protected int gtk_cell_editable_get_type ();
    native static final protected void gtk_cell_editable_start_editing (Handle cellEditable, Handle event);
    native static final protected void gtk_cell_editable_editing_done (Handle cellEditable);
    native static final protected void gtk_cell_editable_remove_widget (Handle cellEditable);

}

