/*******************************************************************************
 * Copyright (C) 2007 The University of Manchester
 *
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.t2.ui.menu;

import java.awt.Component;
import java.lang.ref.WeakReference;
import java.net.URI;
import java.util.List;

import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JToolBar;

import uk.org.taverna.scufl2.api.core.Workflow;
import net.sf.taverna.t2.lang.observer.Observable;
import net.sf.taverna.t2.lang.observer.Observer;
import net.sf.taverna.t2.ui.menu.MenuComponent.MenuType;
import net.sf.taverna.t2.ui.menu.MenuManager.MenuManagerEvent;

/**
 * Create {@link JMenuBar}s and {@link JToolBar}s based on SPI instances of
 * {@link MenuComponent}.
 * <p>
 * Elements of menus are discovered automatically using an {@link SPIRegistry}.
 * The elements specify their internal relationship through
 * {@link MenuComponent#getParentId()} and
 * {@link MenuComponent#getPositionHint()}. {@link MenuComponent#getType()}
 * specifies how the component is to be rendered or grouped.
 * <p>
 * The menu manager is {@link Observable}, you can
 * {@linkplain #addObserver(Observer) add an observer} to be notified when the
 * menus have changed, i.e. when {@link #update()} has been called, for instance
 * when the {@link SPIRegistry} (which the menu manager observes) has been
 * updated due to a plugin installation.
 * <p>
 * {@link #createMenuBar()} creates the default menu bar, ie. the menu bar
 * containing all the items with {@link DefaultMenuBar#DEFAULT_MENU_BAR} as
 * their parent. Alternate menu bars can be created using
 * {@link #createMenuBar(URI)}.
 * <p>
 * Similary {@link #createToolBar()} creates the default tool bar, containing
 * the items that has {@link DefaultToolBar#DEFAULT_TOOL_BAR} as their parent.
 * Alternate toolbars can be created using {@link #createToolBar(URI)}.
 * <p>
 * The menu manager keeps weak references to the created (published) menu bars
 * and tool bars, and will attempt to update them when {@link #update()} is
 * called.
 * <p>
 * See the package level documentation for more information about how to specify
 * menu elements.
 * 
 * @author Stian Soiland-Reyes
 */
public interface MenuManager extends Observable<MenuManagerEvent> {
	/**
	 * Add the items from the list of menu items to the parent menu with
	 * expansion sub-menus if needed.
	 * <p>
	 * If the list contains more than <tt>maxItemsInMenu</tt> items, a series of
	 * sub-menus will be created and added to the parentMenu instead, each
	 * containing a maximum of <tt>maxItemsInMenu</tt> items. (Note that if
	 * menuItems contains more than <tt>maxItemsInMenu*maxItemsInMenu</tt>
	 * items, there might be more than <tt>maxItemsInMenu</tt> sub-menus added
	 * to the parent).
	 * <p>
	 * The sub-menus are titled according to the {@link JMenuItem#getText()} of
	 * the first and last menu item it contains - assuming that they are already
	 * sorted.
	 * <p>
	 * The optional {@link ComponentFactory} headerItemFactory, if not
	 * <code>null</code>, will be invoked to create a header item that will be
	 * inserted on top of the sub-menus. This item does not count towards
	 * <tt>maxItemsInMenu</tt>.
	 * <p>
	 * Note that this is a utility method that does not mandate the use of the
	 * {@link MenuManager} structure for the menu.
	 * 
	 * @param menuItems
	 *            {@link JMenuItem}s to be inserted
	 * @param parentMenu
	 *            Menu to insert items to
	 * @param maxItemsInMenu
	 *            Maximum number of items in parent menu or created sub-menus
	 * @param headerItemFactory
	 *            If not <code>null</code>, a {@link ComponentFactory} to create
	 *            a header item to insert at top of created sub-menus
	 */
	abstract void addMenuItemsWithExpansion(List<JMenuItem> menuItems,
			JMenu parentMenu, int maxItemsInMenu,
			ComponentFactory headerItemFactory);

