/*******************************************************************************
 * Copyright (c) 2005 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.ui.internal.handlers;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.IHandlerListener;
import org.eclipse.core.commands.IObjectWithState;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.State;
import org.eclipse.core.expressions.EvaluationResult;
import org.eclipse.core.expressions.Expression;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.IActionDelegate;
import org.eclipse.ui.IActionDelegate2;
import org.eclipse.ui.IActionDelegateWithEvent;
import org.eclipse.ui.IEditorActionDelegate;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.INullSelectionListener;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISources;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.internal.WorkbenchPlugin;

/**
 * <p>
 * This proxies an {@link IActionDelegate} so that it can impersonate an
 * {@link IHandler}.
 * </p>
 * <p>
 * This class is not intended for use outside of the
 * <code>org.eclipse.ui.workbench</code> plug-in.
 * </p>
 * 
 * @since 3.2
 */
public final class ActionDelegateHandlerProxy implements ISelectionListener,
		ISelectionChangedListener, INullSelectionListener, IHandler,
		IObjectWithState {

	/**
	 * The fake action that proxies all of the command-based services. This
	 * value is never <code>null</code>.
	 */
	private CommandLegacyActionWrapper action;

	/**
	 * The identifier of the actions to create as a wrapper to the command
	 * architecture. This value may be <code>null</code>.
	 */
	private String actionId;

	/**
	 * The command that will back the dummy actions exposed to this delegate.
	 * This value is never <code>null</code>.
	 */
	private ParameterizedCommand command;

	/**
	 * This is the current selection, as seen by this proxy.
	 */
	private ISelection currentSelection;

	/**
	 * The delegate, if it has been created yet.
	 */
	private IActionDelegate delegate;

	/**
	 * The name of the configuration element attribute which contains the
	 * information necessary to instantiate the real handler.
	 */
	private String delegateAttributeName;

	/**
	 * The configuration element from which the handler can be created. This
	 * value will exist until the element is converted into a real class -- at
	 * which point this value will be set to <code>null</code>.
	 */
	private IConfigurationElement element;

	/**
	 * The <code>enabledWhen</code> expression for the handler. Only if this
	 * expression evaluates to <code>true</code> (or the value is
	 * <code>null</code>) should we consult the handler.
	 */
	private final Expression enabledWhenExpression;

	/**
	 * A collection of objects listening to changes to this manager. This
	 * collection is <code>null</code> if there are no listeners.
	 */
	private transient ListenerList listenerList = null;

	/**
	 * The image style to use when selecting the images to display for this
	 * delegate. This value may be <code>null</code>, if the default style
	 * should be used.
	 */
	private final String style;

	/**
	 * The identifier of the view with which this delegate must be associated.
	 * This value is not <code>null</code> iff the delegate is an
	 * {@link IViewActionDelegate}.
	 */
	private final String viewId;

	/**
	 * The workbench window in which this delegate is active. This value is
	 * never <code>null</code>.
	 */
	private final IWorkbenchWindow window;

	/**
	 * Constructs a new instance of <code>ActionDelegateHandlerProxy</code>
	 * with all the information it needs to try to avoid loading until it is
	 * needed.
	 * 
	 * @param element
	 *            The configuration element from which the real class can be
	 *            loaded at run-time; must not be <code>null</code>.
	 * @param delegateAttributeName
	 *            The name of the attibute or element containing the action
	 *            delegate; must not be <code>null</code>.
	 * @param actionId
	 *            The identifier of the underlying action; may be
	 *            <code>null</code>.
	 * @param command
	 *            The command with which the action delegate will be associated;
	 *            must not be <code>null</code>.
	 * @param window
	 *            The workbench window in which this delegate will be active;
	 *            must not be <code>null</code>.
	 * @param style
	 *            The image style with which the icons are associated; may be
	 *            <code>null</code>.
	 * @param enabledWhenExpression
	 *            The name of the element containing the enabledWhen expression.
	 *            This should be a child of the
	 *            <code>configurationElement</code>. If this value is
	 *            <code>null</code>, then there is no enablement expression
	 *            (i.e., enablement will be delegated to the handler when
	 *            possible).
	 * @param viewId
	 *            The identifier of the view to which this proxy is bound; may
	 *            be <code>null</code> if this proxy is not for an
	 *            {@link IViewActionDelegate}.
	 */
	public ActionDelegateHandlerProxy(final IConfigurationElement element,
			final String delegateAttributeName, final String actionId,
			final ParameterizedCommand command, final IWorkbenchWindow window,
			final String style, final Expression enabledWhenExpression,
			final String viewId) {
		if (element == null) {
			throw new NullPointerException(
					"The configuration element backing a handler proxy cannot be null"); //$NON-NLS-1$
		}

		if (delegateAttributeName == null) {
			throw new NullPointerException(
					"The attribute containing the action delegate must be known"); //$NON-NLS-1$
		}

		if (window == null) {
			throw new NullPointerException(
					"The workbench window for a delegate must not be null"); //$NON-NLS-1$
		}

		this.element = element;
		this.enabledWhenExpression = enabledWhenExpression;
		this.delegateAttributeName = delegateAttributeName;
		this.window = window;
		this.command = command;
		this.actionId = actionId;
		this.style = style;
		this.viewId = viewId;
	}

	public final void addHandlerListener(final IHandlerListener handlerListener) {
		if (listenerList == null) {
			listenerList = new ListenerList(ListenerList.IDENTITY);
		}

		listenerList.add(handlerListener);
	}

	public void addState(String id, State state) {
		// TODO Auto-generated method stub

	}

	public final void dispose() {
		final IActionDelegate delegate = getDelegate();
		if (delegate instanceof IWorkbenchWindowActionDelegate) {
			final IWorkbenchWindowActionDelegate workbenchWindowDelegate = (IWorkbenchWindowActionDelegate) delegate;
			workbenchWindowDelegate.dispose();
		} else if (delegate instanceof IActionDelegate2) {
			final IActionDelegate2 delegate2 = (IActionDelegate2) delegate;
			delegate2.dispose();
		}
	}

	public final Object execute(final ExecutionEvent event) {
		final IAction action = getAction();
		if (loadDelegate() && (action != null)) {
			final Object trigger = event.getTrigger();
			final IActionDelegate delegate = getDelegate();

			// Attempt to update the selection.
			final Object applicationContext = event.getApplicationContext();
			if (applicationContext instanceof IEvaluationContext) {
				final IEvaluationContext context = (IEvaluationContext) applicationContext;
				final Object selectionObject = context
						.getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME);
				if (selectionObject instanceof ISelection) {
					currentSelection = (ISelection) selectionObject;
					delegate.selectionChanged(action, currentSelection);
				}
			}

			// Decide what type of delegate we have.
			if ((delegate instanceof IActionDelegate2)
					&& (trigger instanceof Event)) {
				// This supports Eclipse 2.1 to Eclipse 3.1.
				final IActionDelegate2 delegate2 = (IActionDelegate2) delegate;
				final Event triggeringEvent = (Event) trigger;
				delegate2.runWithEvent(action, triggeringEvent);
			} else if ((delegate instanceof IActionDelegateWithEvent)
					&& (trigger instanceof Event)) {
				// This supports Eclipse 2.0
				final IActionDelegateWithEvent delegateWithEvent = (IActionDelegateWithEvent) delegate;
				final Event triggeringEvent = (Event) trigger;
				delegateWithEvent.runWithEvent(action, triggeringEvent);
			} else {
				delegate.run(action);
			}
		}

		return null;
	}

	/**
	 * Retrieves the action corresponding to the currently active workbench
	 * window, if any.
	 * 
	 * @return The current action; <code>null</code> if there is no currently
	 *         active workbench window.
	 */
	private final CommandLegacyActionWrapper getAction() {
		if (action == null) {
			action = new CommandLegacyActionWrapper(actionId, command, style,
					window);
			action.addPropertyChangeListener(new IPropertyChangeListener() {
				public final void propertyChange(final PropertyChangeEvent event) {
					// TODO Update the state somehow.
				}
			});
		}
		return action;
	}

	/**
	 * Retrieves the delegate corresponding to the currently active workbench
	 * window, if any. This does not trigger loading of the delegate.
	 * 
	 * @return The current delegate; or <code>null</code> if none.
	 */
	private final IActionDelegate getDelegate() {
		return delegate;
	}

	public State getState(String stateId) {
		// TODO Auto-generated method stub
		return null;
	}

	public String[] getStateIds() {
		// TODO Auto-generated method stub
		return null;
	}

	public final void handleStateChange(final State state, final Object oldValue) {
		// TODO What should we do here?
	}

	/**
	 * Initialize the action delegate by calling its lifecycle method.
	 */
	private final boolean initDelegate() {
		final IWorkbenchPage page = window.getActivePage();
		final IWorkbenchPart activePart;
		final IEditorPart activeEditor;
		if (page == null) {
			activePart = null;
			activeEditor = null;
		} else {
			activePart = page.getActivePart();
			activeEditor = page.getActiveEditor();
		}
		final IActionDelegate delegate = getDelegate();
		final IAction action = getAction();
		
		// Check to see if the view delegate should be initialized.
		if ((viewId != null) && (page != null)
				&& (delegate instanceof IViewActionDelegate)) {
			final IViewPart viewPart = page.findView(viewId);
			if (viewPart == null) {
				return false;
			}
		}

		// Initialize the delegate.
		final ISafeRunnable runnable = new ISafeRunnable() {
			public final void handleException(final Throwable exception) {
				// Do nothing.
			}

			public final void run() {
				// Handle IActionDelegate2
				if (delegate instanceof IActionDelegate2) {
					final IActionDelegate2 delegate2 = (IActionDelegate2) delegate;
					delegate2.init(action);
				}

				// Handle IObjectActionDelegates
				if ((delegate instanceof IObjectActionDelegate)
						&& (activePart != null)) {
					final IObjectActionDelegate objectActionDelegate = (IObjectActionDelegate) delegate;
					objectActionDelegate.setActivePart(action, activePart);
				}

				// Handle IEditorActionDelegates
				if (delegate instanceof IEditorActionDelegate) {
					final IEditorActionDelegate editorActionDelegate = (IEditorActionDelegate) delegate;
					editorActionDelegate.setActiveEditor(action, activeEditor);
				}

				// Handle IViewActionDelegates
				if ((viewId != null) && (page != null)
						&& (delegate instanceof IViewActionDelegate)) {
					final IViewPart viewPart = page.findView(viewId);
					final IViewActionDelegate viewActionDelegate = (IViewActionDelegate) delegate;
					viewActionDelegate.init(viewPart);
				}

				// Handle IWorkbenchWindowActionDelegate
				if (delegate instanceof IWorkbenchWindowActionDelegate) {
					final IWorkbenchWindowActionDelegate workbenchWindowActionDelegate = (IWorkbenchWindowActionDelegate) delegate;
					workbenchWindowActionDelegate.init(window);
				}
			}
		};
		SafeRunner.run(runnable);
		return true;
	}

	public final boolean isEnabled() {
		final CommandLegacyActionWrapper action = getAction();
		if (enabledWhenExpression != null) {
			try {
				final IHandlerService service = (IHandlerService) window
						.getService(IHandlerService.class);
				final EvaluationResult result = enabledWhenExpression
						.evaluate(service.getCurrentState());
				if (result == EvaluationResult.TRUE) {
					return (action == null)
							|| action.isEnabledDisregardingCommand();
				}
			} catch (final CoreException e) {
				// We will just fall through an let it return false.
				final StringBuffer message = new StringBuffer(
						"An exception occurred while evaluating the enabledWhen expression for "); //$NON-NLS-1$
				if (element == null) {
					message.append(delegate);
				} else {
					message.append(element.getAttribute(delegateAttributeName));
				}
				message.append("' could not be loaded"); //$NON-NLS-1$
				final IStatus status = new Status(IStatus.WARNING,
						WorkbenchPlugin.PI_WORKBENCH, 0, e.getMessage(), e);
				WorkbenchPlugin.log(message.toString(), status);
			}

			return false;
		}

		return (action == null) || action.isEnabledDisregardingCommand();
	}

	public final boolean isHandled() {
		return true;
	}

	/**
	 * Checks if the declaring plugin has been loaded. This means that there
	 * will be no need to delay creating the delegate.
	 * 
	 * @return <code>true</code> if the bundle containing the delegate is
	 *         already loaded -- making it safe to load the delegate.
	 */
	private final boolean isSafeToLoadDelegate() {
		return false;
		// TODO This causes problem because some people expect their selections
		// to be a particular class.
		// final String bundleId = element.getNamespace();
		// return BundleUtility.isActive(bundleId);
	}

	/**
	 * Loads the delegate, if possible. If the delegate is loaded, then the
	 * member variables are updated accordingly.
	 * 
	 * @return <code>true</code> if the delegate is now non-null;
	 *         <code>false</code> otherwise.
	 */
	private final boolean loadDelegate() {
		// Try to load the delegate, if it hasn't been loaded already.
		if (delegate == null) {
			/*
			 * If this is an IViewActionDelegate, then check to see if we have a
			 * view ready yet. If not, then we'll have to wait.
			 */
			if (viewId != null) {
				final IWorkbenchPage activePage = window.getActivePage();
				if (activePage != null) {
					final IViewPart part = activePage.findView(viewId);
					if (part == null) {
						return false;
					}
				} else {
					return false;
				}
			}

			// Load the delegate.
			try {
				delegate = (IActionDelegate) element
						.createExecutableExtension(delegateAttributeName);
				if (initDelegate()) {
					element = null;
					delegateAttributeName = null;
					return true;
				}

				delegate = null;
				return false;

			} catch (final ClassCastException e) {
				final String message = "The proxied delegate was the wrong class"; //$NON-NLS-1$
				final IStatus status = new Status(IStatus.ERROR,
						WorkbenchPlugin.PI_WORKBENCH, 0, message, e);
				WorkbenchPlugin.log(message, status);
				return false;

			} catch (final CoreException e) {
				final String message = "The proxied delegate for '" //$NON-NLS-1$
						+ element.getAttribute(delegateAttributeName)
						+ "' could not be loaded"; //$NON-NLS-1$
				IStatus status = new Status(IStatus.ERROR,
						WorkbenchPlugin.PI_WORKBENCH, 0, message, e);
				WorkbenchPlugin.log(message, status);
				return false;
			}
		}

		return true;
	}

	/**
	 * Refresh the action enablement.
	 */
	private final void refreshEnablement() {
		final IActionDelegate delegate = getDelegate();
		final IAction action = getAction();
		if ((delegate != null) && (action != null)) {
			delegate.selectionChanged(action, currentSelection);
		}
	}

	public void removeHandlerListener(IHandlerListener handlerListener) {
		if (listenerList != null) {
			listenerList.remove(handlerListener);

			if (listenerList.isEmpty()) {
				listenerList = null;
			}
		}
	}

	public void removeState(String stateId) {
		// TODO Auto-generated method stub

	}

	private final void selectionChanged(final ISelection selection) {
		// Update selection.
		currentSelection = selection;
		if (currentSelection == null) {
			currentSelection = StructuredSelection.EMPTY;
		}

		// The selection is passed to the delegate as-is without
		// modification. If the selection needs to be modified
		// the action contributors should do so.

		// If the delegate can be loaded, do so.
		// Otherwise, just update the enablement.
		final IActionDelegate delegate = getDelegate();
		if (delegate == null && isSafeToLoadDelegate()) {
			loadDelegate();
		}
		refreshEnablement();
	}

	public final void selectionChanged(final IWorkbenchPart part,
			final ISelection selection) {
		selectionChanged(selection);

	}

	public final void selectionChanged(final SelectionChangedEvent event) {
		final ISelection selection = event.getSelection();
		selectionChanged(selection);
	}

	public final String toString() {
		final StringBuffer buffer = new StringBuffer();
		buffer.append("ActionDelegateHandlerProxy("); //$NON-NLS-1$
		buffer.append(getDelegate());
		if (element != null) {
			buffer.append(',');
			final String className = element
					.getAttribute(delegateAttributeName);
			buffer.append(className);
		}
		buffer.append(')');
		return buffer.toString();
	}
}
