/*
 * 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.glib.EventMap;
import org.gnu.glib.GObject;
import org.gnu.glib.Type;
import org.gnu.gtk.event.GtkEventType;
import org.gnu.gtk.event.ToolBarEvent;
import org.gnu.gtk.event.ToolBarListener;



/**
 * The ToolBar is used to construct a toolbar. It is the container
 * that controls the position of a set of icons that are mouse
 * sensitive.
 */
public class ToolBar extends Container {
	
	/**
	 * Create a new ToolBar
	 */
	public ToolBar() {
		super(gtk_toolbar_new());
		initializeEventHandlers();
	}
	
	public ToolBar(int hndl) {
		super(hndl);
		initializeEventHandlers();
	}
	
	/**
	 * Add a widget to the end of the toolbar.
	 * 
	 * @param widget The widget to add to the end of the ToolBar.
	 * @param tooltip The text for the tooltip for this item.
	 * @param helpText Context sensitive help about this item.
	 * 
	 * @deprecated
	 */
	public void appendWidget(Widget widget, String tooltip, String helpText) {
		ToolBar.gtk_toolbar_append_widget(getHandle(), widget.getHandle(), tooltip, helpText);
	}
	
	/**
	 * Add a widget to the beginning of the toolbar.
	 * 
	 * @param widget The widget to add to the beginning of the ToolBar.
	 * @param tooltip The text for the tooltip for this item.
	 * @param helpText Context sensitive help about this item.
	 * 
	 * @deprecated
	 */
	public void prependWidget(Widget widget, String tooltip, String helpText) {
		ToolBar.gtk_toolbar_prepend_widget(getHandle(), widget.getHandle(), tooltip, helpText);
	}
	
	/**
	 * Insert a Widget in the ToolBar at the given position
	 * 
	 * @param widget The widget to add to the ToolBar.
	 * @param tooltip The text for the tooltip for this item.
	 * @param helpText Context sensitive help about this item.
	 * @param index The location in the ToolBar to insert this Widget.
	 * 
	 * @deprecated
	 */
	public void insertWidget(Widget widget, String tooltip, String helpText, int index) {
		ToolBar.gtk_toolbar_insert_widget(getHandle(), widget.getHandle(), tooltip, helpText, index);
	}
	
	/**
	 * Add a space to the end of the ToolBar.
	 * 
	 * @deprecated
	 */
	public void appendSpace() {
		ToolBar.gtk_toolbar_append_space(getHandle());
	}
	
	/**
	 * Add a space to the beginning of the ToolBar.
	 * 
	 * @deprecated
	 */
	public void prependSpace() {
		ToolBar.gtk_toolbar_prepend_space(getHandle());
	}
	
	/**
	 * Insert a space in the ToolBar at the specified location.
	 * 
	 * @param position The location to insert the space.
	 * 
	 * @deprecated
	 */
	public void insertSpace(int position) {
		ToolBar.gtk_toolbar_insert_space(getHandle(), position);
	}
	
	/**
	 * Remove a space from the ToolBar.
	 * 
	 * @param position The position of the space to remove.
	 * 
	 * @deprecated
	 */
	public void removeSpace(int position) {
		ToolBar.gtk_toolbar_remove_space(getHandle(), position);
	}
	
	/**
	 * Set whether the ToolBar should appear horizontally or vertically.
	 * 
	 * @param orientation Specifies the direction of the ToolBar.
	 */
	public void setOrientation(Orientation orientation) {
		ToolBar.gtk_toolbar_set_orientation(getHandle(), orientation.getValue());
	}
	
	/**
	 * Alter the view of the ToolBar to display either icons only, text only,
	 * or both.
	 * 
	 * @param style Determines how to display the items.
	 */
	public void setStyle(ToolBarStyle style) {
		ToolBar.gtk_toolbar_set_style(getHandle(), style.getValue());
	}
	
