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

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.*;
import org.eclipse.jface.util.Assert;
import org.eclipse.swt.widgets.Display;

/**
 * Utility class for supporting modal operations.
 * The runnable passed to the <code>run</code> method is executed in a
 * separate thread, depending on the value of the passed fork argument. 
 * If the runnable is executed in a separate thread then the current thread
 * either waits until the new thread ends or, if the current thread is the 
 * UI thread, it polls the SWT event queue and dispatches each event.
 * <p>
 * This class is not intended to be subclassed.
 * </p>
 */
public class ModalContext {

	/**
	 * Indicated whether ModalContext is in debug mode;
	 * <code>false</code> by default.
	 */
	private static boolean debug = false;
	
	/**
	 * The number of nested modal runs, or 0 if not inside a modal run.
	 * This is global state.
	 */
	private static int modalLevel = 0;
	
	/**
	 * Indicates whether operations should be run in a separate thread.
	 * Defaults to true.
	 * For internal debugging use, set to false to run operations in the calling thread.
	 */
	private static boolean runInSeparateThread = true;

	/**
	 * Thread which runs the modal context.
	 */
	private static class ModalContextThread extends Thread {
		/**
		 * The operation to be run.
		 */
		private IRunnableWithProgress runnable;
		
		/** 
		 * The exception thrown by the operation starter.
		 */
		private Throwable throwable;
		
		/**
		 * The progress monitor used for progress and cancelation.
		 */
		private IProgressMonitor progressMonitor;
		
		/**
		 * The display used for event dispatching.
		 */
		private Display display;
		
		/**
		 * Indicates whether to continue event queue dispatching.
		 */
		private volatile boolean continueEventDispatching = true;

