/*******************************************************************************
 * Copyright (c) 2005, 2006 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.core.commands.operations;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;

/**
 * Triggered operations are a specialized implementation of a composite
 * operation that keeps track of operations triggered by the execution of some
 * primary operation. The composite knows which operation was the trigger for
 * subsequent operations, and adds all triggered operations as children. When
 * execution, undo, or redo is performed, only the triggered operation is
 * executed, undone, or redone if it is still present. If the trigger is removed
 * from the triggered operations, then the child operations will replace the
 * triggered operations in the history.
 * <p>
 * This class may be instantiated by clients.
 * </p>
 * 
 * @since 3.1
 */
public final class TriggeredOperations extends AbstractOperation implements
		ICompositeOperation, IAdvancedUndoableOperation,
		IContextReplacingOperation {

	private IUndoableOperation triggeringOperation;

	private IOperationHistory history;

	private List children = new ArrayList();

	/**
	 * Construct a composite triggered operations using the specified undoable
	 * operation as the trigger. Use the label of this trigger as the label of
	 * the operation.
	 * 
	 * @param operation
	 *            the operation that will trigger other operations.
	 * @param history
	 *            the operation history containing the triggered operations.
	 */
	public TriggeredOperations(IUndoableOperation operation,
			IOperationHistory history) {
		super(operation.getLabel());
		triggeringOperation = operation;
		recomputeContexts();
		this.history = history;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IUndoableOperation#add(org.eclipse.core.commands.operations.IUndoableOperation)
	 */
	public void add(IUndoableOperation operation) {
		children.add(operation);
		recomputeContexts();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IUndoableOperation#remove(org.eclipse.core.commands.operations.IUndoableOperation)
	 */
	public void remove(IUndoableOperation operation) {
		if (operation == triggeringOperation) {
			// the triggering operation is being removed, so we must replace
			// this composite with its individual triggers.
			triggeringOperation = null;
			// save the children before replacing the operation, since this
			// operation will be disposed as part of replacing it. We don't want
			// the children to be disposed since they are to replace this
			// operation.
			List childrenToRestore = new ArrayList(children);
			children = new ArrayList(0);
			recomputeContexts();
			operation.dispose();
			// now replace the triggering operation
			history.replaceOperation(this,
					(IUndoableOperation[]) childrenToRestore
							.toArray(new IUndoableOperation[childrenToRestore
									.size()]));
		} else {
			children.remove(operation);
			operation.dispose();
			recomputeContexts();
		}
	}

	/**
	 * Remove the specified context from the receiver. This method is typically
	 * invoked when the history is being flushed for a certain context. In the
	 * case of triggered operations, if the only context for the triggering
	 * operation is being removed, then the triggering operation must be
	 * replaced in the operation history with the atomic operations that it
	 * triggered. If the context being removed is not the only context for the
	 * triggering operation, the triggering operation will remain, and the
	 * children will each be similarly checked.
	 * 
	 * @param context
	 *            the undo context being removed from the receiver.
	 */
	public void removeContext(IUndoContext context) {

		boolean recompute = false;
		// first check to see if we are removing the only context of the
		// triggering operation
		if (triggeringOperation != null
				&& triggeringOperation.hasContext(context)) {
			if (triggeringOperation.getContexts().length == 1) {
				remove(triggeringOperation);
				return;
			}
			triggeringOperation.removeContext(context);
			recompute = true;
		}
		// the triggering operation remains, check all the children
		ArrayList toBeRemoved = new ArrayList();
		for (int i = 0; i < children.size(); i++) {
			IUndoableOperation child = (IUndoableOperation) children.get(i);
			if (child.hasContext(context)) {
				if (child.getContexts().length == 1) {
					toBeRemoved.add(child);
				} else {
					child.removeContext(context);
				}
				recompute = true;
			}
		}
		for (int i = 0; i < toBeRemoved.size(); i++) {
			remove((IUndoableOperation) toBeRemoved.get(i));
		}
		if (recompute) {
			recomputeContexts();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IUndoableOperation#execute(org.eclipse.core.runtime.IProgressMonitor,
	 *      org.eclipse.core.runtime.IAdaptable)
	 */
	public IStatus execute(IProgressMonitor monitor, IAdaptable info)
			throws ExecutionException {
		if (triggeringOperation != null) {
			history.openOperation(this, IOperationHistory.EXECUTE);
			try {
				IStatus status = triggeringOperation.execute(monitor, info);
				history.closeOperation(status.isOK(), false,
						IOperationHistory.EXECUTE);
				return status;
			} catch (ExecutionException e) {
				history.closeOperation(false, false, IOperationHistory.EXECUTE);
				throw e;
			} catch (RuntimeException e) {
				history.closeOperation(false, false, IOperationHistory.EXECUTE);
				throw e;	
			}

		}
		return IOperationHistory.OPERATION_INVALID_STATUS;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IUndoableOperation#redo(org.eclipse.core.runtime.IProgressMonitor,
	 *      org.eclipse.core.runtime.IAdaptable)
	 */
	public IStatus redo(IProgressMonitor monitor, IAdaptable info)
			throws ExecutionException {
		if (triggeringOperation != null) {
			history.openOperation(this, IOperationHistory.REDO);
			List childrenToRestore = new ArrayList(children);
			try {
				removeAllChildren();
				IStatus status = triggeringOperation.redo(monitor, info);
				if (!status.isOK()) {
					children = childrenToRestore;
				}
				history.closeOperation(status.isOK(), false,
						IOperationHistory.REDO);
				return status;
			} catch (ExecutionException e) {
				children = childrenToRestore;
				history.closeOperation(false, false, IOperationHistory.REDO);
				throw e;
			} catch (RuntimeException e) {
				children = childrenToRestore;
				history.closeOperation(false, false, IOperationHistory.REDO);
				throw e;	
			}
		}
		return IOperationHistory.OPERATION_INVALID_STATUS;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IUndoableOperation#undo(org.eclipse.core.runtime.IProgressMonitor,
	 *      org.eclipse.core.runtime.IAdaptable)
	 */
	public IStatus undo(IProgressMonitor monitor, IAdaptable info)
			throws ExecutionException {
		if (triggeringOperation != null) {
			history.openOperation(this, IOperationHistory.UNDO);
			List childrenToRestore = new ArrayList(children);
			try {
				removeAllChildren();
				IStatus status = triggeringOperation.undo(monitor, info);
				if (!status.isOK()) {
					children = childrenToRestore;
				}
				history.closeOperation(status.isOK(), false,
						IOperationHistory.UNDO);
				return status;
			} catch (ExecutionException e) {
				children = childrenToRestore;
				history.closeOperation(false, false, IOperationHistory.UNDO);
				throw e;
			} catch (RuntimeException e) {
				children = childrenToRestore;
				history.closeOperation(false, false, IOperationHistory.UNDO);
				throw e;	
			}
		}
		return IOperationHistory.OPERATION_INVALID_STATUS;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IUndoableOperation#canUndo()
	 */
	public boolean canUndo() {
		if (triggeringOperation != null) {
			return triggeringOperation.canUndo();
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IUndoableOperation#canExecute()
	 */
	public boolean canExecute() {
		if (triggeringOperation != null) {
			return triggeringOperation.canExecute();
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IUndoableOperation#canRedo()
	 */
	public boolean canRedo() {
		if (triggeringOperation != null) {
			return triggeringOperation.canRedo();
		}
		return false;
	}

	/*
	 * Dispose all operations in the receiver.
	 */
	public void dispose() {
		for (int i = 0; i < children.size(); i++) {
			((IUndoableOperation) (children.get(i))).dispose();
		}
		if (triggeringOperation != null) {
			triggeringOperation.dispose();
		}
	}

	/*
	 * Recompute contexts in light of some change in the children
	 */
	private void recomputeContexts() {
		ArrayList allContexts = new ArrayList();
		if (triggeringOperation != null) {
			IUndoContext[] contexts = triggeringOperation.getContexts();
			for (int i = 0; i < contexts.length; i++) {
				allContexts.add(contexts[i]);
			}
		}
		for (int i = 0; i < children.size(); i++) {
			IUndoContext[] contexts = ((IUndoableOperation) children.get(i))
					.getContexts();
			for (int j = 0; j < contexts.length; j++) {
				if (!allContexts.contains(contexts[j])) {
					allContexts.add(contexts[j]);
				}
			}
		}
		contexts = allContexts;

	}

	/*
	 * Remove all non-triggering children
	 */
	private void removeAllChildren() {
		IUndoableOperation[] nonTriggers = (IUndoableOperation[]) children
				.toArray(new IUndoableOperation[children.size()]);
		for (int i = 0; i < nonTriggers.length; i++) {
			children.remove(nonTriggers[i]);
			nonTriggers[i].dispose();
		}
	}

	/**
	 * Return the operation that triggered the other operations in this
	 * composite.
	 * 
	 * @return the IUndoableOperation that triggered the other children.
	 */
	public IUndoableOperation getTriggeringOperation() {
		return triggeringOperation;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IAdvancedModelOperation#getAffectedObjects()
	 */
	public Object[] getAffectedObjects() {
		if (triggeringOperation instanceof IAdvancedUndoableOperation) {
			return ((IAdvancedUndoableOperation) triggeringOperation)
					.getAffectedObjects();
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IAdvancedModelOperation#aboutToNotify(org.eclipse.core.commands.operations.OperationHistoryEvent)
	 */
	public void aboutToNotify(OperationHistoryEvent event) {
		if (triggeringOperation instanceof IAdvancedUndoableOperation) {
			((IAdvancedUndoableOperation) triggeringOperation)
					.aboutToNotify(event);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IAdvancedUndoableOperation#computeUndoableStatus(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public IStatus computeUndoableStatus(IProgressMonitor monitor)
			throws ExecutionException {
		if (triggeringOperation instanceof IAdvancedUndoableOperation) {
			try {
				return ((IAdvancedUndoableOperation) triggeringOperation)
						.computeUndoableStatus(monitor);
			} catch (OperationCanceledException e) {
				return Status.CANCEL_STATUS;
			}
		}
		return Status.OK_STATUS;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.operations.IAdvancedUndoableOperation#computeRedoableStatus(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public IStatus computeRedoableStatus(IProgressMonitor monitor)
			throws ExecutionException {
		if (triggeringOperation instanceof IAdvancedUndoableOperation) {
			try {
				return ((IAdvancedUndoableOperation) triggeringOperation)
						.computeRedoableStatus(monitor);
			} catch (OperationCanceledException e) {
				return Status.CANCEL_STATUS;
			}
		}
		return Status.OK_STATUS;

	}

	/**
	 * Replace the undo context of the receiver with the provided replacement
	 * undo context. In the case of triggered operations, all contained
	 * operations are checked and any occurrence of the original context is
	 * replaced with the new undo context.
	 * <p>
	 * This message has no effect if the original undo context is not present in
	 * the receiver.
	 * 
	 * @param original
	 *            the undo context which is to be replaced
	 * @param replacement
	 *            the undo context which is replacing the original
	 * @since 3.2
	 */
	public void replaceContext(IUndoContext original, IUndoContext replacement) {

		// first check the triggering operation
		if (triggeringOperation != null
				&& triggeringOperation.hasContext(original)) {
			if (triggeringOperation instanceof IContextReplacingOperation) {
				((IContextReplacingOperation) triggeringOperation)
						.replaceContext(original, replacement);
			} else {
				triggeringOperation.removeContext(original);
				triggeringOperation.addContext(replacement);
			}
		}
		// Now check all the children
		for (int i = 0; i < children.size(); i++) {
			IUndoableOperation child = (IUndoableOperation) children.get(i);
			if (child.hasContext(original)) {
				if (child instanceof IContextReplacingOperation) {
					((IContextReplacingOperation) child).replaceContext(
							original, replacement);
				} else {
					child.removeContext(original);
					child.addContext(replacement);
				}
			}
		}
		recomputeContexts();
	}

	/**
	 * Add the specified context to the operation. Overridden in
	 * TriggeredOperations to add the specified undo context to the triggering
	 * operation.
	 * 
	 * @param context
	 *            the context to be added
	 * 
	 * @since 3.2
	 */
	public void addContext(IUndoContext context) {
		if (triggeringOperation != null) {
			triggeringOperation.addContext(context);
			recomputeContexts();
		}
	}

}