	/**
	 * Create a contextual menu for a selected object.
	 * <p>
	 * Items for the contextual menues are discovered in a similar to fashion as
	 * with {@link #createMenuBar()}, but using {@link DefaultContextualMenu} as
	 * the root.
	 * <p>
	 * Additionally, items implementing {@link ContextualMenuComponent} will be
	 * {@linkplain ContextualMenuComponent#setContextualSelection(Object, Object, Component)
	 * informed} about what is the current selection, as passed to this method.
	 * <p>
	 * Thus, the items can choose if they want to be
	 * {@link MenuComponent#isEnabled() visible} or not for a given selection,
	 * and return an action that is bound it to the selection.
	 * 
	 * @param parent
	 *            The parent object of the selected object, for instance a
	 *            {@link Workflow}.
	 * @param selection
	 *            The selected object which actions in the contextual menu
	 *            relate to, for instance a {@link Processor}
	 * @param relativeToComponent
	 *            A UI component which the returned {@link JPopupMenu} (and it's
	 *            actions) is to be relative to, for instance as a parent of
	 *            pop-up dialogues.
	 * @return An empty or populated {@link JPopupMenu} depending on the
	 *         selected objects.
	 */
	abstract JPopupMenu createContextMenu(Object parent, Object selection,
			Component relativeToComponent);

	/**
	 * Create the {@link JMenuBar} containing menu elements defining
	 * {@link DefaultMenuBar#DEFAULT_MENU_BAR} as their
	 * {@linkplain MenuComponent#getParentId() parent}.
	 * <p>
	 * A {@linkplain WeakReference weak reference} is kept in the menu manager
	 * to update the menubar if {@link #update()} is called (manually or
	 * automatically when the SPI is updated).
	 * 
	 * @return A {@link JMenuBar} populated with the items belonging to the
	 *         default menu bar
	 */
	abstract JMenuBar createMenuBar();

	/**
	 * Create the {@link JMenuBar} containing menu elements defining the given
	 * <code>id</code> as their {@linkplain MenuComponent#getParentId() parent}.
	 * <p>
	 * Note that the parent itself also needs to exist as a registered SPI
	 * instance og {@link MenuComponent#getType()} equal to
	 * {@link MenuType#menu}, for instance by subclassing {@link AbstractMenu}.
	 * <p>
	 * A {@linkplain WeakReference weak reference} is kept in the menu manager
	 * to update the menubar if {@link #update()} is called (manually or
	 * automatically when the SPI is updated).
	 * 
	 * @param id
	 *            The {@link URI} identifying the menu bar
	 * @return A {@link JMenuBar} populated with the items belonging to the
	 *         given parent id.
	 */
	abstract JMenuBar createMenuBar(URI id);

	/**
	 * Create the {@link JToolBar} containing elements defining
	 * {@link DefaultToolBar#DEFAULT_TOOL_BAR} as their
	 * {@linkplain MenuComponent#getParentId() parent}.
	 * <p>
	 * A {@linkplain WeakReference weak reference} is kept in the menu manager
	 * to update the toolbar if {@link #update()} is called (manually or
	 * automatically when the SPI is updated).
	 * 
	 * @return A {@link JToolBar} populated with the items belonging to the
	 *         default tool bar
	 */
	abstract JToolBar createToolBar();

	/**
	 * Create the {@link JToolBar} containing menu elements defining the given
	 * <code>id</code> as their {@linkplain MenuComponent#getParentId() parent}.
	 * <p>
	 * Note that the parent itself also needs to exist as a registered SPI
	 * instance of {@link MenuComponent#getType()} equal to
	 * {@link MenuType#toolBar}, for instance by subclassing
	 * {@link AbstractToolBar}.
	 * <p>
	 * A {@linkplain WeakReference weak reference} is kept in the menu manager
	 * to update the toolbar if {@link #update()} is called (manually or
	 * automatically when the SPI is updated).
	 * 
	 * @param id
	 *            The {@link URI} identifying the tool bar
	 * @return A {@link JToolBar} populated with the items belonging to the
	 *         given parent id.
	 */
	abstract JToolBar createToolBar(URI id);

