/*******************************************************************************
 * Copyright (c) 2006, 2009 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.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.rwt.graphics.Graphics;
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 1.0
 */
public abstract class Saveable extends InternalSaveable implements IAdaptable {

	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
	 */
	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
	 * @return true if this Saveable is equal to the given object
	 */
	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
	 */
	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
	 */
	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.
	 */
	public void disableUI(IWorkbenchPart[] parts, boolean closing) {
		for (int i = 0; i < parts.length; i++) {
			IWorkbenchPart workbenchPart = parts[i];
			Composite paneComposite = (Composite) ((PartSite) workbenchPart
					.getSite()).getPane().getControl();
			Control[] paneChildren = paneComposite.getChildren();
			Composite toDisable = ((Composite) paneChildren[0]);
			toDisable.setEnabled(false);
			if (waitCursor == null) {
				waitCursor = new Cursor(workbenchPart.getSite().getWorkbenchWindow().getShell().getDisplay(), SWT.CURSOR_WAIT);
			}
			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
	 */
	public void enableUI(IWorkbenchPart[] parts) {
		for (int i = 0; i < parts.length; i++) {
			IWorkbenchPart workbenchPart = parts[i];
			Composite paneComposite = (Composite) ((PartSite) workbenchPart
					.getSite()).getPane().getControl();
			Control[] paneChildren = paneComposite.getChildren();
			Composite toEnable = ((Composite) paneChildren[0]);
			paneComposite.setCursor(originalCursor);
			if (waitCursor!=null && !waitCursor.isDisposed()) {
				waitCursor.dispose();
				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.
	 */
	public Object getAdapter(Class adapter) {
		return null;
	}
}
