/*******************************************************************************
 * Copyright (c) 2006, 2015 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;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.internal.InternalSaveable;
import org.eclipse.ui.internal.PartSite;
import org.eclipse.ui.progress.IJobRunnable;

/**
 * A <code>Saveable</code> represents a unit of saveability, e.g. an editable
 * subset of the underlying domain model that may contain unsaved changes.
 * Different workbench parts (editors and views) may present the same saveables
 * in different ways. This interface allows the workbench to provide more
 * appropriate handling of operations such as saving and closing workbench
 * parts. For example, if two editors sharing the same saveable with unsaved
 * changes are closed simultaneously, the user is only prompted to save the
 * changes once for the shared saveable, rather than once for each editor.
 * <p>
 * Workbench parts that work in terms of saveables should implement
 * {@link ISaveablesSource}.
 * </p>
 *
 * @see ISaveablesSource
 * @since 3.2
 */
public abstract class Saveable extends InternalSaveable implements IAdaptable {

	/**
	 * Either {@code null} or the System's {@link SWT#CURSOR_WAIT} cursor instance.
	 * Should never be disposed.
	 */
	private Cursor waitCursor;
	private Cursor originalCursor;

	/**
	 * Attempts to show this saveable in the given page and returns
	 * <code>true</code> on success. The default implementation does nothing and
	 * returns <code>false</code>.
	 *
	 * @param page the workbench page in which to show this saveable
	 * @return <code>true</code> if this saveable is now visible to the user
	 * @since 3.3
	 */
	public boolean show(IWorkbenchPage page) {
		if (page == null) {
			// I wish it was easier to avoid warnings about unused parameters
		}
		return false;
	}

	/**
	 * Returns the name of this saveable for display purposes.
	 *
	 * @return the model's name; never <code>null</code>.
	 */
	public abstract String getName();

	/**
	 * Returns the tool tip text for this saveable. This text is used to
	 * differentiate between two inputs with the same name. For instance,
	 * MyClass.java in folder X and MyClass.java in folder Y. The format of the text
	 * varies between input types.
	 *
	 * @return the tool tip text; never <code>null</code>
	 */
	public abstract String getToolTipText();

	/**
	 * Returns the image descriptor for this saveable.
	 *
	 * @return the image descriptor for this model; may be <code>null</code> if
	 *         there is no image
	 */
	public abstract ImageDescriptor getImageDescriptor();

	/**
	 * Saves the contents of this saveable.
	 * <p>
	 * If the save is cancelled through user action, or for any other reason, the
	 * part should invoke <code>setCancelled</code> on the
	 * <code>IProgressMonitor</code> to inform the caller.
	 * </p>
	 * <p>
	 * This method is long-running; progress and cancellation are provided by the
	 * given progress monitor.
	 * </p>
	 *
	 * @param monitor the progress monitor
	 * @throws CoreException if the save fails; it is the caller's responsibility to
	 *                       report the failure to the user
	 */
	public abstract void doSave(IProgressMonitor monitor) throws CoreException;

	/**
	 * Returns whether the contents of this saveable have changed since the last
	 * save operation.
	 * <p>
	 * <b>Note:</b> this method is called frequently, for example by actions to
	 * determine their enabled status.
	 * </p>
	 *
	 * @return <code>true</code> if the contents have been modified and need saving,
	 *         and <code>false</code> if they have not changed since the last save
	 */
	public abstract boolean isDirty();

	/**
	 * Clients must implement equals and hashCode as defined in
	 * {@link Object#equals(Object)} and {@link Object#hashCode()}. Two saveables
	 * should be equal if their dirty state is shared, and saving one will save the
	 * other. If two saveables are equal, their names, tooltips, and images should
	 * be the same because only one of them will be shown when prompting the user to
	 * save.
	 *
	 * @param object the object to compare
	 * @return true if this Saveable is equal to the given object
	 */
	@Override
	public abstract boolean equals(Object object);

	/**
	 * Clients must implement equals and hashCode as defined in
	 * {@link Object#equals(Object)} and {@link Object#hashCode()}. Two saveables
	 * should be equal if their dirty state is shared, and saving one will save the
	 * other. If two saveables are equal, their hash codes MUST be the same, and
	 * their names, tooltips, and images should be the same because only one of them
	 * will be shown when prompting the user to save.
	 * <p>
	 * IMPORTANT: Implementers should ensure that the hashCode returned is
	 * sufficiently unique so as not to collide with hashCodes returned by other
	 * implementations. It is suggested that the defining plug-in's ID be used as
	 * part of the returned hashCode, as in the following example:
	 * </p>
	 *
	 * <pre>
	 *     int PRIME = 31;
	 *     int hash = ...; // compute the &quot;normal&quot; hash code, e.g. based on some identifier unique within the defining plug-in
	 *     return hash * PRIME + MY_PLUGIN_ID.hashCode();
	 * </pre>
	 *
	 * @return a hash code
	 */
	@Override
	public abstract int hashCode();

