/*******************************************************************************
 * Copyright (c) 2004, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.progress;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IconAndMessageDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.progress.WorkbenchJob;

/**
 * The BlockedJobsDialog class displays a dialog that provides information on
 * the running jobs.
 */
public class BlockedJobsDialog extends IconAndMessageDialog {
	/**
	 * The singleton dialog instance. A singleton avoids the possibility of
	 * recursive dialogs being created. The singleton is created when a dialog is
	 * requested, and cleared when the dialog is disposed.
	 */
	protected static BlockedJobsDialog singleton;

	/**
	 * The running jobs progress viewer.
	 */
	private DetailedProgressViewer viewer;

	/**
	 * The name of the task that is being blocked.
	 */
	private String blockedTaskName = ProgressMessages.SubTaskInfo_UndefinedTaskName;

	/**
	 * The Cancel button control.
	 */
	private Button cancelSelected;

	private IProgressMonitor blockingMonitor;

	private JobTreeElement blockedElement = new BlockedUIElement();

	/**
	 * The BlockedUIElement is the JobTreeElement that represents the blocked job in
	 * the dialog.
	 */
	private class BlockedUIElement extends JobTreeElement {
		@Override
		Object[] getChildren() {
			return ProgressManagerUtil.EMPTY_OBJECT_ARRAY;
		}

		@Override
		String getDisplayString() {
			if (blockedTaskName == null || blockedTaskName.isEmpty()) {
				return ProgressMessages.BlockedJobsDialog_UserInterfaceTreeElement;
			}
			return blockedTaskName;
		}

		@Override
		public Image getDisplayImage() {
			return JFaceResources.getImage(ProgressManager.WAITING_JOB_KEY);
		}

		@Override
		boolean hasChildren() {
			return false;
		}

		@Override
		boolean isActive() {
			return true;
		}

		@Override
		boolean isJobInfo() {
			return false;
		}

		@Override
		public void cancel() {
			blockingMonitor.setCanceled(true);
		}

		@Override
		public boolean isCancellable() {
			return true;
		}
	}

	/**
	 * Creates a progress monitor dialog under the given shell. It also sets the
	 * dialog's message. The dialog is opened automatically after a reasonable
	 * delay. When no longer needed, the dialog must be closed by calling
	 * <code>close(IProgressMonitor)</code>, where the supplied monitor is the same
	 * monitor passed to this factory method.
	 *
	 * @param parentShell    The parent shell, or <code>null</code> to create a
	 *                       top-level shell. If the parentShell is not null we will
	 *                       open immediately as parenting has been determined. If
	 *                       it is <code>null</code> then the dialog will not open
	 *                       until there is no modal shell blocking it.
	 * @param blockedMonitor The monitor that is currently blocked
	 * @param reason         A status describing why the monitor is blocked
	 * @param taskName       A name to give the blocking task in the dialog
	 * @return BlockedJobsDialog
	 */
	public static BlockedJobsDialog createBlockedDialog(Shell parentShell, IProgressMonitor blockedMonitor,
			IStatus reason, String taskName) {
		// Use an existing dialog if available.
		if (singleton != null) {
			return singleton;
		}
		singleton = new BlockedJobsDialog(parentShell, blockedMonitor, reason);

		if (taskName == null || taskName.isEmpty()) {
			singleton.setBlockedTaskName(ProgressMessages.BlockedJobsDialog_UserInterfaceTreeElement);
		} else {
			singleton.setBlockedTaskName(taskName);
		}

		/**
		 * If there is no parent shell we have not been asked for a parent so we want to
		 * avoid blocking. If there is a parent then it is OK to open.
		 */
		if (parentShell == null) {
			// Create the job that will open the dialog after a delay.
			WorkbenchJob dialogJob = new WorkbenchJob(WorkbenchMessages.EventLoopProgressMonitor_OpenDialogJobName) {
				@Override
				public IStatus runInUIThread(IProgressMonitor monitor) {
					if (singleton == null) {
						return Status.CANCEL_STATUS;
					}
					if (ProgressManagerUtil.rescheduleIfModalShellOpen(this)) {
						return Status.CANCEL_STATUS;
					}
					singleton.open();
					return Status.OK_STATUS;
				}
			};
			// Wait for long operation time to prevent a proliferation of
			// dialogs.
			dialogJob.setSystem(true);
			dialogJob.schedule(PlatformUI.getWorkbench().getProgressService().getLongOperationTime());
		} else {
			singleton.open();
		}

		return singleton;
	}

	/**
	 * The monitor is done. Clear the receiver.
	 *
	 * @param monitor The monitor that is now cleared.
	 */
	public static void clear(IProgressMonitor monitor) {
		if (singleton != null)
			singleton.close(monitor);
	}

