/***************************************************************************************************
 * Copyright (c) 2003, 2004 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.wst.common.modulecore;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.wst.common.frameworks.internal.operations.IOperationHandler;
import org.eclipse.wst.common.internal.emfworkbench.edit.EditModelRegistry;
import org.eclipse.wst.common.internal.emfworkbench.integration.EditModel;
import org.eclipse.wst.common.internal.emfworkbench.integration.EditModelListener;
import org.eclipse.wst.common.internal.emfworkbench.integration.IEditModelFactory;

import com.ibm.wtp.internal.emf.workbench.nls.EMFWorkbenchResourceHandler;

/**
 * Provides a Facade pattern for accessing Module Content Metamodels for Web Tools Platform flexible
 * modules.
 * <p>
 * ArtifactEdit hides the management of accessing edit models ({@see ArtifactEditModel})
 * correctly. Each project may have multiple ({@see ArtifactEditModel})s depending on the number
 * of modules contained by the project. Clients should use ArtifactEdit or an appropriate subclass
 * when working with the content models of WTP modules.
 * </p>
 * 
 * <p>
 * Each ArtifactEdit facade is designed to manage the EditModel lifecycle for clients. However,
 * while each ArtifactEdit is designed to be passed around as needed, clients must enforce the
 * ArtifactEdit lifecycle. The most common method of acquiring a ArtifactEdit instance facade is to
 * use {@see #getArtifactEditForRead(WorkbenchComponent)}&nbsp;or
 * {@see #getArtifactEditForWrite(WorkbenchComponent)}.
 * </p>
 * <p>
 * When clients have concluded their use of the instance, <b>clients must call {@see #dispose()}
 * </b>.
 * </p>
 * <p>
 * This class is experimental until fully documented.
 * </p>
 * 
 * @see ModuleCoreNature
 * @see ArtifactEditModel
 */
public class ArtifactEdit implements IEditModelHandler {

	public static final Class ADAPTER_TYPE = ArtifactEdit.class;
	private final ArtifactEditModel artifactEditModel;
	private boolean isReadOnly;
	private boolean isArtifactEditModelSelfManaged;
	protected WorkbenchComponent module;

	/**
	 * <p>
	 * Returns an instance facade to manage the underlying edit model for the given
	 * {@see WorkbenchComponent}. Instances of ArtifactEdit that are returned through this method must
	 * be {@see #dispose()}ed of when no longer in use.
	 * </p>
	 * <p>
	 * Use to acquire an ArtifactEdit facade for a specific {@see WorkbenchComponent}&nbsp;that will
	 * not be used for editing. Invocations of any save*() API on an instance returned from this
	 * method will throw exceptions.
	 * </p>
	 * <p>
	 * <b>The following method may return null. </b>
	 * </p>
	 * 
	 * @param aModule
	 *            A valid {@see WorkbenchComponent}&nbsp;with a handle that resolves to an accessible
	 *            project in the workspace
	 * @return An instance of ArtifactEdit that may only be used to read the underlying content
	 *         model
	 */
	public static ArtifactEdit getArtifactEditForRead(WorkbenchComponent aModule) {
		try {
			if (isValidEditableModule(aModule)) {
				IProject project = ModuleCore.getContainingProject(aModule.getHandle());
				ModuleCoreNature nature = ModuleCoreNature.getModuleCoreNature(project);
				return new ArtifactEdit(nature, aModule, true);
			}
		} catch (UnresolveableURIException uue) {
		}
		return null;
	}