	/**
	 * Saves this saveable, or prepares this saveable for a background save
	 * operation. Returns null if this saveable has been successfully saved, or a
	 * job runnable that needs to be run to complete the save in the background.
	 * This method is called in the UI thread. If this saveable supports saving in
	 * the background, it should do only minimal work. However, since the job
	 * runnable returned by this method (if any) will not run on the UI thread, this
	 * method should copy any state that can only be accessed from the UI thread so
	 * that the job runnable will be able to access it.
	 * <p>
	 * The supplied shell provider can be used from within this method and from
	 * within the job runnable for the purpose of parenting dialogs. Care should be
	 * taken not to open dialogs gratuitously and only if user input is required for
	 * cases where the save cannot otherwise proceed - note that in any given save
	 * operation, many saveable objects may be saved at the same time. In
	 * particular, errors should be signaled by throwing an exception, or if an
	 * error occurs while running the job runnable, an error status should be
	 * returned.
	 * </p>
	 * <p>
	 * If the foreground part of the save is cancelled through user action, or for
	 * any other reason, the part should invoke <code>setCancelled</code> on the
	 * <code>IProgressMonitor</code> to inform the caller. If the background part of
	 * the save is cancelled, the job should return a {@link IStatus#CANCEL} status.
	 * </p>
	 * <p>
	 * This method is long-running; progress and cancellation are provided by the
	 * given progress monitor.
	 * </p>
	 * <p>
	 * The default implementation of this method calls
	 * {@link #doSave(IProgressMonitor)} and returns <code>null</code>.
	 * </p>
	 *
	 * @param monitor       a progress monitor used for reporting progress and
	 *                      cancellation
	 * @param shellProvider an object that can provide a shell for parenting dialogs
	 * @return <code>null</code> if this saveable has been saved successfully, or a
	 *         job runnable that needs to be run to complete the save in the
	 *         background.
	 * @throws CoreException if the save fails; it is the caller's responsibility to
	 *                       report the failure to the user
	 * @since 3.3
	 */
	public IJobRunnable doSave(IProgressMonitor monitor, IShellProvider shellProvider) throws CoreException {
		doSave(monitor);
		return null;
	}

	/**
	 * Disables the UI of the given parts containing this saveable if necessary.
	 * This method is not intended to be called by clients. A corresponding call to
	 * <p>
	 * Saveables that can be saved in the background should ensure that the user
	 * cannot make changes to their data from the UI, for example by disabling
	 * controls, unless they are prepared to handle this case. This method is called
	 * on the UI thread after a job runnable has been returned from
	 * {@link #doSave(IProgressMonitor, IShellProvider)} and before spinning the
	 * event loop. The <code>closing</code> flag indicates that this saveable is
	 * currently being saved in response to closing a workbench part, in which case
	 * further changes to this saveable through the UI must be prevented.
	 * </p>
	 * <p>
	 * The default implementation calls setEnabled(false) on the given parts'
	 * composites.
	 * </p>
	 *
	 * @param parts   the workbench parts containing this saveable
	 * @param closing a boolean flag indicating whether the save was triggered by a
	 *                request to close a workbench part, and all of the given parts
	 *                will be closed after the save operation finishes successfully.
	 *
	 * @since 3.3
	 */
	public void disableUI(IWorkbenchPart[] parts, boolean closing) {
		for (IWorkbenchPart workbenchPart : parts) {
			Composite paneComposite = (Composite) ((PartSite) workbenchPart.getSite()).getModel().getWidget();
			Control[] paneChildren = paneComposite.getChildren();
			Composite toDisable = ((Composite) paneChildren[0]);
			toDisable.setEnabled(false);
			if (waitCursor == null) {
				waitCursor = workbenchPart.getSite().getWorkbenchWindow().getShell().getDisplay()
						.getSystemCursor(SWT.CURSOR_WAIT);
			}
			if (waitCursor.equals(paneComposite.getCursor())) {
				originalCursor = paneComposite.getCursor();
				paneComposite.setCursor(waitCursor);
			}
		}
	}

	/**
	 * Enables the UI of the given parts containing this saveable after a background
	 * save operation has finished. This method is not intended to be called by
	 * clients.
	 * <p>
	 * The default implementation calls setEnabled(true) on the given parts'
	 * composites.
	 * </p>
	 *
	 * @param parts the workbench parts containing this saveable
	 *
	 * @since 3.3
	 */
	public void enableUI(IWorkbenchPart[] parts) {
		for (IWorkbenchPart workbenchPart : parts) {
			Composite paneComposite = (Composite) ((PartSite) workbenchPart.getSite()).getModel().getWidget();
			Control[] paneChildren = paneComposite.getChildren();
			Composite toEnable = ((Composite) paneChildren[0]);
			paneComposite.setCursor(originalCursor);
			if (waitCursor != null) {
				/*
				 * waitCursor is always the System SWT.CURSOR_WAIT instance and should never be
				 * disposed
				 */
				waitCursor = null;
			}
			toEnable.setEnabled(true);
		}
	}

	/**
	 * This implementation of {@link IAdaptable#getAdapter(Class)} returns
	 * <code>null</code>. Subclasses may override. This allows two unrelated
	 * subclasses of Saveable to implement {@link #equals(Object)} and
	 * {@link #hashCode()} based on an underlying implementation class that is
	 * shared by both Saveable subclasses.
	 *
	 * @since 3.3
	 */
	@Override
	public <T> T getAdapter(Class<T> adapter) {
		return null;
	}
}