	/**
	 * Get a menu item identified by the given URI.
	 * <p>
	 * Return the UI {@link Component} last created for a {@link MenuComponent},
	 * through {@link #createMenuBar()}, {@link #createMenuBar(URI)},
	 * {@link #createToolBar()} or {@link #createToolBar(URI)}.
	 * <p>
	 * For instance, if {@link #createMenuBar()} created a menu bar containing a
	 * "File" menu with {@link MenuComponent#getId() getId()} ==
	 * <code>http://example.com/menu#file</code>, calling:
	 * 
	 * <pre>
	 * Component fileMenu = getComponentByURI(URI
	 * 		.create(&quot;http://example.com/menu#file&quot;));
	 * </pre>
	 * 
	 * would return the {@link JMenu} last created for "File". Note that "last
	 * created" could mean both the last call to {@link #createMenuBar()} and
	 * last call to {@link #update()} - which could have happened because the
	 * SPI registry was updated. To be notified when
	 * {@link #getComponentByURI(URI)} might return a new Component because the
	 * menues have been reconstructed, {@linkplain #addObserver(Observer) add an
	 * observer} to the MenuManager.
	 * <p>
	 * If the URI is unknown, has not yet been rendered as a {@link Component},
	 * or the Component is no longer in use outside the menu manager's
	 * {@linkplain WeakReference weak references}, <code>null</code> is returned
	 * instead.
	 * 
	 * @see #getURIByComponent(Component)
	 * @param id
	 *            {@link URI} of menu item as returned by
	 *            {@link MenuComponent#getId()}
	 * @return {@link Component} as previously generated by
	 *         {@link #createMenuBar()}/{@link #createToolBar()}, or
	 *         <code>null</code> if the URI is unknown, or if the
	 *         {@link Component} no longer exists.
	 */
	public abstract Component getComponentByURI(URI id);

	/**
	 * Get the URI of the {@link MenuComponent} this menu/toolbar
	 * {@link Component} was created from.
	 * <p>
	 * If the component was created by the MenuManager, through
	 * {@link #createMenuBar()}, {@link #createMenuBar(URI)},
	 * {@link #createToolBar()} or {@link #createToolBar(URI)}, the URI
	 * identifying the defining {@link MenuComponent} is returned. This will be
	 * the same URI as returned by {@link MenuComponent#getId()}.
	 * <p>
	 * Note that if {@link #update()} has been invoked, the {@link MenuManager}
	 * might have rebuilt the menu structure and replaced the components since
	 * the given <code>component</code> was created. The newest
	 * {@link Component} for the given URI can be retrieved using
	 * {@link #getComponentByURI(URI)}.
	 * <p>
	 * If the component is unknown, <code>null</code> is returned instead.
	 * 
	 * @see #getComponentByURI(URI)
	 * @param component
	 *            {@link Component} that was previously created by the
	 *            {@link MenuManager}
	 * @return {@link URI} identifying the menu component, as returned by
	 *         {@link MenuComponent#getId()}, or <code>null</code> if the
	 *         component is unknown.
	 */
	abstract URI getURIByComponent(Component component);

	/**
	 * Update and rebuild the menu structure.
	 * <p>
	 * Rebuild menu structure as defined by the {@link MenuComponent}s retrieved
	 * from the MenuComponent {@link SPIRegistry}.
	 * <p>
	 * Rebuilds previously published menubars and toolbars created with
	 * {@link #createMenuBar()}, {@link #createMenuBar(URI)},
	 * {@link #createToolBar()} and {@link #createToolBar(URI)}. Note that the
	 * rebuild will do a removeAll() on the menubar/toolbar, so all components
	 * will be reconstructed. You can use {@link #getComponentByURI(URI)} to
	 * look up individual components within the menu and toolbars.
	 * <p>
	 * Note that the menu manager is observing the {@link SPIRegistry}, so if a
	 * plugin gets installed and the SPI registry is updated, this update method
	 * will be called by the SPI registry observer.
	 * <p>
	 * If there are several concurrent calls to {@link #update()}, the calls
	 * from the other thread will return immediately, while the first thread to
	 * get the synchronization lock on the menu manager will do the actual
	 * update. If you want to ensure that {@link #update()} does not return
	 * before the update has been performed fully, synchronize on the menu
	 * manager:
	 * 
	 * <pre>
	 * MenuManager menuManager = MenuManager.getInstance();
	 * synchronized (menuManager) {
	 * 	menuManager.update();
	 * }
	 * doSomethingAfterUpdateFinished();
	 * </pre>
	 */
	abstract void update();

	/**
	 * Abstract class for events sent to {@linkplain Observer observers} of the
	 * menu manager.
	 * 
	 * @see UpdatedMenuManagerEvent
	 * @author Stian Soiland-Reyes
	 */
	static abstract class MenuManagerEvent {
	}

	/**
	 * Event sent to observers registered by
	 * {@link MenuManager#addObserver(Observer)} when the menus have been
	 * updated, i.e. when {@link MenuManager#update()} has been called.
	 */
	static class UpdatedMenuManagerEvent extends MenuManagerEvent {
	}

	/**
	 * A factory for making {@link Component}s, in particular for making headers
	 * (like {@link JLabel}s) for
	 * {@link MenuManager#addMenuItemsWithExpansion(List, JMenu, int, ComponentFactory)}
	 */
	interface ComponentFactory {
		public Component makeComponent();
	}
}
