/**
 * File:    ViewConfWizard.java
 * Created: 15.12.2008
 *
 *
/*******************************************************************************
 * Copyright (c) 2005-2011
 * University of Augsburg, Germany <www.ds-lab.org>
 *
 * 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:
 *    Christian Saad, Programming distributed Systems Lab, University of Augsburg 
 *    	- initial API and implementation
 *******************************************************************************/

package org.eclipse.jwt.we.misc.wizards.view;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.commands.Command;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jwt.meta.model.processes.Scope;
import org.eclipse.jwt.we.Plugin;
import org.eclipse.jwt.we.PluginProperties;
import org.eclipse.jwt.we.commands.view.CreateLayoutDataCommand;
import org.eclipse.jwt.we.commands.view.ImportLayoutDataCommand;
import org.eclipse.jwt.we.misc.logging.Logger;
import org.eclipse.jwt.we.misc.util.GeneralHelper;
import org.eclipse.jwt.we.misc.views.LayoutDataManager;
import org.eclipse.jwt.we.misc.views.Views;
import org.eclipse.jwt.we.misc.wizards.view.pages.ActivityViewConfWizardPage;
import org.eclipse.jwt.we.misc.wizards.view.pages.CreateViewConfWizardPage;
import org.eclipse.jwt.we.misc.wizards.view.pages.ImportViewConfWizardPage;
import org.eclipse.jwt.we.misc.wizards.view.pages.ModeViewConfWizardPage;
import org.eclipse.jwt.we.misc.wizards.view.pages.PreviewViewConfWizardPage;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;

/**
 * A wizard to configure the positions and dimensions of elements in a view. The
 * layoutdata can be imported from another view, synchronized with another view
 * or created using a layouting algorithm.
 * 
 * @version $Id: ViewConfWizard.java,v 1.5 2009-11-27 14:27:56 chsaad Exp $
 * @author Christian Saad (csaad@gmx.net), Programming distributed Systems Lab,
 *         University of Augsburg, Germany, www.ds-lab.org
 */
public class ViewConfWizard extends Wizard implements INewWizard
{

	/**
	 * A Logger.
	 */
	static final Logger logger = Logger.getLogger(ViewConfWizard.class);

	/**
	 * Select import/sync/create mode.
	 */
	protected ModeViewConfWizardPage modePage;

	/**
	 * Viewdata import mode.
	 */
	protected ImportViewConfWizardPage importPage;

	/**
	 * Viewdata create mode.
	 */
	protected CreateViewConfWizardPage createPage;

	/**
	 * Activity page.
	 */
	protected ActivityViewConfWizardPage activityPage;

	/**
	 * Preview page.
	 */
	protected PreviewViewConfWizardPage previewPage;

	/**
	 * Remember the workbench during initialization.
	 */
	protected IWorkbench workbench;

	/**
	 * The command to apply and undo the preview.
	 */
	private Command previewLayoutCommand;


	/**
	 * This just records the information.
	 * 
	 * @param workbench
	 *            The current workbench.
	 * @param selection
	 *            The current object selection.
	 */
	public void init(IWorkbench workbench, IStructuredSelection selection)
	{
		this.workbench = workbench;
		setWindowTitle(PluginProperties.wizards_ViewConf_title);
		setDefaultPageImageDescriptor(Plugin.getInstance().getFactoryRegistry()
				.getImageFactory(Views.getInstance().getSelectedView())
				.createImageDescriptor(PluginProperties.editor_Wizard_icon));
	}


