/*
 * 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.gnome;

import java.util.Vector;

import org.gnu.glib.EventMap;
import org.gnu.glib.GObject;
import org.gnu.glib.Type;
import org.gnu.gnome.event.AppBarEvent;
import org.gnu.gnome.event.AppBarListener;
import org.gnu.gtk.HBox;
import org.gnu.gtk.ProgressBar;
import org.gnu.gtk.event.GtkEventType;
/**
 * The AppBar widget is a progress bar with a textual annotation.
 */
public class AppBar extends HBox {
	/**
	 * Listeners for handling AppBar events
	 */
	private Vector appBarListeners = null;

	/**
	 * Creates new instance of AppBar.
	 */
	public AppBar(boolean hasProgress, boolean hasStatus, PreferencesType type) {
		super(gnome_appbar_new(hasProgress, hasStatus, type.getValue()));
		initializeEventHandlers();
	}

	/**
	 * Construct an AppBar using a handle to a native resource.
	 */
	public AppBar(int handle) {
		super(handle);
	}

	/**
	 * Clears any prompt.
	 * @see #setPrompt(String, boolean)
	 */
	public void clearPrompt() {
		gnome_appbar_clear_prompt(getHandle());
	}

	/**
	 * Clears the stack.
	 */
	public void clearStack() {
		gnome_appbar_clear_stack(getHandle());
	}

	/**
	 * Returns the progress bar used by AppBar.
	 * @return The progress bar.
	 */
	public ProgressBar getProgressBar() {
		int hndl = gnome_appbar_get_progress(getHandle());
		GObject obj = retrieveGObject(hndl);
		if (null != obj)
			return (ProgressBar)obj;
		return new ProgressBar(hndl);
	}

	/**
	 * Gets the response to setPrompt
	 * @see #setPrompt(String, boolean)
	 * @return The user's response.
	 */
	public String getResponse() {
		return gnome_appbar_get_response(getHandle());
	}

	/**
	 * Pops the top status off the stack.  Calling this on an empty stack
	 * causes no problems.
	 */
	public void popStack() {
		gnome_appbar_pop(getHandle());
	}

	/**
	 * Pushes the status onto the stack.
	 * @param status The status text.  Not null.
	 */
	public void pushStack(String status) {
		gnome_appbar_push(getHandle(), status);
	}

	/**
	 * Refreshes to the current state of stack/default.  Useful for forcing the
	 * text set by a call to setStatusText to disappear.
	 */
	public void refresh() {
		gnome_appbar_refresh(getHandle());
	}

	/**
	 * Sets the percetage to show for progress.
	 */
	public void setProgressPercentage(double percentage) {
		gnome_appbar_set_progress_percentage(getHandle(), percentage);
	}

	/**
	 * Sets a prompt in the appbar and waits for a response.  When the user
	 * responds or cancels, a user_response signal is emitted.
	 * @param prompt The message used to prompt the user.
	 * @param modal True if all user input to the application should be blocked
	 *              until the user responds to the prompt or cancels.
	 */
	public void setPrompt(String prompt, boolean modal) {
		gnome_appbar_set_prompt(getHandle(), prompt, modal);
	}

	/**
	 * What to show when showing nothing else.  Defaults to nothing.
	 * @param status The text to use as default.  Not null.
	 */
	public void setStatusDefault(String status) {
		gnome_appbar_set_default(getHandle(), status);
	}

	/**
	 * Sets the status text without changing the widget state.  The next set
	 * or push will destroy this permanently.
	 * @param status The text to set.  Not null.
	 */
	public void setStatusText(String status) {
		gnome_appbar_set_status(getHandle(), status);
	}

	/**
	 * Retrieve the runtime type used by the GLib library.
	 */
	public static Type getType() {
		return new Type(gnome_appbar_get_type());
	}

	////////////////////////////////////
	// Event handling
	///////////////////////////////////

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

	protected void fireAppBarEvent(AppBarEvent event) {
		if (null == appBarListeners) {
			return;
		}
		int size = appBarListeners.size();
		int i = 0;
		while (i < size) {
			AppBarListener abl = (AppBarListener)appBarListeners.elementAt(i);
			abl.appBarEvent(event);
			i++;
		}
	}

	private void handleUserResponse() {
		fireAppBarEvent(new AppBarEvent(this, AppBarEvent.Type.USER_RESPONSE));
	}

	private void handleClearPrompt() {
		fireAppBarEvent(new AppBarEvent(this, AppBarEvent.Type.CLEAR_PROMPT));
	}

	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("user_response", "handleUserResponse", AppBarEvent.Type.USER_RESPONSE, AppBarListener.class);
		anEvtMap.addEvent("clear_prompt", "handleClearPrompt", AppBarEvent.Type.CLEAR_PROMPT, AppBarListener.class);
	}

	/****************************************
	 * BEGINNING OF GENERATED CODE
	 ****************************************/
	native static final protected int gnome_appbar_get_type();
	native static final protected int gnome_appbar_new(boolean hasProgress, boolean hasStatus, int interactivity);
	native static final protected void gnome_appbar_set_status(int appbar, String status);
	native static final protected int gnome_appbar_get_status(int appbar);
	native static final protected void gnome_appbar_set_default(int appbar, String defaultStatus);
	native static final protected void gnome_appbar_push(int appbar, String status);
	native static final protected void gnome_appbar_pop(int appbar);
	native static final protected void gnome_appbar_clear_stack(int appbar);
	native static final protected void gnome_appbar_set_progress_percentage(int appbar, double percentage);
	native static final protected int gnome_appbar_get_progress(int appbar);
	native static final protected void gnome_appbar_refresh(int appbar);
	native static final protected void gnome_appbar_set_prompt(int appbar, String prompt, boolean modal);
	native static final protected void gnome_appbar_clear_prompt(int appbar);
	native static final protected String gnome_appbar_get_response(int appbar);
	/****************************************
	 * END OF GENERATED CODE
	 ****************************************/
}