	/**
	 * Creates a progress monitor dialog under the given shell. It also sets the
	 * dialog's\ message. <code>open</code> is non-blocking.
	 *
	 * @param parentShell    The parent shell, or <code>null</code> to create a
	 *                       top-level shell.
	 * @param blocking       The monitor that is blocking the job
	 * @param blockingStatus A status describing why the monitor is blocked
	 */
	private BlockedJobsDialog(Shell parentShell, IProgressMonitor blocking, IStatus blockingStatus) {
		super(parentShell == null ? ProgressManagerUtil.getDefaultParent() : parentShell);
		blockingMonitor = blocking;
		setShellStyle(SWT.BORDER | SWT.TITLE | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX | getDefaultOrientation());
		// no close button
		setBlockOnOpen(false);
		setMessage(blockingStatus.getMessage());
	}

	/**
	 * Creates the dialog area under the parent composite.
	 *
	 * @param parent The parent Composite.
	 *
	 * @return parent The parent Composite.
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		setMessage(message);
		createMessageArea(parent);
		showJobDetails(parent);
		return parent;
	}

	/**
	 * Creates a dialog area in the parent composite and displays a progress tree
	 * viewer of the running jobs.
	 *
	 * @param parent The parent Composite.
	 */
	void showJobDetails(Composite parent) {
		viewer = new DetailedProgressViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
		viewer.setComparator(ProgressManagerUtil.getProgressViewerComparator());
		ProgressViewerContentProvider provider = getContentProvider();
		viewer.setContentProvider(provider);
		viewer.setInput(provider);
		viewer.setLabelProvider(new ProgressLabelProvider());
		GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
		data.horizontalSpan = 2;
		int heightHint = convertHeightInCharsToPixels(10);
		data.heightHint = heightHint;
		viewer.getControl().setLayoutData(data);
	}

	/**
	 * Returns the content provider used for the receiver.
	 *
	 * @return ProgressTreeContentProvider
	 */
	private ProgressViewerContentProvider getContentProvider() {
		return new ProgressViewerContentProvider(viewer, true, false) {
			@Override
			public Object[] getElements(Object inputElement) {
				Object[] elements = super.getElements(inputElement);
				Object[] result = new Object[elements.length + 1];
				System.arraycopy(elements, 0, result, 1, elements.length);
				result[0] = blockedElement;
				return result;
			}
		};
	}

	/**
	 * Clears the cursors in the dialog.
	 */
	private void clearCursors() {
		clearCursor(cancelSelected);
		clearCursor(getShell());
	}

	/**
	 * Clears the cursor on the supplied control.
	 *
	 * @param control the control where custom cursor is removed
	 */
	private void clearCursor(Control control) {
		if (control != null && !control.isDisposed()) {
			control.setCursor(null);
		}
	}

	@Override
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		shell.setText(ProgressMessages.BlockedJobsDialog_BlockedTitle);
		shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
	}

	/**
	 * This method sets the message in the message label.
	 *
	 * @param messageString the String for the message area
	 */
	private void setMessage(String messageString) {
		// must not set null text in a label
		message = messageString == null ? "" : messageString; //$NON-NLS-1$
		if (messageLabel == null || messageLabel.isDisposed()) {
			return;
		}
		messageLabel.setText(message);
	}

	@Override
	protected Image getImage() {
		return getInfoImage();
	}

	/**
	 * Returns the progress monitor being used for this dialog. This allows
	 * recursive blockages to also respond to cancellation.
	 *
	 * @return IProgressMonitor
	 */
	public IProgressMonitor getProgressMonitor() {
		return blockingMonitor;
	}

	/**
	 * Requests that the blocked jobs dialog be closed. The supplied monitor must be
	 * the same one that was passed to the createBlockedDialog method.
	 *
	 * @param monitor the monitor associated with this block dialog. Dialog will not
	 *                close if it is another monitor.
	 * @return <code>true</code> if successfully closed
	 */
	public boolean close(IProgressMonitor monitor) {
		// ignore requests to close the dialog from all but the first monitor
		if (blockingMonitor != monitor) {
			return false;
		}
		return close();
	}

	@Override
	public boolean close() {
		// Clear the singleton first.
		singleton = null;
		clearCursors();
		return super.close();
	}

	@Override
	protected Control createButtonBar(Composite parent) {
		// Do nothing here as we want no buttons
		return parent;
	}

	/**
	 * @param taskName The blockedTaskName to set.
	 */
	void setBlockedTaskName(String taskName) {
		this.blockedTaskName = taskName;
	}
}
