/*******************************************************************************
 * Copyright (c) 2000, 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.ltk.internal.core.refactoring;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
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.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.IOperationHistory;
import org.eclipse.core.commands.operations.IOperationHistoryListener;
import org.eclipse.core.commands.operations.IUndoableOperation;
import org.eclipse.core.commands.operations.OperationHistoryEvent;
import org.eclipse.core.commands.operations.OperationHistoryFactory;
import org.eclipse.core.commands.operations.TriggeredOperations;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.IUndoManager;
import org.eclipse.ltk.core.refactoring.IUndoManagerListener;
import org.eclipse.ltk.core.refactoring.IValidationCheckResultQuery;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;

public class UndoManager2 implements IUndoManager {
	
	private class OperationHistroyListener implements IOperationHistoryListener {
		public void historyNotification(OperationHistoryEvent event) {
			IUndoableOperation op= event.getOperation();
			if (op instanceof TriggeredOperations) {
				op= ((TriggeredOperations)op).getTriggeringOperation(); 
			}
			UndoableOperation2ChangeAdapter changeOperation= null;
			if (op instanceof UndoableOperation2ChangeAdapter) {
				changeOperation= (UndoableOperation2ChangeAdapter)op;
			}
			if (changeOperation == null) 
				return;
			Change change= changeOperation.getChange();
			switch(event.getEventType()) {
				case OperationHistoryEvent.ABOUT_TO_EXECUTE:
				case OperationHistoryEvent.ABOUT_TO_UNDO:
				case OperationHistoryEvent.ABOUT_TO_REDO:
					fireAboutToPerformChange(change);
					break;
				case OperationHistoryEvent.DONE:
				case OperationHistoryEvent.UNDONE:
				case OperationHistoryEvent.REDONE:
					fireChangePerformed(change);
					fireUndoStackChanged();
					fireRedoStackChanged();
					break;
				case OperationHistoryEvent.OPERATION_NOT_OK:					
					fireChangePerformed(change);
					break;
				case OperationHistoryEvent.OPERATION_ADDED:
					// would be better to have different events for this
					fireUndoStackChanged();
					fireRedoStackChanged();
					break;
				case OperationHistoryEvent.OPERATION_REMOVED:
					// would be better to have different events for this
					fireUndoStackChanged();
					fireRedoStackChanged();
					break;
			}
		}
	}
	
	private static class NullQuery implements IValidationCheckResultQuery {
		public boolean proceed(RefactoringStatus status) {
			return true;
		}
		public void stopped(RefactoringStatus status) {
			// do nothing
		}
	}
	
	private static class QueryAdapter implements IAdaptable {
		private IValidationCheckResultQuery fQuery;
		public QueryAdapter(IValidationCheckResultQuery query) {
			fQuery= query;
		}
		public Object getAdapter(Class adapter) {
			if (IValidationCheckResultQuery.class.equals(adapter))
				return fQuery;
			return null;
		}
	}
	
	private IOperationHistory fOperationHistroy;
	private IOperationHistoryListener fOperationHistoryListener;
	
	private boolean fIsOpen;
	private TriggeredOperations fActiveOperation;
	
	private ListenerList fListeners;

	public UndoManager2() {
		fOperationHistroy= OperationHistoryFactory.getOperationHistory();
	}
	
	public void addListener(IUndoManagerListener listener) {
		if (fListeners == null) {
			fListeners= new ListenerList(ListenerList.IDENTITY);
			fOperationHistoryListener= new OperationHistroyListener();
			fOperationHistroy.addOperationHistoryListener(fOperationHistoryListener);
		}
		fListeners.add(listener);
	}

	public void removeListener(IUndoManagerListener listener) {
		if (fListeners == null)
			return;
		fListeners.remove(listener);
		if (fListeners.size() == 0) {
			fOperationHistroy.removeOperationHistoryListener(fOperationHistoryListener);
			fListeners= null;
			fOperationHistoryListener= null;
		}
	}

	public void aboutToPerformChange(Change change) {
		IUndoableOperation operation= new UndoableOperation2ChangeAdapter(change);
		operation.addContext(RefactoringCorePlugin.getUndoContext());
		fActiveOperation= new TriggeredOperations(operation, fOperationHistroy);
		fActiveOperation.addContext(RefactoringCorePlugin.getUndoContext());
    	fOperationHistroy.openOperation(fActiveOperation, IOperationHistory.EXECUTE);
    	fIsOpen= true;
	}

	public void changePerformed(Change change) {
		changePerformed(change, true);
	}

	public void changePerformed(Change change, boolean successful) {
		if (fIsOpen && fActiveOperation != null) {
			fOperationHistroy.closeOperation(successful, false, IOperationHistory.EXECUTE);
	        fIsOpen= false;
		}
	}

	public void addUndo(String name, Change change) {
		if (fActiveOperation != null) {
			UndoableOperation2ChangeAdapter operation= (UndoableOperation2ChangeAdapter)fActiveOperation.getTriggeringOperation();
			operation.setUndoChange(change);
			operation.setLabel(name);
			fOperationHistroy.add(fActiveOperation);
			fActiveOperation= null;
		}
	}

	public boolean anythingToUndo() {
		return fOperationHistroy.canUndo(RefactoringCorePlugin.getUndoContext());
	}

	public String peekUndoName() {
		IUndoableOperation op= fOperationHistroy.getUndoOperation(RefactoringCorePlugin.getUndoContext());
		if (op == null)
			return null;
		return op.getLabel();
	}

	public void performUndo(IValidationCheckResultQuery query, IProgressMonitor pm) throws CoreException {
		IUndoableOperation undo= fOperationHistroy.getUndoOperation(RefactoringCorePlugin.getUndoContext());
		UndoableOperation2ChangeAdapter changeOperation= getUnwrappedOperation(undo);
		if (changeOperation == null) 
			throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(),
				IStatus.ERROR, RefactoringCoreMessages.UndoManager2_no_change, null)); 
		if (query == null)
			query= new NullQuery();
		try {
			fOperationHistroy.undoOperation(undo, pm, new QueryAdapter(query));
		} catch (ExecutionException e) {
			handleException(e);
		}
	}

	public boolean anythingToRedo() {
		return fOperationHistroy.canRedo(RefactoringCorePlugin.getUndoContext());
	}

	public String peekRedoName() {
		IUndoableOperation op= fOperationHistroy.getRedoOperation(RefactoringCorePlugin.getUndoContext());
		if (op == null)
			return null;
		return op.getLabel();
	}

	public void performRedo(IValidationCheckResultQuery query, IProgressMonitor pm) throws CoreException {
		IUndoableOperation redo= fOperationHistroy.getRedoOperation(RefactoringCorePlugin.getUndoContext());
		UndoableOperation2ChangeAdapter changeOperation= getUnwrappedOperation(redo);
		if (changeOperation == null) 
			throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(),
				IStatus.ERROR, RefactoringCoreMessages.UndoManager2_no_change, null)); 
		if (query == null)
			query= new NullQuery();
		try {
			fOperationHistroy.redoOperation(redo, pm, new QueryAdapter(query));
		} catch (ExecutionException e) {
			handleException(e);
		}
	}

	private UndoableOperation2ChangeAdapter getUnwrappedOperation(IUndoableOperation operation) {
		IUndoableOperation result= operation;
		if (result instanceof TriggeredOperations) {
			result= ((TriggeredOperations)result).getTriggeringOperation();
		}
		if (result instanceof UndoableOperation2ChangeAdapter) {
			return (UndoableOperation2ChangeAdapter)result;
		}
		return null;
	}

	public void flush() {
		if (fActiveOperation != null) {
			if (fIsOpen) {
				fOperationHistroy.closeOperation(false, false, IOperationHistory.EXECUTE);
			}
			/* the triggering operation is invalid, but we must ensure that any
	         * other operations executed while it was open remain in the undo
	         * history.  We accomplish this by adding the invalid operation,
	         * since disposing the context later will cause it to be broken up into
	         * its atomic parts.
	         */
			fOperationHistroy.add(fActiveOperation);
		}
		fActiveOperation= null;
		fIsOpen= false;
		fOperationHistroy.dispose(RefactoringCorePlugin.getUndoContext(), true, true, false);
	}

	public void shutdown() {
		// nothing to do since we have a shared undo manager anyways.
	}
	
	private void handleException(ExecutionException e) throws CoreException {
		Throwable cause= e.getCause();
		if (cause instanceof CoreException) {
			throw (CoreException)cause;
		} else {
			throw new CoreException(new Status(
				IStatus.ERROR, RefactoringCorePlugin.getPluginId(),IStatus.ERROR, 
				RefactoringCoreMessages.RefactoringCorePlugin_internal_error, 
				e));
		}
	}

	//---- event firing methods -------------------------------------------------
	
	private void fireAboutToPerformChange(final Change change) {
		if (fListeners == null)
			return;
		Object[] listeners= fListeners.getListeners();
		for (int i= 0; i < listeners.length; i++) {
			final IUndoManagerListener listener= (IUndoManagerListener)listeners[i];
			SafeRunner.run(new ISafeRunnable() {
				public void run() throws Exception {
					listener.aboutToPerformChange(UndoManager2.this, change);
				}
				public void handleException(Throwable exception) {
					RefactoringCorePlugin.log(exception);
				}
			});			
		}
	}
	
	private void fireChangePerformed(final Change change) {
		if (fListeners == null)
			return;
		Object[] listeners= fListeners.getListeners();
		for (int i= 0; i < listeners.length; i++) {
			final IUndoManagerListener listener= (IUndoManagerListener)listeners[i];
			SafeRunner.run(new ISafeRunnable() {
				public void run() throws Exception {
					listener.changePerformed(UndoManager2.this, change);
				}
				public void handleException(Throwable exception) {
					RefactoringCorePlugin.log(exception);
				}
			});
		}
	}
	
	private void fireUndoStackChanged() {
		if (fListeners == null)
			return;
		Object[] listeners= fListeners.getListeners();
		for (int i= 0; i < listeners.length; i++) {
			final IUndoManagerListener listener= (IUndoManagerListener)listeners[i];
			SafeRunner.run(new ISafeRunnable() {
				public void run() throws Exception {
					listener.undoStackChanged(UndoManager2.this);
				}
				public void handleException(Throwable exception) {
					RefactoringCorePlugin.log(exception);
				}
			});
		}
	}

	private void fireRedoStackChanged() {
		if (fListeners == null)
			return;
		Object[] listeners= fListeners.getListeners();
		for (int i= 0; i < listeners.length; i++) {
			final IUndoManagerListener listener= (IUndoManagerListener)listeners[i];
			SafeRunner.run(new ISafeRunnable() {
				public void run() throws Exception {
					listener.redoStackChanged(UndoManager2.this);
				}
				public void handleException(Throwable exception) {
					RefactoringCorePlugin.log(exception);
				}
			});
		}
	}
	
	//---- testing methods ---------------------------------------------
	
	public boolean testHasNumberOfUndos(int number) {
		return fOperationHistroy.getUndoHistory(RefactoringCorePlugin.getUndoContext()).length == number;
	}
	
	public boolean testHasNumberOfRedos(int number) {
		return fOperationHistroy.getRedoHistory(RefactoringCorePlugin.getUndoContext()).length == number;
	}	
}