	/**
	 * The framework calls this to create the contents of the wizard.
	 */
	@Override
	public void addPages()
	{
		// select mode
		modePage = new ModeViewConfWizardPage("mode", workbench); //$NON-NLS-1$
		modePage.setTitle(PluginProperties.wizards_ViewConfSelect_title);
		addPage(modePage);

		// import mode
		importPage = new ImportViewConfWizardPage("import", workbench); //$NON-NLS-1$
		importPage.setTitle(PluginProperties.wizards_ViewConfImport_title);
		addPage(importPage);

		// create mode
		createPage = new CreateViewConfWizardPage("create", workbench); //$NON-NLS-1$
		createPage.setTitle(PluginProperties.wizards_ViewConfCreate_title);
		addPage(createPage);

		// select activities
		activityPage = new ActivityViewConfWizardPage("activity", workbench); //$NON-NLS-1$
		activityPage.setTitle(PluginProperties.wizards_ViewConfActivity_title);
		addPage(activityPage);

		// preview
		previewPage = new PreviewViewConfWizardPage("preview", workbench);
		previewPage.setTitle(PluginProperties.wizards_ViewConfPreview_title);
		addPage(previewPage);
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.wizard.Wizard#canFinish()
	 */
	@Override
	public boolean canFinish()
	{
		if (modePage.isImportMode())
		{
			return getPage("import").isPageComplete();
		}
		else if (modePage.isCreateMode())
		{
			return getPage("create").isPageComplete();
		}

		return false;
	}


	/**
	 * Do the work after everything is specified.
	 * 
	 * @return <code>true</code>, if the wizards completes sucessfully.
	 *         <code>false</code> if an error occured or the dialog was
	 *         cancelled.
	 */
	@Override
	@SuppressWarnings("unchecked")
	public boolean performFinish()
	{
		// remove preview layoutdata (if preview page is active)
		disposePreview();

		// call perform finish
		if (modePage.isImportMode())
		{
			return performFinishImport();
		}
		else if (modePage.isCreateMode())
		{
			return performFinishCreate();
		}

		return false;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.wizard.Wizard#performCancel()
	 */
	@Override
	public boolean performCancel()
	{
		// remove preview layoutdata (if preview page is active)
		disposePreview();

		return super.performCancel();
	}


	/**
	 * Do the work after everything is specified.
	 * 
	 * @return <code>true</code>, if the wizards completes sucessfully.
	 *         <code>false</code> if an error occured or the dialog was
	 *         cancelled.
	 */
	public boolean performFinishImport()
	{
		Set<Scope> selectedScopes = collectContainedScopes();

		// import layoutdata
		LayoutDataManager.importLayoutData(GeneralHelper.getActiveInstance(),
				selectedScopes, importPage.getSelectedViewID(), Views.getInstance()
						.getSelectedView().getInternalName(), importPage
						.isImportOnlyMissingLayoutData());
		return true;
	}


	/**
	 * Do the work after everything is specified.
	 * 
	 * @return <code>true</code>, if the wizards completes sucessfully.
	 *         <code>false</code> if an error occured or the dialog was
	 *         cancelled.
	 */
	@SuppressWarnings("unchecked")
	public boolean performFinishCreate()
	{
		Set<Scope> selectedScopes = collectContainedScopes();

		// create layoutdata
		LayoutDataManager.createLayoutData(GeneralHelper.getActiveInstance(),
				selectedScopes, createPage.getSelectedLayoutClass());
		return true;
	}


	/**
	 * Undo the layoutdata changes for the preview (called on entering select
	 * activity page = leaving preview page and before! cancel/close).
	 */
	public void disposePreview()
	{
		if (previewLayoutCommand != null)
		{
			previewLayoutCommand.undo();
			previewLayoutCommand.dispose();
			previewLayoutCommand = null;
		}
	}


	/**
	 * Update the layoutdata according to the preview (called on entering
	 * preview page).
	 */
	public void updatePreview()
	{
		// dispose/undo old preview
		disposePreview();

		Set<Scope> selectedScopes = collectContainedScopes();

		// update preview by applying the current settings in an undoable
		// command
		if (((ModeViewConfWizardPage) getPage("mode")).isImportMode())
		{
			ImportViewConfWizardPage importPage = ((ImportViewConfWizardPage) getPage("import"));
			previewLayoutCommand = new ImportLayoutDataCommand(GeneralHelper
					.getActiveInstance(), selectedScopes, importPage.getSelectedViewID(),
					Views.getInstance().getSelectedView().getInternalName(), importPage
							.isImportOnlyMissingLayoutData());
			previewLayoutCommand.execute();
		}
		else if (((ModeViewConfWizardPage) getPage("mode")).isCreateMode())
		{
			CreateViewConfWizardPage createPage = ((CreateViewConfWizardPage) getPage("create"));
			previewLayoutCommand = new CreateLayoutDataCommand(GeneralHelper
					.getActiveInstance(), selectedScopes, createPage
					.getSelectedLayoutClass());
			previewLayoutCommand.execute();
		}
	}


	/**
	 * Collects all scopes contained in an activity.
	 * 
	 * @return
	 */
	private Set<Scope> collectContainedScopes()
	{
		Set<Scope> selectedScopes = new HashSet<Scope>();
		selectedScopes.addAll(activityPage.getSelectedActivities());

		// collect contained scopes
		for (Scope scope : activityPage.getSelectedActivities())
		{
			for (Iterator iter = scope.eAllContents(); iter.hasNext();)
			{
				EObject object = (EObject) iter.next();

				if (object instanceof Scope)
				{
					selectedScopes.add((Scope) object);
				}
			}
		}
		return selectedScopes;
	}

}