// NewIdentifiableWizard.java
package org.eclipse.stem.ui.wizards;

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

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.ui.action.WorkbenchWindowActionDelegate;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.stem.core.Utility;
import org.eclipse.stem.core.common.Identifiable;
import org.eclipse.stem.core.common.presentation.CoreEditorAdvisor;
import org.eclipse.stem.ui.Activator;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.actions.WorkspaceModifyOperation;

/**
 * This class is the super class for the {@link Wizard}s that create
 * {@link Identifiable}s. The basic {@link Identifiable} wizard contains two
 * {@link WizardPage}s. The first is a subclass instance of the abstract class
 * {@link NewIdentifiablePage} and the second is an instance of
 * {@link DublinCorePage}. The {@link NewIdentifiablePage} implements the
 * template pattern by creating an overall structure for the page that is filled
 * in by the results of calls to abstract methods implemented by the subclasses.
 * 
 * @see org.eclipse.stem.core.common.Identifiable
 * @see org.eclipse.stem.core.graph.Graph
 * @see org.eclipse.stem.core.model.Model
 * @see org.eclipse.stem.core.scenario.Scenario
 */
abstract public class NewIdentifiableWizard extends Wizard implements
		INewWizard {

	/**
	 * The wizard's link to the {@link IWorkbench}.
	 */
	private IWorkbench workbench;

	/**
	 * The first page in the wizard that a user uses to specify the details of a
	 * new {@link Identifiable} to be created.
	 * 
	 * @see #newDublinCorePage
	 */
	protected NewIdentifiablePage newIdentifiablePage = null;

	/**
	 * The second page in the wizard that a user uses to specify the details of
	 * the {@link org.eclipse.stem.core.common.DublinCore} metadata associated with the {@link Identifiable}
	 * being created.
	 * 
	 * @see #newIdentifiablePage
	 */
	public DublinCorePage newDublinCorePage;

	/**
	 * This is the context sensitive help context id for the wizard
	 */
	
	protected String helpContextId;
	
	protected String getHelpContextId() {
		return helpContextId;
	}

	protected void setHelpContextId(String helpContextId) {
		this.helpContextId = helpContextId;
	}

	/**
	 * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench,
	 *      org.eclipse.jface.viewers.IStructuredSelection)
	 */
	public void init(final IWorkbench workbench,
			@SuppressWarnings("unused") final IStructuredSelection selection) {
		this.workbench = workbench;
		setWindowTitle(getWizardTitle());
		setHelpAvailable(true);
	} // init


	/**
	 * Create the {@link Wizard}'s pages.
	 * 
	 * @see org.eclipse.jface.wizard.Wizard#addPages()
	 */
	@Override
	public void addPages() {
		super.addPages();
		setForcePreviousAndNextButtons(false);
		newIdentifiablePage = createNewIdentifiablePage();
		// Were we successful in creating the page?
		if (newIdentifiablePage == null) {
			// No
			return;
		}
		newDublinCorePage = createDublinCorePage();
		// Were we successful in creating the page?
		if (newDublinCorePage == null) {
			// No
			return;
		}
		addPage(newIdentifiablePage);
		addPage(newDublinCorePage);
	} // addPages

	/**
	 * @param page
	 *            the {@link IWizardPage} page currently being displayed.
	 * @return the next {@link IWizardPage} to be displayed to the user.
	 */
	@Override
	public IWizardPage getNextPage(final IWizardPage page) {
		final IWizardPage nextPage = super.getNextPage(page);
		// Dublin Core next?
		if (nextPage instanceof DublinCorePage) {
			// Yes
			// We pre-populate some of the fields in the DublinCore page with
			// values obtained from the newIdentifaiblePage that the user has
			// just completed. The exact details are specific to the type of
			// Identifiable being created.
			final DublinCorePage dcPage = (DublinCorePage) nextPage;
			
			// JHK TODO it would be nice to append the name to the title field
			// construct the title
			/*
			String title = dcPage.titleTextField.getText();
			StringBuilder sb= new StringBuilder();
			if((title != null)&&(title.length()>=1)) {
				sb.append(title);
			}
			if(sb.length()>1) sb.append(" ");
			sb.append(getSerializationFileName());
			dcPage.titleTextField.setText(sb.toString());
			*/			
		} // if DublinCorePage
		return nextPage;
	} // getNextPage

	/**
	 * @see org.eclipse.jface.wizard.Wizard#performFinish()
	 */
	@Override
	public boolean performFinish() {
		// This is executed when the user clicks on the "Finish" button of the
		// wizard. It uses the details in the two pages (newIdentifiablePage and
		// newDublinCorePage) to create the Identifiable. It serializes the
		// Identifiable in a file in the project that was selected on the
		// newIdentifablePage.
		final boolean retValue = true;
		try {
			// The fileURI specifies where the Identifiable will be serialized
			final URI serializationURI = createSerializationURI();

			// Creating the Identifiable can potentially take a while so we
			// wrap the call to createIdentifable in an "operation" so that it
			// can be run in the background.
			final WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
				@Override
				protected void execute(final IProgressMonitor monitor) {
					createIdentifiable(
							monitor == null ? new NullProgressMonitor()
									: monitor, serializationURI);
				} // execute
			}; // WorkspaceModifyOperation

			// The container is a IRunnableContext, we use it to execute the
			// operation we created above. The first argument of false indicates
			// not to "fork", the second of "true" indicates that the operation
			// is cancelable.
			getContainer().run(false, true, op);

			// Refresh the project so that the new serialized file will display
			try {
				newIdentifiablePage.getSelectedProject().refreshLocal(
						IResource.DEPTH_INFINITE, null);
			} catch (final CoreException e) {
				// Ignore
			}
			// Now open up the appropriate editor for the new Identifiable.
//			return CoreEditorAdvisor.openEditor(workbench, CommonPlugin
//					.asLocalURI(serializationURI));
			return CoreEditorAdvisor.openEditor(workbench, serializationURI);

		} // try
		catch (final InvocationTargetException e) {
			Activator.logError(Activator.PLUGIN_ID, e);
		} catch (final InterruptedException e) {
			// This gets thrown if the operation is canceled
			Activator.logInformation(Activator.PLUGIN_ID, e);
		}
		return retValue;

	} // performFinish

	/**
	 * Create the specific {@link Identifiable} as specified by the contents of
	 * the wizard pages and serialize it in the file specified by the
	 * {@link URI} returned by {@link #createSerializationURI()}.
	 * 
	 * @param monitor
	 *            a {@link IProgressMonitor} to use to report our progress
	 * @param serializationURI
	 *            the {@link URI} of the serialization file
	 * @see #performFinish()
	 */
	void createIdentifiable(IProgressMonitor monitor, final URI serializationURI) {
		// Was a progress monitor specified?
		if (monitor == null) {
			// No
			monitor = new NullProgressMonitor();
		}

		monitor.beginTask(Messages.getString("NIdWiz.creating"), 100); //$NON-NLS-1$
		try {
			// Create the Identifiable from the contents of the Wizard
			// Pages.
			final Identifiable identifiable = createIdentifiable();
			identifiable.setURI(serializationURI);
			assert identifiable.sane();

			Utility.serializeIdentifiable(identifiable, serializationURI);
		} catch (final IOException e) {
			Activator.logError(Messages.getString("NIdWiz.saveErr"), e); //$NON-NLS-1$
		} catch (final Exception e) {
			Activator.logError(Messages.getString("NIdWiz.saveErr"), e); //$NON-NLS-1$
		} finally {
			monitor.done();
		}
	} // createIdentifiable

	/**
	 * Create the {@link URI} to be used to serialize the {@link Identifiable}
	 * created in {@link #performFinish()}. The path in the {@link URI} will
	 * place the serialization file into the project returned by
	 * {@link #getSelectedProject()}. The name of the folder in the project is
	 * supplied by {@link #getSerializationFolderName()} which is overridden by
	 * a subclass. The name of the file and the file extension are provided by
	 * the methods {@link #getSerializationFileName()} and
	 * {@link #getSerializationFileNameExtension()}, both of which are
	 * implemented by a subclass.
	 * 
	 * @return the {@link URI} that will be used to serialize the
	 *         {@link Identifiable} created in {@link #performFinish()}.
	 * 
	 * @see #createIdentifiable(IProgressMonitor, URI)
	 */
	private URI createSerializationURI() {

		final StringBuilder sb = new StringBuilder(newIdentifiablePage
				.getSelectedProject().getName());
		sb.append("/"); //$NON-NLS-1$
		sb.append(getSerializationFolderName());
		sb.append("/"); //$NON-NLS-1$
		sb.append(getSerializationFileName());
		sb.append("."); //$NON-NLS-1$
		sb.append(getSerializationFileNameExtension());

		return URI.createPlatformResourceURI(sb.toString(), true);
	} // createSerializationURI

	/**
	 * @return the name of the serialization file for the {@link Identifiable}
	 *         entered by the user on {@link #newIdentifiablePage}.
	 */
	private String getSerializationFileName() {
		return newIdentifiablePage.serializationFileNameField.getText();
	} // getSerializationFileName

	/**
	 * @return the title of the Wizard for use as the title of the window.
	 */
	abstract protected String getWizardTitle();

	/**
	 * This method is implemented by subclasses to create a {@link WizardPage}
	 * that is specific to the type of {@link Identifiable} that is being
	 * created.
	 * 
	 * @return the page used to specify the new {@link Identifiable} to create.
	 * @see #createDublinCorePage()
	 */
	abstract protected NewIdentifiablePage createNewIdentifiablePage();

	/**
	 * This method is implemented by subclasses to create a
	 * {@link DublinCorePage} that is specific to the type of
	 * {@link Identifiable} that is being created. Typically, the method will
	 * create a {@link DublinCorePage} with some of the fields pre-populated
	 * with values specific to the {@link Identifiable}.
	 * 
	 * @return a pre-populated {@link DublinCorePage}.
	 * @see #createNewIdentifiablePage()
	 */
	abstract protected DublinCorePage createDublinCorePage();

	/**
	 * This method is implemented by subclasses to create the specific type of
	 * {@link Identifiable} that the {@link #newIdentifiablePage} that they
	 * returned from {@link #createNewIdentifiablePage()} specifies.
	 * 
	 * @return the specific type of {@link Identifiable} created by a subclasses
	 *         of this class.
	 */
	abstract protected Identifiable createIdentifiable();

	/**
	 * @return the name of the folder under the selected project that the
	 *         {@link Identifiable} created by
	 *         {@link #createIdentifiable(IProgressMonitor, URI)} should be
	 *         serialized in.
	 * @see #getSelectedProject()
	 * @see #createSerializationURI()
	 */
	abstract protected String getSerializationFolderName();

	/**
	 * @return the file extension of the serialization file of the
	 *         {@link Identifiable} created by
	 *         {@link #createIdentifiable(IProgressMonitor, URI)}. Typically,
	 *         this is the EMF "eNAME" of the model in which the
	 *         {@link Identifiable} is defined.
	 * @see org.eclipse.stem.core.graph.GraphPackage#eNAME
	 * @see org.eclipse.stem.core.model.ModelPackage#eNAME
	 * @see org.eclipse.stem.core.scenario.ScenarioPackage#eNAME
	 * @see  org.eclipse.stem.core.experiment.ExperimentPackage#eNAME
	 */
	abstract protected String getSerializationFileNameExtension();

	/**
	 * Run the Wizard from an Action
	 */
	abstract protected static class NewIdentifiableWizardAction extends
			WorkbenchWindowActionDelegate {
		protected void run(final NewIdentifiableWizard wizard) {
			wizard.init(getWindow().getWorkbench(), StructuredSelection.EMPTY);
			final WizardDialog wizardDialog = new WizardDialog(getWindow()
					.getShell(), wizard);
			wizardDialog.open();
		} // run
	} // NewIdentifiableWizardAction

} // NewIdentifiableWizard
