/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.ui.synchronize;

import java.util.*;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.*;
import org.eclipse.jface.util.ListenerList;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.*;
import org.eclipse.team.internal.ui.synchronize.SynchronizePageConfiguration;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IKeyBindingService;
import org.eclipse.ui.actions.ActionGroup;

/**
 * Used to add one or more actions to the context menu, toolbar or view menu 
 * of an {@link ISynchronizePage}. An action group is added to a synchronize
 * page by adding the group to the {@link ISynchronizePageConfiguration} after
 * configuration has been created by the page but before the page is created. 
 * <p>
 * The life cycle of an action group is:
 * <ul>
 * <li>the <code>initialize(ISynchronizePageConfiguration}</code> method is
 * invoked before the methods to populate menus. This is done to give clients 
 * a change to create and initialize the actions of the action group.
 * <li>The <code>fillActionBars(IActionBars)</code> method is invoked
 * to populate the page's action bars (view menu and toolbar). It is
 * possible for the action bars to be missing one or more components
 * so clients are expected to check for <code>null</code> when accessing
 * the menus from the action bars.
 * <li>The <code>fillContextMenu(IMenuManager)</code> method is invoked each time
 * the context menu is shown. Before this method is called, the 
 * action group will be provided with an <code>ActionContext</code>
 * containing the view selection. Clients can access the context using
 * <code>getContext()</code>.
 * <li>The <code>updateActionBars()</code> method is invoked whenever the
 * page's selection changes. Before this method is called, the 
 * action group will be provided with an <code>ActionContext</code>
 * containing the view selection. Clients can access the context using
 * <code>getContext()</code>.
 * <li>The <code>modelChanged(ISynchronizeModelElement)</code> method is
 * invoked whenever the model being displayed is changed. This gives clients
 * a chance to adjust the input to actions that operate on all visible elements.
 * <li>The <code>dispose()</code> method is called when the page is disposed.
 * </ul>
 * </p>
 * @since 3.0
 */
public abstract class SynchronizePageActionGroup extends ActionGroup {

	private ISynchronizePageConfiguration configuration;
	
	private Map menuContributions = new HashMap();
	
	private VisibleRootsSelectionProvider visibleRootSelectionProvider;

	/*
	 * A selection provider whose selection is the root elements visible in the
	 * page. Selection changed events are sent out when the model roots change
	 * or their visible children change
	 */
	private class VisibleRootsSelectionProvider extends SynchronizePageActionGroup implements ISelectionProvider {

		private ListenerList selectionChangedListeners = new ListenerList();
		private ISelection selection;

		protected VisibleRootsSelectionProvider(ISynchronizeModelElement element) {
			modelChanged(element);
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.team.ui.synchronize.SynchronizePageActionGroup#modelChanged(org.eclipse.team.ui.synchronize.ISynchronizeModelElement)
		 */
		public void modelChanged(ISynchronizeModelElement root) {
			if (root == null) {
				setSelection(StructuredSelection.EMPTY);
			} else {
				setSelection(new StructuredSelection(root));
			}
		}
		
		/* (non-Javadoc)
		 * Method declared on ISelectionProvider.
		 */
		public void addSelectionChangedListener(ISelectionChangedListener listener) {
			selectionChangedListeners.add(listener);	
		}
		
		/* (non-Javadoc)
		 * Method declared on ISelectionProvider.
		 */
		public void removeSelectionChangedListener(ISelectionChangedListener listener) {
			selectionChangedListeners.remove(listener);
		}
		
		/* (non-Javadoc)
		 * Method declared on ISelectionProvider.
		 */
		public ISelection getSelection() {
			return selection;
		}
		
		/* (non-Javadoc)
		 * Method declared on ISelectionProvider.
		 */
		public void setSelection(ISelection selection) {
			this.selection = selection;
			selectionChanged(new SelectionChangedEvent(this, getSelection()));
		}
		
		private void selectionChanged(final SelectionChangedEvent event) {
			// pass on the notification to listeners
			Object[] listeners = selectionChangedListeners.getListeners();
			for (int i = 0; i < listeners.length; ++i) {
				final ISelectionChangedListener l = (ISelectionChangedListener)listeners[i];
				Platform.run(new SafeRunnable() {
					public void run() {
						l.selectionChanged(event);
					}
				});		
			}
		}
	}
	