	/**
	 * Sets if the tooltips of the ToolBar should be active or not.
	 * 
	 * @param enable Should the tooltips be enabled.
	 */
	public void setToolTips(boolean enable) {
		ToolBar.gtk_toolbar_set_tooltips(getHandle(), enable);
	}
	
	/**
	 * Sets the size of the stock icons in the ToolBar.
	 * 
	 * @param iconSize The size of the icons.
	 * 
	 * @deprecated
	 */
	public void setIconSize(IconSize iconSize) {
		ToolBar.gtk_toolbar_set_icon_size(getHandle(), iconSize.getValue());
	}

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

	/**
	 * Insert a ToolItem into the ToolBar at a specified position.  If position is 0
	 * then the item is prepended to the start of the ToolBar.  If position is negative
	 * then it is appended to the end of the ToolBar.
	 * @param item
	 * @param position
	 */
	public void insert(ToolItem item, int position) {
		gtk_toolbar_insert(getHandle(), item.getHandle(), position);
	}

	/**
	 * Return the position of an item on the ToolBar starting from 0.
	 * @param item
	 * @return
	 */
	public int getItemIndex(ToolItem item) {
		return gtk_toolbar_get_item_index(getHandle(), item.getHandle());
	}
	
	/**
	 * Return the number of items on the ToolBar.
	 * @return
	 */
	public int getNumItems() {
		return gtk_toolbar_get_n_items(getHandle());
	}

	/**
	 * Return the ToolItem on the ToolBar from the position specified.
	 * @param position
	 * @return
	 */
	public ToolItem getItem(int position) {
		int hndl = gtk_toolbar_get_nth_item(getHandle(), position);
		GObject obj = retrieveGObject(hndl);
		if (null != obj)
			return (ToolItem)obj;
		return new ToolItem(hndl);
	}

	/**
	 * Returns whether the ToolBar has an overflow menu.
	 * @return
	 */
	public boolean getShowArrow() {
		return gtk_toolbar_get_show_arrow(getHandle());
	}

	/**
	 * Sets whether to show an overflow menu when ToolBar doesn't
	 * have room for all of its' items. 
	 * @param showArrow
	 */
	public void setShowArrow(boolean showArrow) {
		gtk_toolbar_set_show_arrow(getHandle(), showArrow);
	}

	/**
	 * Returns the ReliefStyle of Buttons on the ToolBar.
	 * @return
	 */

	public ReliefStyle getReliefStyle() {
		return ReliefStyle.intern(gtk_toolbar_get_relief_style(getHandle()));
	}

	/**
	 * Returns the position corresponding to the indicated point on ToolBar.
	 * This is useful when dragging items to the ToolBar: this functions returns
	 * the position a new item would be inserted. 
	 * @param x
	 * @param y
	 * @return
	 */
	public int getDropIndex(int x, int y) {
		return gtk_toolbar_get_drop_index(getHandle(), x, y);
	}

	/**
	 * Highlights ToolBar to give an idea of what it would look like if a ToolItem was
	 * added to the ToolBar and the provided index. 
	 * @param item
	 * @param index
	 */
	public void setDropHighlightItem(ToolItem item, int index) {
		gtk_toolbar_set_drop_highlight_item(getHandle(), item.getHandle(), index);
	}
	
	
	/***************************************
	 * EVENT LISTENERS
	 ****************************************/

	/**
	 * Listeners for handling events
	 */
	private Vector tbListeners = null;

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

	protected void fireToolBarEvent(ToolBarEvent event) {
		if (null == tbListeners) {
			return;
		}
		int size = tbListeners.size();
		int i = 0;
		while (i < size) {
			ToolBarListener tbl = (ToolBarListener)tbListeners.elementAt(i);
			tbl.toolBarEvent(event);
			i++;
		}
	}