		/**
		 * Creates a new modal context.
		 * 
		 * @param operation the runnable to run
		 * @param monitor the progress monitor to use to display progress and receive
		 *   requests for cancelation
		 * @param display the display to be used to read and dispatch events
		 */
		private ModalContextThread(IRunnableWithProgress operation, IProgressMonitor monitor, Display display) {
			super("ModalContext"); //$NON-NLS-1$
			Assert.isTrue(monitor != null && display != null);
			runnable = operation;
			progressMonitor = new AccumulatingProgressMonitor(monitor, display);
			this.display = display;
		}
		/* (non-Javadoc)
		 * Method declared on Thread.
		 */
		public void run() {
			try {
				if (runnable != null)
					runnable.run(progressMonitor);
			} catch (InvocationTargetException e) {
				throwable= e;
			} catch (InterruptedException e) {
				throwable= e;
			} catch (RuntimeException e) {
				throwable= e;
			} catch (ThreadDeath e) {
				// Make sure to propagate ThreadDeath, or threads will never fully terminate
				throw e;
			} catch (Error e) {
				throwable= e;
			} finally {
				// Make sure that all events in the asynchronous event queue
				// are dispatched.
				display.syncExec(new Runnable() {
					public void run() {
						// do nothing
					}
				});
				
				// Stop event dispatching
				continueEventDispatching= false;
				
				// Force the event loop to return from sleep () so that
				// it stops event dispatching.
				display.asyncExec(null);
			}	
		}
		/**
		 * Processes events or waits until this modal context thread terminates.
		 */
		public void block() {
			if (display == Display.getCurrent()) {
				while (continueEventDispatching) {
					if (!display.readAndDispatch())
						display.sleep();
				}
			} else {
				try {
					join();
				} catch (InterruptedException e) {
				}
			}
		}		
	}
/**
 * Returns whether the first progress monitor is the same as, or
 * a wrapper around, the second progress monitor.
 *
 * @param monitor1 the first progress monitor
 * @param monitor2 the second progress monitor
 * @return <code>true</code> if the first is the same as, or
 *   a wrapper around, the second
 * @see ProgressMonitorWrapper
 */
public static boolean canProgressMonitorBeUsed(IProgressMonitor monitor1, IProgressMonitor monitor2) {
	if (monitor1 == monitor2)
		return true;
		
	while (monitor1 instanceof ProgressMonitorWrapper) {
		monitor1= ((ProgressMonitorWrapper)monitor1).getWrappedProgressMonitor();
		if (monitor1 == monitor2)
			return true;
	}
	return false;
}
/**
 * Checks with the given progress monitor and throws 
 * <code>InterruptedException</code> if it has been canceled.
 * <p>
 * Code in a long-running operation should call this method
 * regularly so that a request to cancel will be honored.
 * </p>
 * <p>
 * Convenience for:
 * <pre>
 * if (monitor.isCanceled())
 *    throw new InterruptedException();
 * </pre>
 * </p>
 *
 * @param monitor the progress monitor
 * @exception InterruptedException if cancelling the operation has been requested
 * @see IProgressMonitor#isCanceled()
 */
public static void checkCanceled(IProgressMonitor monitor) throws InterruptedException {
	if (monitor.isCanceled())
		throw new InterruptedException();
}
/**
 * Returns the currently active modal context thread, or null if no modal context is active.
 */
private static ModalContextThread getCurrentModalContextThread() {
	Thread t = Thread.currentThread();
	if (t instanceof ModalContextThread)
		return (ModalContextThread) t;
	return null;
}
/**
 * Returns the modal nesting level.
 * <p>
 * The modal nesting level increases by one each time the
 * <code>ModalContext.run</code> method is called within the
 * dynamic scope of another call to <code>ModalContext.run</code>.
 * </p>
 *
 * @return the modal nesting level, or <code>0</code> if 
 *  this method is called outside the dynamic scope of any
 *  invocation of <code>ModalContext.run</code>
 */
public static int getModalLevel() {
	return modalLevel;
}
/**
 * Returns whether the given thread is running a modal context.
 *
 * @return <code>true</code> if the given thread is running a modal context, <code>false</code> if not
 */
public static boolean isModalContextThread(Thread thread) {
	return thread instanceof ModalContextThread;
}
/**
 * Runs the given runnable in a modal context, passing it a progress monitor.
 * <p>
 * The modal nesting level is increased by one from the perspective
 * of the given runnable.
 * </p>
 *
 * @param operation the runnable to run
 * @param fork <code>true</code> if the runnable should run in a separate thread,
 *   and <code>false</code> if in the same thread
 * @param monitor the progress monitor to use to display progress and receive
 *   requests for cancelation
 * @param display the display to be used to read and dispatch events
 * @exception InvocationTargetException if the run method must propagate a checked exception,
 * 	it should wrap it inside an <code>InvocationTargetException</code>; runtime exceptions and errors are automatically
 *  wrapped in an <code>InvocationTargetException</code> by this method
 * @exception InterruptedException if the operation detects a request to cancel, 
 *  using <code>IProgressMonitor.isCanceled()</code>, it should exit by throwing 
 *  <code>InterruptedException</code>; this method propagates the exception
 */
public static void run(IRunnableWithProgress operation, boolean fork, IProgressMonitor monitor, Display display) throws InvocationTargetException, InterruptedException {
	Assert.isTrue(operation != null && monitor != null);
		
	modalLevel++;
	try {
		if (monitor != null)
			monitor.setCanceled(false);
		// Is the runnable supposed to be execute in the same thread.
		if (!fork || !runInSeparateThread) {
			runInCurrentThread(operation, monitor);
		} else {
			ModalContextThread t = getCurrentModalContextThread();
			if (t != null) {
				Assert.isTrue(canProgressMonitorBeUsed(monitor, t.progressMonitor));
				runInCurrentThread(operation, monitor);
			} else {
				t = new ModalContextThread(operation, monitor, display);
				t.start();
				t.block();
				Throwable throwable= t.throwable;
				if (throwable != null) {
					if (debug
						&& !(throwable instanceof InterruptedException)
						&& !(throwable instanceof OperationCanceledException)) {
						System.err.println("Exception in modal context operation:"); //$NON-NLS-1$
						throwable.printStackTrace();
						System.err.println("Called from:"); //$NON-NLS-1$
						// Don't create the InvocationTargetException on the throwable,
						// otherwise it will print its stack trace (from the other thread).
						new InvocationTargetException(null).printStackTrace();
					}
					if (throwable instanceof InvocationTargetException) {
						throw (InvocationTargetException) throwable;
					} else if (throwable instanceof InterruptedException) {
						throw (InterruptedException) throwable;
					} else if (
						throwable instanceof OperationCanceledException) {
						// See 1GAN3L5: ITPUI:WIN2000 - ModalContext converts OperationCancelException into InvocationTargetException
						throw new InterruptedException(throwable.getMessage());
					} else {
						throw new InvocationTargetException(throwable);
					}	
				}
			}
		}
	}
	finally {
		modalLevel--;
	}
}
/**
 * Run a runnable.  Convert all thrown exceptions to 
 * either InterruptedException or InvocationTargetException
 */
private static void runInCurrentThread(IRunnableWithProgress runnable, IProgressMonitor progressMonitor) 
	throws InterruptedException, InvocationTargetException
{
	try {
		if (runnable != null)
			runnable.run(progressMonitor);
	} catch (InvocationTargetException e) {
		throw e;
	} catch (InterruptedException e) {
		throw e;
	} catch (OperationCanceledException e) {
		throw new InterruptedException();
	} catch (ThreadDeath e) {
		// Make sure to propagate ThreadDeath, or threads will never fully terminate
		throw e;
	} catch (RuntimeException e) {
		throw new InvocationTargetException(e);
	} catch (Error e) {
		throw new InvocationTargetException(e);
	}
}
/**
 * Sets whether ModalContext is running in debug mode.
 *
 * @param debugMode <code>true</code> for debug mode, 
 *  and <code>false</code> for normal mode (the default)
 */
public static void setDebugMode(boolean debugMode) {
	debug = debugMode;
}
}
