//------------------------------------------------------------------------------
// 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.edit.command;

import java.util.EventObject;
import java.util.Iterator;

import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.process.command.BSDragAndDropCommand;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.osgi.util.NLS;

/**
 * A command stack that tries its best to fully revert to its initial state.
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class FullyRevertibleCommandStack extends BasicCommandStack {

	public static interface IErrorReporter {
		void showError(String msg);
	}

	private IErrorReporter errReporter;

	private ActionManager actionMgr;

	public FullyRevertibleCommandStack(ActionManager actionMgr) {
		this.actionMgr = actionMgr;
	}

	public FullyRevertibleCommandStack(ActionManager actionMgr,
			IErrorReporter errReporter) {
		this(actionMgr);
		this.errReporter = errReporter;
	}

	public void setErrorReporter(IErrorReporter errReporter) {
		this.errReporter = errReporter;
	}

	public boolean doExecute(Command command) {
		if (!command.canUndo())
			return false; // throw new IllegalArgumentException("Cannot
		// execute command that cannot de undone");
		super.execute(command);
		
		// special handling for ActivityDropCommand
		//
		// TODO: all commands must return a correct value in getAffectedObject()
		// if getAffectedObject() return an empty collection, the action manager
		// will not register it as a modifier of the resources returned by getModifiedResources()
		// and the editor might not be marked dirty as the result.
		//
		if(command instanceof BSDragAndDropCommand && command.getAffectedObjects().isEmpty()) {
			if(top != -1) {
				commandList.remove(top--);
				if(top != -1) {
					mostRecentCommand = (Command) commandList.get(top);
				}
				else {
					mostRecentCommand = null;
				}
			}
			return false;
		}
		
		boolean ret = getMostRecentCommand() != null;
		if (ret && actionMgr != null) {
			if (command instanceof IResourceAwareCommand) {
				for (Iterator iter = ((IResourceAwareCommand) command)
						.getModifiedResources().iterator(); iter.hasNext();) {
					Resource resource = (Resource) iter.next();
					actionMgr.registerAsModifierOf(resource);
				}
			} else {
				EObject modified = TngUtil.getOwner(command);
				if (modified != null) {
					actionMgr.registerAsModifierOf(modified);
				}
			}
		}
		notifyListeners(new CommandStackChangedEvent(this,
				CommandStackChangedEvent.EXECUTED));
		return ret;
	}

	public void execute(Command command) {
		doExecute(command);
	}

	public void redo() {
		super.redo();
		notifyListeners(new CommandStackChangedEvent(this,
				CommandStackChangedEvent.EXECUTED));
	}

	public void undo() {
		if (canUndo()) {
			Command command = (Command) commandList.get(top--);
			try {
				command.undo();
				mostRecentCommand = command;
			} catch (RuntimeException exception) {
				CommonPlugin.INSTANCE
						.log(new WrappedException(
								CommonPlugin.INSTANCE
										.getString("_UI_IgnoreException_exception"), exception).fillInStackTrace()); //$NON-NLS-1$

				mostRecentCommand = null;
				top++;

				if (errReporter != null) {
					Object[] object = new Object[1];
					object[0] = command;
					object[1] = exception;
					errReporter.showError(NLS.bind(LibraryEditResources.undoCommandError_msg, object)); 
				}
			}
			notifyListeners(new CommandStackChangedEvent(this,
					CommandStackChangedEvent.UNDO));
		}
	}

	public boolean undoAll() {
		try {
			while (canUndo()) {
				Command command = (Command) commandList.get(top--);
				try {
					command.undo();
					mostRecentCommand = command;
				} catch (RuntimeException exception) {
					CommonPlugin.INSTANCE
							.log(new WrappedException(
									CommonPlugin.INSTANCE
											.getString("_UI_IgnoreException_exception"), exception).fillInStackTrace()); //$NON-NLS-1$

					mostRecentCommand = null;
					top++;

					if (errReporter != null) {
						// errReporter.showError("Cannot undo command: '" +
						// command + "', exception: " + exception);
						Object[] object = new Object[1];
						object[0] = command;
						object[1] = exception;
						errReporter
								.showError(NLS.bind(LibraryEditResources.undoCommandError_msg, object)); 
					}

					return false;
				}
			}
		} finally {
			notifyListeners(new CommandStackChangedEvent(this,
					CommandStackChangedEvent.UNDO_ALL));
		}

		return true;
	}

	protected void notifyListeners(EventObject event) {
		for (Iterator i = listeners.iterator(); i.hasNext();) {
			((CommandStackListener) i.next()).commandStackChanged(event);
		}
	}

	protected void notifyListeners() {
		//
	}

	public void saveIsDone() {
		super.saveIsDone();
		notifyListeners(new CommandStackChangedEvent(this,
				CommandStackChangedEvent.SAVED));
		commandList.clear();
		top = -1;
		saveIndex = -1;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.BasicCommandStack#isSaveNeeded()
	 */
	public boolean isSaveNeeded() {
		return super.isSaveNeeded();
	}

}
