//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.publishing.ui.wizards;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.publishing.services.PublishHTMLOptions;
import org.eclipse.epf.publishing.services.PublishManager;
import org.eclipse.epf.publishing.services.PublishOptions;
import org.eclipse.epf.publishing.ui.PublishingUIPlugin;
import org.eclipse.epf.publishing.ui.PublishingUIResources;
import org.eclipse.epf.publishing.ui.preferences.PublishingUIPreferences;
import org.eclipse.epf.ui.wizards.BaseWizard;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;

/**
 * A wizard that guides the user to publish a method configuration to a web
 * site.
 * 
 * @author Kelvin Low
 * @author Bingxue Xu
 * @author Jinhua Xi
 * @since 1.0
 */
public class PublishConfigWizard extends BaseWizard implements INewWizard {

	/**
	 * The wizard ID.
	 */
	public static final String WIZARD_ID = PublishConfigWizard.class.getName();

	/**
	 * The Publish Configuration wizard extension point ID.
	 */
	public static final String WIZARD_EXTENSION_POINT_ID = "org.eclipse.epf.publishing.ui.publishConfigWizard"; //$NON-NLS-1$	

	// The select configuration wizard page.
	protected SelectConfigPage selectConfigPage;

	// The select configuration content wizard page.
	protected SelectContentPage selectContentPage;

	// The select publishing options wizard page.
	protected SelectPublishingOptionsPage selectPublishingOptionsPage;

	// The select destination wizard page.
	protected SelectDestinationPage selectDestinationPage;

	/**
	 * Creates a new instance.
	 */
	public PublishConfigWizard() {
		super();
	}

	/**
	 * @see org.eclipse.epf.ui.wizards.BaseWizard#init(IWorkbench,
	 *      IStructuredSelection)
	 */
	public void init(IWorkbench workbench, IStructuredSelection selection) {
		super.init(workbench, selection);
		setWindowTitle(PublishingUIResources.publishConfigWizard_title);
	}

	/**
	 * @see org.eclipse.epf.ui.wizards.BaseWizard#getWizardExtenderExtensionPointId()
	 */
	public String getWizardExtenderExtensionPointId() {
		return WIZARD_EXTENSION_POINT_ID;
	}

	/**
	 * @see org.eclipse.jface.wizard.Wizard#addPages()
	 */
	public void addPages() {
		if (wizardExtender == null) {
			selectConfigPage = new SelectConfigPage();
			selectContentPage = new SelectContentPage();
			selectPublishingOptionsPage = new SelectPublishingOptionsPage();
			selectDestinationPage = new SelectDestinationPage();
			super.addPage(selectConfigPage);
			super.addPage(selectContentPage);
			super.addPage(selectPublishingOptionsPage);
			super.addPage(selectDestinationPage);
		} else {
			List<IWizardPage> wizardPages = new ArrayList<IWizardPage>();

			IWizardPage page = wizardExtender
					.getReplaceWizardPage(SelectConfigPage.PAGE_NAME);
			if (page != null) {
				wizardPages.add(page);
			} else {
				selectConfigPage = new SelectConfigPage();
				wizardPages.add(selectConfigPage);
			}

			page = wizardExtender
					.getReplaceWizardPage(SelectContentPage.PAGE_NAME);
			if (page != null) {
				wizardPages.add(page);
			} else {
				selectContentPage = new SelectContentPage();
				wizardPages.add(selectContentPage);
			}

			page = wizardExtender
					.getReplaceWizardPage(SelectPublishingOptionsPage.PAGE_NAME);
			if (page != null) {
				wizardPages.add(page);
			} else {
				selectPublishingOptionsPage = new SelectPublishingOptionsPage();
				wizardPages.add(selectPublishingOptionsPage);
			}

			page = wizardExtender
					.getReplaceWizardPage(SelectDestinationPage.PAGE_NAME);
			if (page != null) {
				wizardPages.add(page);
			} else {
				selectDestinationPage = new SelectDestinationPage();
				wizardPages.add(selectDestinationPage);
			}

			super.getNewWizardPages(wizardPages);

			for (Iterator it = wizardPages.iterator(); it.hasNext();) {
				IWizardPage wizardPage = (IWizardPage) it.next();
				super.addPage(wizardPage);
			}

			wizardExtender.initWizardPages(wizardPages);
		}
	}

	/**
	 * @see org.eclipse.jface.wizard.Wizard#createPageControls(Composite)
	 */
	public void createPageControls(Composite pageContainer) {
		super.createPageControls(pageContainer);
		pageContainer.getShell().setImage(
				AuthoringUIPlugin.getDefault().getSharedImage(
						"full/obj16/MethodConfiguration.gif")); //$NON-NLS-1$
	}

	/**
	 * @see org.eclipse.jface.wizard.Wizard#performFinish()
	 */
	public boolean performFinish() {
		if (wizardExtender != null) {
			return wizardExtender.doFinish();
		} else {
			PublishManager publisher = new PublishManager();
			boolean success = publishConfig(selectConfigPage.getConfigName(),
					getPublishingOptions(), publisher);
			if (publisher != null) {
				publisher.dispose();
			}
			return success;
		}
	}

