/*******************************************************************************
 * Copyright (c) 2000, 2011 IBM Corporation and others.
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * https://www.eclipse.org/legal/epl-2.0
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 *     IBM Corporation - initial API and implementation
 *     Chris Gross (schtoo@schtoo.com) - patch for bug 16179
 *     Tasktop Technologies - extracted code for Mylyn
 *******************************************************************************/

package org.eclipse.mylyn.commons.ui;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ProgressMonitorWrapper;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.operation.ModalContext;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
 * A helper class for running operations in dialogs. Based on {@link WizardDialog}.
 * 
 * @author Steffen Pingel
 * @since 3.7
 */
public class ProgressContainer implements IRunnableContext {

	private static final String FOCUS_CONTROL = "focusControl"; //$NON-NLS-1$

	// The number of long running operation executed from the dialog.
	private long activeRunningOperations = 0;

	private Cursor arrowCursor;

	private Button cancelButton;

	private boolean lockedUI = false;

	// The progress monitor
	private final ProgressMonitorPart progressMonitorPart;

	private final Shell shell;

	private Cursor waitCursor;

	private boolean useWaitCursor;

	public ProgressContainer(Shell shell, ProgressMonitorPart progressMonitorPart) {
		Assert.isNotNull(shell);
		Assert.isNotNull(progressMonitorPart);
		this.shell = shell;
		this.progressMonitorPart = progressMonitorPart;
		init();
	}

	private void init() {
		this.shell.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				progressMonitorPart.setCanceled(true);
			}
		});
	}

	public boolean useWaitCursor() {
		return useWaitCursor;
	}

	public void setUseWaitCursor(boolean useWaitCursor) {
		this.useWaitCursor = useWaitCursor;
	}

	/**
	 * About to start a long running operation triggered through the wizard. Shows the progress monitor and disables the
	 * wizard's buttons and controls.
	 * 
	 * @param enableCancelButton
	 *            <code>true</code> if the Cancel button should be enabled, and <code>false</code> if it should be
	 *            disabled
	 * @return the saved UI state
	 */
	private Object aboutToStart(boolean enableCancelButton) {
		Map<Object, Object> savedState = null;
		if (getShell() != null) {
			// Save focus control
			Control focusControl = getShell().getDisplay().getFocusControl();
			if (focusControl != null && focusControl.getShell() != getShell()) {
				focusControl = null;
			}
			// Set the busy cursor to all shells.
			Display d = getShell().getDisplay();
			if (useWaitCursor()) {
				waitCursor = new Cursor(d, SWT.CURSOR_WAIT);
				setDisplayCursor(waitCursor);
				// Set the arrow cursor to the cancel component.
				arrowCursor = new Cursor(d, SWT.CURSOR_ARROW);
				if (cancelButton != null) {
					cancelButton.setCursor(arrowCursor);
				}
			}
			// Deactivate shell
			savedState = new HashMap<Object, Object>(10);
			saveUiState(savedState);
			if (focusControl != null) {
				savedState.put(FOCUS_CONTROL, focusControl);
			}
			// Attach the progress monitor part to the cancel button
			if (cancelButton != null) {
				progressMonitorPart.attachToCancelComponent(cancelButton);
			}
			progressMonitorPart.setVisible(true);
		}
		return savedState;
	}

	public Button getCancelButton() {
		return cancelButton;
	}

	private IProgressMonitor getProgressMonitor() {
		return new ProgressMonitorWrapper(progressMonitorPart) {
			@Override
			public void internalWorked(double work) {
				if (progressMonitorPart.isDisposed()) {
					this.setCanceled(true);
					return;
				}
				super.internalWorked(work);
			}
		};
	}

	public Shell getShell() {
		return shell;
	}

	public boolean isActive() {
		return activeRunningOperations > 0;
	}

	public boolean isLockedUI() {
		return lockedUI;
	}

	protected void restoreUiState(Map<Object, Object> state) {
		// ignore

	}

	/**
	 * This implementation of IRunnableContext#run(boolean, boolean, IRunnableWithProgress) blocks until the runnable
	 * has been run, regardless of the value of <code>fork</code>. It is recommended that <code>fork</code> is set to
	 * true in most cases. If <code>fork</code> is set to <code>false</code>, the runnable will run in the UI thread and
	 * it is the runnable's responsibility to call <code>Display.readAndDispatch()</code> to ensure UI responsiveness.
	 * UI state is saved prior to executing the long-running operation and is restored after the long-running operation
	 * completes executing. Any attempt to change the UI state of the wizard in the long-running operation will be
	 * nullified when original UI state is restored.
	 */
	public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException,
			InterruptedException {
		// The operation can only be canceled if it is executed in a separate
		// thread.
		// Otherwise the UI is blocked anyway.
		Object state = null;
		if (activeRunningOperations == 0) {
			state = aboutToStart(fork && cancelable);
		}
		activeRunningOperations++;
		try {
			if (!fork) {
				lockedUI = true;
			}
			ModalContext.run(runnable, fork, getProgressMonitor(), getShell().getDisplay());
			lockedUI = false;
		} finally {
			activeRunningOperations--;
			// Stop if this is the last one
			if (state != null) {
				stopped(state);
			}
		}
	}

	protected void saveUiState(Map<Object, Object> savedState) {
		// ignore

	}

	public void setCancelButton(Button cancelButton) {
		this.cancelButton = cancelButton;
	}

	/**
	 * Sets the given cursor for all shells currently active for this window's display.
	 * 
	 * @param c
	 *            the cursor
	 */
	private void setDisplayCursor(Cursor c) {
		Shell[] shells = getShell().getDisplay().getShells();
		for (Shell shell2 : shells) {
			shell2.setCursor(c);
		}
	}

	/**
	 * A long running operation triggered through the wizard was stopped either by user input or by normal end. Hides
	 * the progress monitor and restores the enable state wizard's buttons and controls.
	 * 
	 * @param savedState
	 *            the saved UI state as returned by <code>aboutToStart</code>
	 * @see #aboutToStart
	 */
	@SuppressWarnings("unchecked")
	private void stopped(Object savedState) {
		if (getShell() != null && !getShell().isDisposed()) {
			progressMonitorPart.setVisible(false);
			if (cancelButton != null) {
				progressMonitorPart.removeFromCancelComponent(cancelButton);
			}

			Map<Object, Object> state = (Map<Object, Object>) savedState;
			restoreUiState(state);
			if (waitCursor != null) {
				setDisplayCursor(null);
				if (cancelButton != null) {
					cancelButton.setCursor(null);
				}
				waitCursor.dispose();
				waitCursor = null;
				arrowCursor.dispose();
				arrowCursor = null;
			}
			Control focusControl = (Control) state.get(FOCUS_CONTROL);
			if (focusControl != null && !focusControl.isDisposed()) {
				focusControl.setFocus();
			}
		}
	}

}