	/**
	 * Initialize the actions of this contribution. This method will be invoked
	 * once before any calls are made to <code>filleContextMenu</code> or
	 * <code>setActionBars</code> but after the control for the page has been
	 * created. As a result of this, the site of the configuration can be
	 * accessed. Sublcasses may override this method but must invoke the
	 * overriden method.
	 * 
	 * @param configuration the configuration for the part to which the
	 * contribution is associated
	 */
	public void initialize(ISynchronizePageConfiguration configuration) {
		this.configuration = configuration;
		if (visibleRootSelectionProvider != null) {
			configuration.addActionContribution(visibleRootSelectionProvider);
		}
	}
	
	/**
	 * This method is invoked whenever the model being displayed in the view
	 * changes. This includes when the input to the view changes and when the
	 * children of the input change. The default implementation of this method
	 * does nothing. Subclasses may override.
	 * 
	 * @param root the root of the model being viewed
	 */
	public void modelChanged(ISynchronizeModelElement root) {
		// Do nothing by default
	}
	
	/** 
	 * Dispose of the action group. Subclasses may override but must
	 * invoke the overriden method.
	 */
	public void dispose() {
		super.dispose();
		if (configuration != null) {
			configuration.removeActionContribution(this);
		}
	}

	/**
	 * Helper method to find the group of the given id for the page associated
	 * with the configuration of this action group. The id of the returned group
	 * will not match that of the provided id since the group must be modified
	 * to ensure that groups are unique accross pages.
	 * 
	 * @param menu the menu
	 * @param groupId the id of the group being searched for
	 * @return the group for the given id or <code>null</code>
	 */
	protected IContributionItem findGroup(IContributionManager menu, String groupId) {
		if(menu == null) return null;
		IContributionItem item = menu.find(((SynchronizePageConfiguration)configuration).getGroupId(groupId));
		if (item == null) {
			// Context menus do not change the id
			item = menu.find(groupId);
		}
		return item;
	}
	
	/**
	 * Helper method to add an action to a group in a menu. The action is only
	 * added to the menu if the group exists in the menu. Calling this method
	 * also has no effect if either the menu or action are <code>null</code>.
	 * 
	 * @param manager the menu manager
	 * @param groupId the group to append the action to
	 * @param action the action to add
	 * @return <code>true</code> if the group exists and the action was added
	 * and <code>false</code> if the action was not added
	 */
	protected boolean appendToGroup(IContributionManager manager, String groupId, IAction action) {
		if (manager == null || action == null) return false;
		IContributionItem group = findGroup(manager, groupId);
		if (group != null) {
			manager.appendToGroup(group.getId(), action);
			registerActionWithWorkbench(action);
			return true;
		}
		return false;
	}
	
	/**
	 * Helper method to add a contribution item to a group in a menu. The item
	 * is only added to the menu if the group exists in the menu. Calling this
	 * method also has no effect if either the menu or item are
	 * <code>null</code>.
	 * 
	 * @param manager the menu manager
	 * @param groupId the group to append the action to
	 * @param item the item to add
	 * @return <code>true</code> if the group exists and the action was added
	 * and <code>false</code> if the action was not added
	 */
	protected boolean appendToGroup(IContributionManager manager, String groupId, IContributionItem item) {
		if (manager == null || item == null) return false;
		IContributionItem group = findGroup(manager, groupId);
		if (group != null) {
			manager.appendToGroup(group.getId(), item);
			return true;
		}
		return false;
	}
	
	/**
	 * Helper method that can be invoked during initialization to add an action
	 * to a particular menu (one of P_TOOLBAR_MENU, P_VIEW_MENU, P_CONTEXT_MENU
	 * from ISynchronizePageConfiguration). The action is added to the given
	 * group if it is present. Otherwise the action is not added to the menu.
	 * 
	 * @param menuId the menu id (one of P_TOOLBAR_MENU, P_VIEW_MENU,
	 * P_CONTEXT_MENU from ISynchronizePageConfiguration)
	 * @param groupId the group id in the menu to which the action is to be
	 * added
	 * @param action the action to be added
	 */
	protected void appendToGroup(String menuId, String groupId, IAction action) {
		registerActionWithWorkbench(action);
		internalAppendToGroup(menuId, groupId, action);
	}
	
