/*******************************************************************************
 * Copyright (c) 2000, 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.jface.operation;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.ProgressMonitorWrapper;
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;
        
        /**
         * The thread that forked this modal context thread.
         * 
         * @since 3.1
         */
        private Thread callingThread;
        
        /**
         * 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;
            this.callingThread = Thread.currentThread();
        }

        /* (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 {
                //notify the operation of change of thread of control
            	if (runnable instanceof IThreadListener)
            		((IThreadListener)runnable).threadChange(callingThread);
            	
                // 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) {
                	// Run the event loop.  Handle any uncaught exceptions caused
                	// by UI events.
                   	try {
                    	if (!display.readAndDispatch())
                        	display.sleep();
                	}
                   	// ThreadDeath is a normal error when the thread is dying.  We must
                   	// propagate it in order for it to properly terminate.
                	catch (ThreadDeath e) {
                   		throw (e);
                	}
                	// For all other exceptions, log the problem.
                	catch (Throwable e) {
                		System.err.println("Unhandled event loop exception during blocked modal context."); //$NON-NLS-1$
             			e.printStackTrace();
                	}
                }
            } else {
                try {
                    join();
                } catch (InterruptedException e) {
                    throwable = 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.
     * 
     * @param thread The thread to be checked
     * @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>
     *<p>
     * If the supplied operation implements <code>IThreadListener</code>, it
     * will be notified of any thread changes required to execute the operation.
     * Specifically, the operation will be notified of the thread that will call its 
     * <code>run</code> method before it is called, and will be notified of the
     * change of control back to the thread calling this method when the operation
     * completes.  These thread change notifications give the operation an 
     * opportunity to transfer any thread-local state to the execution thread before 
     * control is transferred to the new thread.
     *</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);
                	if (operation instanceof IThreadListener)
                		((IThreadListener)operation).threadChange(t);
                    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;
    }

	/**
	 * Sets whether ModalContext may process events (by calling <code>Display.readAndDispatch()</code>)
	 * while running operations. By default, ModalContext will process events while running operations.
	 * Use this method to disallow event processing temporarily.
	 * @param allowReadAndDispatch <code>true</code> (the default) if events may be processed while
	 * running an operation, <code>false</code> if Display.readAndDispatch() should not be called
	 * from ModalContext.
	 * @since 3.2
	 */
	public static void setAllowReadAndDispatch(boolean allowReadAndDispatch) {
		// use a separate thread if and only if it is OK to spin the event loop
		runInSeparateThread = allowReadAndDispatch;
	}
}