	private void handleOrientationChange(int orientation) {
		ToolBarEvent evt = new ToolBarEvent(this, ToolBarEvent.Type.ORIENTATION_CHANGED);
		evt.setOrientation(Orientation.intern(orientation));
		fireToolBarEvent(evt);
	}
	
	private void handleStyleChange(int style) {
		ToolBarEvent evt = new ToolBarEvent(this, ToolBarEvent.Type.STYLE_CHANGED);
		evt.setStyle(ToolBarStyle.intern(style));
		fireToolBarEvent(evt);
	}
	
	private boolean handlePopupContextMenu(int x, int y, int button) {
		ToolBarEvent evt = new ToolBarEvent(this, ToolBarEvent.Type.POPUP_CONTEXT_MENU);
		evt.setX(x);
		evt.setY(y);
		evt.setButtonNumber(button);
		fireToolBarEvent(evt);
		return true;
	}

	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("orientation_changed", "handleOrientationChange", ToolBarEvent.Type.ORIENTATION_CHANGED, ToolBarListener.class);
		anEvtMap.addEvent("style_changed", "handleStyleChange", ToolBarEvent.Type.STYLE_CHANGED, ToolBarListener.class);
		anEvtMap.addEvent("popup_context_menu", "handlePopupContextMenu", ToolBarEvent.Type.POPUP_CONTEXT_MENU, ToolBarListener.class);
	}

	/****************************************
	 * BEGINNING OF JNI CODE
	 ****************************************/
	native static final protected int gtk_toolbar_get_type();
	native static final protected int gtk_toolbar_new();
	native static final protected void gtk_toolbar_set_orientation(int toolbar, int orientation);
	native static final protected void gtk_toolbar_set_style(int toolbar, int style);
	native static final protected void gtk_toolbar_set_tooltips(int toolbar, boolean enable);
	native static final protected void gtk_toolbar_unset_style(int toolbar);
	native static final protected int gtk_toolbar_get_orientation(int toolbar);
	native static final protected int gtk_toolbar_get_style(int toolbar);
	native static final protected int gtk_toolbar_get_icon_size(int toolbar);
	native static final protected boolean gtk_toolbar_get_tooltips(int toolbar);
	
	// Deprecated Methods
	native static final protected void gtk_toolbar_append_space(int toolbar);
	native static final protected void gtk_toolbar_prepend_space(int toolbar);
	native static final protected void gtk_toolbar_insert_space(int toolbar, int position);
	native static final protected void gtk_toolbar_remove_space(int toolbar, int position);
	native static final protected void gtk_toolbar_append_widget(int Toolbar, int Widget, String tooltipText, String tooltipPrivateText);
	native static final protected void gtk_toolbar_prepend_widget(int Toolbar, int Widget, String tooltipText, String tooltipPrivateText);
	native static final protected void gtk_toolbar_insert_widget(int toolbar, int widget, String tooltipText, String tooltipPrivateText, int position);
	native static final protected void gtk_toolbar_set_icon_size(int toolbar, int iconSize);
	native static final protected void gtk_toolbar_unset_icon_size(int toolbar);
	
	// New Methods
	native static final protected void gtk_toolbar_insert(int toolbar, int item, int pos);
	native static final protected int gtk_toolbar_get_item_index(int toolbar, int item);
	native static final protected int gtk_toolbar_get_n_items(int toolbar);
	native static final protected int gtk_toolbar_get_nth_item(int toolbar, int pos);
	native static final protected boolean gtk_toolbar_get_show_arrow(int toolbar);
	native static final protected void gtk_toolbar_set_show_arrow(int toolbar, boolean show);
	native static final protected int gtk_toolbar_get_relief_style(int toolbar);
	native static final protected int gtk_toolbar_get_drop_index(int toolbar, int x, int y);
	native static final protected void gtk_toolbar_set_drop_highlight_item(int toolbar, int item, int index);
	/****************************************
	 * END OF JNI CODE
	 ****************************************/
}