	/**
	 * Register this action with the workbench so that it can participate in keybindings and
	 * retargetable actions.
	 * 
	 * @param action the action to register
	 */
	private void registerActionWithWorkbench(IAction action) {
		ISynchronizePageSite site = configuration.getSite();
		site.getActionBars().setGlobalActionHandler(action.getId(), action);
		IKeyBindingService keyBindingService = site.getKeyBindingService();
		if(keyBindingService != null)
			keyBindingService.registerAction(action);
	}

	/**
	 * Helper method that can be invoked during initialization to add an item to
	 * a particular menu (one of P_TOOLBAR_MENU, P_VIEW_MENU, P_CONTEXT_MENU
	 * from ISynchronizePageConfiguration). The item is added to the given group
	 * if it is present. Otherwise the item is not added to the menu.
	 * 
	 * @param menuId the menu id (one of P_TOOLBAR_MENU, P_VIEW_MENU,
	 * P_CONTEXT_MENU from ISynchronizePageConfiguration)
	 * @param groupId the group id in the menu to which the item is to be added
	 * @param item the item to be added
	 */
	protected void appendToGroup(String menuId, String groupId, IContributionItem item) {
		internalAppendToGroup(menuId, groupId, item);
	}
	
	/**
	 * Return a selection provider whose selection includes all roots of the
	 * elements visible in the page. Selection change events are fired when the
	 * elements visible in the view change.
	 * 
	 * @return a selection provider whgose selection is the roots of all
	 * elements visible in the page
	 */
	protected ISelectionProvider getVisibleRootsSelectionProvider() {
		if (visibleRootSelectionProvider == null) {
			ISynchronizeModelElement root = null;
			if (configuration != null) {
				root = (ISynchronizeModelElement)configuration.getProperty(SynchronizePageConfiguration.P_MODEL);
			}
			visibleRootSelectionProvider = new VisibleRootsSelectionProvider(root);
			if (configuration != null) {
				configuration.addActionContribution(visibleRootSelectionProvider);
			}
		}
		return visibleRootSelectionProvider;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.actions.ActionGroup#fillContextMenu(org.eclipse.jface.action.IMenuManager)
	 */
	public void fillContextMenu(IMenuManager menu) {
		super.fillContextMenu(menu);
		fillMenu(menu, ISynchronizePageConfiguration.P_CONTEXT_MENU);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.actions.ActionGroup#fillActionBars(org.eclipse.ui.IActionBars)
	 */
	public void fillActionBars(IActionBars actionBars) {
		super.fillActionBars(actionBars);
		if (actionBars != null) {
			fillMenu(actionBars.getMenuManager(), ISynchronizePageConfiguration.P_VIEW_MENU);
			fillMenu(actionBars.getToolBarManager(), ISynchronizePageConfiguration.P_TOOLBAR_MENU);
		}
	}
	
	private void fillMenu(IContributionManager menu, String menuId) {
		Map groups = (Map)menuContributions.get(menuId);
		if (menu != null && groups != null) {
			for (Iterator iter = groups.keySet().iterator(); iter.hasNext(); ) {
				String groupId = (String) iter.next();
				List actions = (List)groups.get(groupId);
				if (actions != null) {
					for (Iterator iter2 = actions.iterator(); iter2.hasNext();) {
						Object element = iter2.next();
						if (element instanceof IAction) {
							appendToGroup(menu, groupId, (IAction)element);
						} else if (element instanceof IContributionItem) {
							appendToGroup(menu, groupId, (IContributionItem)element);
						}
					}
				}
			}
		}
	}

	private void internalAppendToGroup(String menuId, String groupId, Object action) {
		Map groups = (Map)menuContributions.get(menuId);
		if (groups == null) {
			groups = new HashMap();
			menuContributions.put(menuId, groups);
		}
		List actions = (List)groups.get(groupId);
		if (actions == null) {
			actions = new ArrayList();
			groups.put(groupId, actions);
		}
		actions.add(action);
	}
	
	/**
	 * Return the configuration for the page to which the action group
	 * is associated.
	 * @return the configuration for the page to which the action group
	 * is associated
	 * 
	 * @since 3.1
	 */
    public ISynchronizePageConfiguration getConfiguration() {
        return configuration;
    }
}