	/**
	 * Publishes the selected method configuration.
	 * 
	 * @param configName
	 *            the method configuration name
	 * @param options
	 *            the publishing options
	 */
	public boolean publishConfig(String configName, PublishOptions options,
			PublishManager publisher) {
		try {
			if (checkAndCreateDir(options)) {
				MethodConfiguration config = LibraryServiceUtil
						.getMethodConfiguration(LibraryService.getInstance()
								.getCurrentMethodLibrary(), configName);

				publisher.init(options.getPublishDir(), config, options);
				PublishingOperation operation = new PublishingOperation(
						publisher);

				PublishProgressMonitorDialog dlg = new PublishProgressMonitorDialog(
						Display.getCurrent().getActiveShell(), publisher
								.getViewBuilder());

				UserInteractionHelper.runWithProgress(operation, dlg, true,
						PublishingUIResources.publishConfigWizard_title);

				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			PublishingUIPlugin.getDefault().getMsgDialog().displayError(
					PublishingUIResources.publishConfigWizard_title,
					PublishingUIResources.publishConfigError_msg,
					PublishingUIResources.publishConfigError_reason, e);
		} finally {
			if (selectPublishingOptionsPage != null) {
				selectPublishingOptionsPage.savePreferences();
			}
			if (selectDestinationPage != null) {
				selectDestinationPage.savePreferences();
			}
			MethodConfiguration config = LibraryServiceUtil
					.getMethodConfiguration(LibraryService.getInstance()
							.getCurrentMethodLibrary(), configName);
			String configId = config.getGuid();
			PublishingUIPreferences.setConfigPrefInitialized(configId, true);
			PublishingUIPreferences.saveAllPreferences();
		}

		return true;
	}

	/**
	 * Gets the user specified publishing options.
	 * 
	 * @return the user specified publishing options.
	 */
	public PublishOptions getPublishingOptions() {
		PublishOptions options;
		
		if (selectPublishingOptionsPage != null) {
			options = selectPublishingOptionsPage.getPublishingOptions();
		}
		else {
			options = new PublishOptions();
		}

		if (selectContentPage != null) {
			boolean publishConfig = selectContentPage.getPublishConfigSelection();
			options.setPublishConfiguration(publishConfig);
			options.setPublishProcess(!publishConfig);
			if (!publishConfig) {
				options.setProcesses(selectContentPage.getSelectedProcesses());
			}
		}
		
		if (selectDestinationPage != null) {
			options.setPublishDir(selectDestinationPage.getPublishDirectory());

			if (!selectDestinationPage.getStaticWebSiteSelection()
					&& options instanceof PublishHTMLOptions) {
				PublishHTMLOptions htmlOptions = (PublishHTMLOptions) options;
				htmlOptions.setPublishDynamicWebApp(true);
				htmlOptions.setDynamicWebAppName(selectDestinationPage
						.getWebAppName());
				htmlOptions.setIncludeServletSearch(selectDestinationPage
						.getIncludeSearchSelection());
			}
		}

		return options;
	}

	/**
	 * Checks and creates the destination path where the method configuration
	 * will be published.
	 * 
	 * @param options
	 *            the publishing options
	 * @return <code>true</code> if the destination path is valid,
	 *         <code>false</code> otherwise
	 */
	public boolean checkAndCreateDir(PublishOptions options) {
		String dir = options.getPublishDir();
		String defaultPublishPath = PublishingUIPreferences
				.getDefaultPublishPath();
		boolean answer = false;

		IPath ecPath = Path.fromOSString(dir);
		if (!ecPath.isAbsolute()) {
			String path = defaultPublishPath
					+ System.getProperty("file.separator") + dir; //$NON-NLS-1$
			answer = PublishingUIPlugin
					.getDefault()
					.getMsgDialog()
					.displayPrompt(
							PublishingUIResources.publishConfigDialog_title,
							PublishingUIResources
									.bind(
											PublishingUIResources.confirmPathDialog_text,
											path));

			if (answer) {
				options.setPublishDir(dir);
			} else {
				return false;
			}
		}

		File file = new File(dir);

		if (file.exists()) {
			File[] files = file.listFiles();
			if (files != null && files.length > 0) {
				answer = PublishingUIPlugin
						.getDefault()
						.getMsgDialog()
						.displayConfirmation(
								PublishingUIResources.publishConfigDialog_title,
								PublishingUIResources
										.bind(
												PublishingUIResources.overwriteDialog_text,
												dir));

				if (answer == true) {
					try {
						answer = FileUtil
								.deleteAllFiles(file.getAbsolutePath());
						if (answer == false) {
							PublishingUIPlugin
									.getDefault()
									.getMsgDialog()
									.displayError(
											PublishingUIResources.publishConfigDialog_title,
											PublishingUIResources.cannotPublishError_msg,
											PublishingUIResources
													.bind(
															PublishingUIResources.deleteFilesError_reason,
															dir));
							return false;

						}
					} catch (Exception e) {
						PublishingUIPlugin
								.getDefault()
								.getMsgDialog()
								.displayError(
										PublishingUIResources.publishConfigDialog_title,
										PublishingUIResources.cannotPublishError_msg,
										PublishingUIResources
												.bind(
														PublishingUIResources.deleteFilesError_reason,
														dir), e);
						return false;
					}
				}
			} else {
				return true;
			}
		} else {
			try {
				answer = file.mkdirs();
			} catch (Exception e) {
				PublishingUIPlugin.getDefault().getMsgDialog().displayError(
						PublishingUIResources.publishConfigDialog_title,
						PublishingUIResources.cannotPublishError_msg,
						PublishingUIResources.bind(
								PublishingUIResources.createDirError_reason,
								file.getAbsolutePath()), e);
				return false;
			}
			if (!answer) {
				PublishingUIPlugin.getDefault().getMsgDialog().displayError(
						PublishingUIResources.publishConfigDialog_title,
						PublishingUIResources.cannotPublishError_msg,
						PublishingUIResources.bind(
								PublishingUIResources.createDirError_reason,
								file.getAbsolutePath()));
				return false;
			}
		}

		return answer;
	}

}