/*
 * 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.glib.Type;
import org.gnu.gtk.event.ColorSelectionEvent;
import org.gnu.gtk.event.ColorSelectionListener;
import org.gnu.gtk.event.GtkEventType;

/**
 * This widget displays color information in such a way that the user
 * can specify, with the mouse, any available color.
 * @see ColorSelectionDialog
 */
public class ColorSelection extends VBox {

	/**
	 * Creates a new gtk.ColorSelection.
	 */
	public ColorSelection() {
		super(gtk_color_selection_new ());
		initializeEventHandlers();
	}
	
	/**
	 * construct a ColorSelection from a handle to a native peer.
	 */
	public ColorSelection(int handle) {
	    super(handle);
	    initializeEventHandlers();
	}

	/**
	 * Sets the widget to have an opacity control
	 */
	public void setHasOpacity(boolean hasOpacity) {
		gtk_color_selection_set_has_opacity_control(getHandle(), hasOpacity);
	}

	/**
	 * Sets the current color to be color. The first time this is called, it 
	 * will also set the original color to be color too.
	 * @param color 
	 */
	public void setCurrentColor(Color color) {
		gtk_color_selection_set_current_color(getHandle(), color.getHandle());
	}

	/**
	 * Returns the color which is set in the widget
	 * @return the set colour
	 */
	public Color getCurrentColor() {
	    int colorHandle = gtk_color_selection_get_current_color(getHandle());
	    return new Color(colorHandle);
	}
	
	/**
	 * Sets the ColorSelection to use or not to use the opacity control.
	 * @param hasOpacity true if this widget can set the opacity.
	 */
	public void setHasOpacityControl(boolean hasOpacity) {
		gtk_color_selection_set_has_opacity_control(getHandle(), hasOpacity);
	}
	
	/**
	 * Determines whether the ColorSelection has an opacity control.
	 * @return true if the widget has the opacity control.
	 */
	public boolean getHasOpacityControl() {
		return gtk_color_selection_get_has_opacity_control(getHandle());
	}
	
	/**
	 * Shows and hides the palette based upon the value of hasPalette.
	 * @param hasPalette true if the palette should be visible.
	 */
	public void setHasPalette(boolean hasPalette) {
		gtk_color_selection_set_has_palette(getHandle(), hasPalette);
	}
	
	/**
	 * Determines whether the widget's palette is visible.
	 * @return true if the palette is visible.
	 */
	public boolean getHasPalette() {
		return gtk_color_selection_get_has_palette(getHandle());
	}
	
	/**
	 * Sets the current opacity to be <i>alpha</i>. The first time this
	 * is called it will also set the original opacity to be <i>alpha</i>
	 * too.
	 * @param alpha An integer between 0 and 65535.
	 */
	public void setCurrentAlpha(int alpha) {
		gtk_color_selection_set_current_alpha(getHandle(), alpha);
	}
	
	/**
	 * Returns the current opacity.
	 * @return An integer between 0 and 65535.
	 */
	public int getCurrentAlpha() {
		return gtk_color_selection_get_current_alpha(getHandle());
	}
	
	/**
	 * Sets the previous alpha value.
	 */
	public void setPreviousAlpha(int alpha) {
		gtk_color_selection_set_previous_alpha(getHandle(), alpha);
	}
	
	/**
	 * Returns the previous alpha value.
	 */
	public int getPreviousAlpha() {
		return gtk_color_selection_get_previous_alpha(getHandle());
	}
	
	/**
	 * Sets the previous color value.
	 */
	public void setPreviousColor(Color color) {
		gtk_color_selection_set_previous_color(getHandle(), color.getHandle());
	}
	
	/**
	 * Returns the previous color.
	 */
	public Color getPreviousColor() {
		int [] color = new int[1];
		gtk_color_selection_get_previous_color(getHandle(), color);
		return new org.gnu.gdk.Color(color[0]);
	}
	
	/**
	 * Retrieve the runtime type used by the GLib library.
	 */
	public static Type getType() {
		return new Type(gtk_color_selection_get_type());
	}

	/* **************************************
	 * EVENT LISTENERS
	 ****************************************/
	/**
	 * Listeners for handling dialog events
	 */
	private Vector csListeners = null;

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

	protected void fireColorSelectionEvent(ColorSelectionEvent event) {
		if (null == csListeners) {
			return;
		}
		int size = csListeners.size();
		int i = 0;
		while (i < size) {
			ColorSelectionListener csl = (ColorSelectionListener)csListeners.elementAt(i);
			csl.colorSelectionEvent(event);
			i++;
		}
	}

	private void handleColorChanged() {
		fireColorSelectionEvent(new ColorSelectionEvent(this, ColorSelectionEvent.Type.COLOR_CHANGED));
	}

	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_changed", "handleColorChanged", ColorSelectionEvent.Type.COLOR_CHANGED, ColorSelectionListener.class);
	}

	/****************************************
     * BEGINNING OF JNI CODE
     ****************************************/
    native static final protected int gtk_color_selection_get_type ();
    native static final protected int gtk_color_selection_new ();
    native static final protected boolean gtk_color_selection_get_has_opacity_control (int colorsel);
    native static final protected void gtk_color_selection_set_has_opacity_control (int colorsel,  boolean hasOpacity);
    native static final protected boolean gtk_color_selection_get_has_palette (int colorsel);
    native static final protected void gtk_color_selection_set_has_palette (int colorsel, boolean hasPalette);
    native static final protected void gtk_color_selection_set_current_color (int colorsel, int color);
    native static final protected void gtk_color_selection_set_current_alpha (int colorsel, int alpha);
    native static final protected int gtk_color_selection_get_current_color (int colorsel);
    native static final protected int gtk_color_selection_get_current_alpha (int colorsel);
    native static final protected void gtk_color_selection_set_previous_color (int colorsel, int color);
    native static final protected void gtk_color_selection_set_previous_alpha (int colorsel, int alpha);
    native static final protected void gtk_color_selection_get_previous_color (int colorsel, int [] color);
    native static final protected int gtk_color_selection_get_previous_alpha (int colorsel);
    native static final protected boolean gtk_color_selection_is_adjusting (int colorsel);
    native static final protected boolean gtk_color_selection_palette_from_string (String str, int [] color, int nColors);
    native static final protected String gtk_color_selection_palette_to_string (int color, int nColors);
    /****************************************
     * END OF JNI CODE
     ****************************************/
}