	/**
	 * <p>
	 * Returns an instance facade to manage the underlying edit model for the given
	 * {@see WorkbenchComponent}. Instances of ArtifactEdit that are returned through this method must
	 * be {@see #dispose()}ed of when no longer in use.
	 * </p>
	 * <p>
	 * Use to acquire an ArtifactEdit facade for a specific {@see WorkbenchComponent}&nbsp;that will
	 * be used for editing.
	 * </p>
	 * <p>
	 * <b>The following method may return null. </b>
	 * </p>
	 * 
	 * @param aModule
	 *            A valid {@see WorkbenchComponent}&nbsp;with a handle that resolves to an accessible
	 *            project in the workspace
	 * @return An instance of ArtifactEdit that may be used to modify and persist changes to the
	 *         underlying content model
	 */
	public static ArtifactEdit getArtifactEditForWrite(WorkbenchComponent aModule) {
		try {
			if (isValidEditableModule(aModule)) {
				IProject project = ModuleCore.getContainingProject(aModule.getHandle());
				ModuleCoreNature nature = ModuleCoreNature.getModuleCoreNature(project);
				return new ArtifactEdit(nature, aModule, false);
			}
		} catch (UnresolveableURIException uue) {
		}
		return null;
	}

	/**
	 * @param module
	 *            A {@see WorkbenchComponent}
	 * @return True if the supplied module has a moduleTypeId which has a defined
	 *         {@see IEditModelFactory}&nbsp;and is contained by an accessible project
	 */
	public static boolean isValidEditableModule(WorkbenchComponent aModule) throws UnresolveableURIException {
		/* The ComponentType must be non-null, and the moduleTypeId must be non-null */
		ComponentType moduleType = aModule.getComponentType();
		if (moduleType == null || moduleType.getModuleTypeId() == null)
			return false;
		if(aModule.getHandle() == null)
			return false;
		/* and the containing project must be resolveable and accessible */
		IProject project = ModuleCore.getContainingProject(aModule.getHandle());
		if (project == null || !project.isAccessible())
			return false;
		/* and an edit model factory must be defined for the module type */
		IEditModelFactory factory = EditModelRegistry.getInstance().findEditModelFactoryByKey(moduleType.getModuleTypeId());
		if (factory == null)
			return false;
		return true;
	}


	/**
	 * <p>
	 * Creates an instance facade for the given {@see ArtifactEditModel}.
	 * </p>
	 * 
	 * @param anArtifactEditModel
	 */
	public ArtifactEdit(ArtifactEditModel anArtifactEditModel) {
		artifactEditModel = anArtifactEditModel;
		isReadOnly = artifactEditModel.isReadOnly();
		isArtifactEditModelSelfManaged = false;
	}

	/**
	 * <p>
	 * Creates an instance facade for the given {@see WorkbenchComponent}.
	 * </p>
	 * 
	 * @param aNature
	 *            A non-null {@see ModuleCoreNature}&nbsp;for an accessible project
	 * @param aModule
	 *            A non-null {@see WorkbenchComponent}&nbsp;pointing to a module from the given
	 *            {@see ModuleCoreNature}
	 */
	public ArtifactEdit(ModuleCoreNature aNature, WorkbenchComponent aModule, boolean toAccessAsReadOnly) {
		if (toAccessAsReadOnly)
			artifactEditModel = aNature.getArtifactEditModelForRead(aModule.getHandle(), this);
		else
			artifactEditModel = aNature.getArtifactEditModelForWrite(aModule.getHandle(), this);
		isReadOnly = toAccessAsReadOnly;
		isArtifactEditModelSelfManaged = true;
	}


	/**
	 * <p>
	 * Force a save of the underlying model. The following method should be used with care. Unless
	 * required, use {@see #saveIfNecessary(IProgressMonitor)}&nbsp; instead.
	 * </p>
	 * 
	 * @see org.eclipse.wst.common.modulecore.IEditModelHandler#save()
	 * @throws IllegalStateException
	 *             If the ModuleCore object was created as read-only
	 */
	public void save(IProgressMonitor aMonitor) {
		if (isReadOnly)
			throwAttemptedReadOnlyModification();
		artifactEditModel.save(aMonitor, this);
	}

