/*
 * 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.Color;
import org.gnu.glib.EventMap;
import org.gnu.gtk.event.ColorButtonEvent;
import org.gnu.gtk.event.ColorButtonListener;
import org.gnu.gtk.event.GtkEventType;

/**
 * The ColorButton is a widget in the form of a small button 
 * containing a swatch representing the current selected 
 * color. When the button is clicked, a ColorSelection dialog 
 * will open, allowing the user to select a color. The swatch 
 * will be updated to reflect the new color when the user finishes.
 */
public class ColorButton extends Button {

	/**
	 * Create a new ColorButton.
	 */
	public ColorButton() {
		super(gtk_color_button_new());
		initializeEventHandlers();
	}
	
	/**
	 * Create a new ColorButton initialized with the provided color.
	 * @param color A Color to set the current color with.
	 */
	public ColorButton(Color color) {
		super(gtk_color_button_new_with_color(color.getHandle()));
		initializeEventHandlers();
	}
	
	/**
	 * Set the current color for the widget.
	 * @param color
	 */
	public void setColor(Color color) {
		gtk_color_button_set_color(getHandle(), color.getHandle());
	}
	
	/**
	 * Returns the current color value.
	 * @return
	 */
	public Color getColor() {
		return new Color(gtk_color_button_get_color(getHandle()));
	}
	
	/**
	 * Sets the current opacity to be alpha
	 * @param alpha
	 */
	public void setAlpha(int alpha) {
		gtk_color_button_set_alpha(getHandle(), alpha);
	}
	
	/**
	 * Returns the current alpha value.
	 * @return
	 */
	public int getAlpha() {
		return gtk_color_button_get_alpha(getHandle());
	}
	
	/**
	 * Sets whether or not the ColorButton should use the alpha channel.
	 * @param useAlpha
	 */
	public void setUseAlpha(boolean useAlpha) {
		gtk_color_button_set_use_alpha(getHandle(), useAlpha);
	}
	
	/**
	 * Returns whether or not the ColorButton is using the alpha channel.
	 * @return
	 */
	public boolean getUseAlpha() {
		return gtk_color_button_get_use_alpha(getHandle());
	}
	
	/**
	 * Sets the color for the ColorSelectionDialog.
	 * @param title
	 */
	public void setTitle(String title) {
		gtk_color_button_set_title(getHandle(), title);
	}
	
	/**
	 * Returns the title from the ColorSelectionDialog.
	 * @return
	 */
	public String getTitle() {
		return gtk_color_button_get_title(getHandle());
	}
	
	/* **************************************
	 * EVENT LISTENERS
	 ****************************************/

	/**
	 * Listeners for handling dialog events
	 */
	private Vector cbListeners = null;

	/**
	 * Register an object to handle dialog events.
	 * @see ColorButtonListener
	 */
	public void addListener(ColorButtonListener listener) {
		// Don't add the listener a second time if it is in the Vector.
		int i = findListener(cbListeners, listener);
		if (i == -1) {
			if (null == cbListeners) {
				cbListeners = new Vector();
			}
			cbListeners.addElement(listener);
		}
	}
	
	/**
	 * Removes a listener
	 * @see #addListener(ColorButtonListener)
	 */
	public void removeListener(ColorButtonListener listener) {
		int i = findListener(cbListeners, listener);
		if (i > -1) {
			cbListeners.remove(i);
		}
		if (0 == cbListeners.size()) {
			cbListeners = null;
		}
	}

	protected void fireColorButtonEvent(ColorButtonEvent event) {
		if (null == cbListeners) {
			return;
		}
		int size = cbListeners.size();
		int i = 0;
		while (i < size) {
			ColorButtonListener cbl = (ColorButtonListener)cbListeners.elementAt(i);
			cbl.colorButtonEvent(event);
			i++;
		}
	}

	private void handleColorSet() {
		fireColorButtonEvent(new ColorButtonEvent(this, ColorButtonEvent.Type.COLOR_SET));
	}

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

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

	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("color_set", "handleColorSet", ColorButtonEvent.Type.COLOR_SET, ColorButtonListener.class);
	}

	/****************************************
	 * BEGINNING OF JNI CODE
	 ****************************************/
	native static final protected int gtk_color_button_get_type ();
	native static final protected int gtk_color_button_new();
	native static final protected int gtk_color_button_new_with_color(int color);
	native static final protected void gtk_color_button_set_color(int button, int color);
	native static final protected void gtk_color_button_set_alpha(int button, int alpha);
	native static final protected int gtk_color_button_get_color(int button);
	native static final protected int gtk_color_button_get_alpha(int button);
	native static final protected void gtk_color_button_set_use_alpha(int button, boolean useAlpha);
	native static final protected boolean gtk_color_button_get_use_alpha(int button);
	native static final protected void gtk_color_button_set_title(int button, String title);
	native static final protected String gtk_color_button_get_title(int button);                                                                                
	/****************************************
	 * END OF JNI CODE
	 ****************************************/
}