	/**
	 * <p>
	 * Save the underlying model only if no other clients are currently using the model. If the
	 * model is not shared, it will be saved. If it is shared, the save will be deferred.
	 * </p>
	 * 
	 * @see org.eclipse.wst.common.modulecore.IEditModelHandler#saveIfNecessary()
	 * @throws IllegalStateException
	 *             If the ModuleCore object was created as read-only
	 */
	public void saveIfNecessary(IProgressMonitor aMonitor) {
		if (isReadOnly)
			throwAttemptedReadOnlyModification();
		artifactEditModel.saveIfNecessary(aMonitor, this);
	}
	/**
	 * Save only if necessary. If typically a save would not occur because this edit model is
	 * shared, the user will be prompted using the
	 * 
	 * @operationHandler. If the prompt returns true (the user wants to save) the entire edit model
	 *                    will be saved. You may pass in a boolean <code>wasDirty</code> to
	 *                    indicate whether this edit model was dirty prior to making any changes and
	 *                    calling this method. {@link EditModel#isDirty()}
	 */
	public void saveIfNecessaryWithPrompt(IProgressMonitor monitor, IOperationHandler operationHandler, boolean wasDirty) {

		if (shouldSave(operationHandler, wasDirty))
			saveIfNecessary(monitor);
		else
			handleSaveIfNecessaryDidNotSave(monitor);
	}
	/**
	 * Default is to do nothing. This method is called if a saveIfNecessary or
	 * saveIfNecessaryWithPrompt determines not to save. This provides subclasses with an
	 * opportunity to do some other action.
	 */
	private void handleSaveIfNecessaryDidNotSave(IProgressMonitor monitor) {
		//do nothing
	}
	/**
	 * Should the resources be saved.
	 */
	private boolean shouldSave(IOperationHandler operationHandler, boolean wasDirty) {
		return !wasDirty ? shouldSave() : shouldSave(operationHandler);
	}
	/**
	 * Prompt for a save.
	 */
	private boolean promptToSave(IOperationHandler operationHandler) {
		if (operationHandler == null)
			return false;
		return operationHandler.canContinue(EMFWorkbenchResourceHandler.getString("The_following_resources_ne_UI_"), getArtifactEditModel().getResourceURIs(true)); //$NON-NLS-1$ = "The following resources need to be saved but are currently shared, do you want to save now?"
	}
	/**
	 * Should the resources be saved.
	 */
	private boolean shouldSave(IOperationHandler operationHandler) {
		return shouldSave() || promptToSave(operationHandler);
	}
	/**
	 * Should the resources be saved.
	 */
	private boolean shouldSave() {
		return !isReadOnly && isArtifactEditModelSelfManaged;
	}
	/**
	 * <p>
	 * Clients must call the following method when they have finished using the model, even if the
	 * ArtifactEdit instance facade was created as read-only.
	 * </p>
	 * 
	 * @see org.eclipse.wst.common.modulecore.IEditModelHandler#dispose()
	 */
	public void dispose() {
		if (isArtifactEditModelSelfManaged)
			artifactEditModel.releaseAccess(this);
	}

	/**
	 * <p>
	 * Returns the root object for read or write access (depending on how the current ArtifactEdit
	 * was loaded).
	 * </p>
	 * 
	 * @return The root object of the underlying model
	 */
	public EObject getContentModelRoot() {
		return artifactEditModel.getPrimaryRootObject();
	}

	/**
	 * <p>
	 * Add a listener to track lifecylce events from the underlying EditModel.
	 * </p>
	 * 
	 * @param listener
	 *            A non-null EditModelListener
	 */
	public void addListener(EditModelListener listener) {
		artifactEditModel.addListener(listener);
	}

	/**
	 * <p>
	 * Remove the supplied listener
	 * </p>
	 * 
	 * @param listener
	 *            A non-null EditModelListener
	 */
	public void removeListener(EditModelListener listener) {
		artifactEditModel.removeListener(listener);
	}

	/**
	 * <p>
	 * This method may be removed soon. Avoid adding dependencies to it.
	 * </p>
	 * 
	 * @param editModel
	 * @return
	 */
	public boolean hasEditModel(EditModel editModel) {
		return artifactEditModel == editModel;
	}

	/**
	 * @return The underlying managed edit model
	 */
	protected ArtifactEditModel getArtifactEditModel() {
		return artifactEditModel;
	}

	private void throwAttemptedReadOnlyModification() {
		throw new IllegalStateException("Attempt to modify an ArtifactEdit instance facade that was loaded as read-only.");
	}
}