//------------------------------------------------------------------------------
// 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 org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.epf.authoring.ui.AuthoringUIHelpContexts;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIText;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.publishing.services.PublishOptions;
import org.eclipse.epf.publishing.ui.PublishingUIResources;
import org.eclipse.epf.publishing.ui.preferences.PublishingPreferencePage;
import org.eclipse.epf.publishing.ui.preferences.PublishingUIPreferences;
import org.eclipse.epf.ui.wizards.BaseWizardPage;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;

/**
 * A wizard page that prompts the user to select the publishing options for a
 * method configuration.
 * 
 * @author Kelvin Low
 * @author Bingxue Xu
 * @author Jinhua Xi
 * @since 1.0
 */
public class SelectPublishingOptionsPage extends BaseWizardPage {

	/**
	 * The wizard page name.
	 */
	public static final String PAGE_NAME = SelectPublishingOptionsPage.class
			.getName();

	private Text destinationPathText;

	private Text titleText;

	private Text bannerImageText;

	private Text aboutHTMLText;

	private Text feedbackURLText;

	private Button browseButton;

	private Button defaultPathCheckbox;

	private Button selectImageButton;

	private Button selectHTMLButton;

	private Button includeGlossary;

	private Button includeIndex;

	private Button checkExternalLinks;

	private Button convertBrokenLinks;

	private Button autoGenerateActivityDiagrams;

	private boolean displayDestinationGroup = true;

	private Button extraDescriptorInfoCtr;

	private Button lightWeightTreeCtr;

	private Button publishUnOpenExtendActivityDiagram;
	
	private String configName = "";

	/**
	 * Creates a new instance.
	 * 
	 * @param name
	 *            the name of the wizard page
	 */
	public SelectPublishingOptionsPage(String name) {
		super(name);
		setTitle(PublishingUIResources.publishConfigWizard_selectOptionsPage_title);
		setDescription(PublishingUIResources.publishConfigWizard_selectOptionsPage_text);
		setImageDescriptor(AuthoringUIPlugin.getDefault().getImageDescriptor(
				"full/wizban/PublishConfiguration.gif")); //$NON-NLS-1$			
	}

	/**
	 * Creates a new instance.
	 */
	public SelectPublishingOptionsPage() {
		this(PAGE_NAME);
	}

	/**
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(Composite)
	 */
	public void createControl(Composite parent) {
		Composite composite = new Composite(parent, SWT.NULL);
		composite.setLayout(new GridLayout(1, false));

		createDestinationGroupUI(composite);
		createPublishingOptionsUI(composite);
		createPublishingMiscOptionsUI(composite);

		initializeControls();

		addListeners(composite);

		setControl(composite);

		PlatformUI
				.getWorkbench()
				.getHelpSystem()
				.setHelp(
						composite,
						AuthoringUIHelpContexts.CONFIGURATION_PUBLISH_WIZARD_ALL_PAGES_CONTEXT);
	}

	protected void createDestinationGroupUI(Composite composite) {
		if (displayDestinationGroup) {
			// Create the Destination Path group.
			Group destinationGroup = new Group(composite, SWT.NULL);
			destinationGroup.setLayout(new GridLayout(3, false));
			destinationGroup.setLayoutData(new GridData(
					GridData.FILL_HORIZONTAL));
			destinationGroup
					.setText(PublishingUIResources.publishConfigWizard_destinationGroup_text);

			createLabel(destinationGroup,
					PublishingUIResources.publishConfigWizard_directory_text);
			destinationPathText = createEditableText(destinationGroup,
					"", 360, 1); //$NON-NLS-1$
//			String initPath = PublishingUIPreferences.getPublishPath();
//			if (initPath == null || initPath.length() <= 0)
//				initPath = PublishingUIPreferences.getDefaultPublishPath();
//			destinationPathText.setText(initPath);
			browseButton = new Button(destinationGroup, SWT.NONE);
			browseButton.setText(AuthoringUIText.BROWSE_BUTTON_TEXT);
			browseButton.setEnabled(false);

			createLabel(destinationGroup, ""); //$NON-NLS-1$
			defaultPathCheckbox = createCheckbox(
					destinationGroup,
					PublishingUIResources.publishConfigWizard_useDefaultPath_text,
					2);
			defaultPathCheckbox.setSelection(destinationPathText.getText()
					.equals(PublishingUIPreferences.getDefaultPublishPath()));
			destinationPathText.setEnabled(!defaultPathCheckbox.getSelection());

			if (!defaultPathCheckbox.getSelection()) {
				browseButton.setEnabled(true);
			}
		}
	}

	protected void createPublishingOptionsUI(Composite composite) {
		// Create the Published Website group.
		Group webSiteGroup = new Group(composite, SWT.NULL);
		webSiteGroup.setLayout(new GridLayout(3, false));
		webSiteGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		webSiteGroup
				.setText(PublishingUIResources.publishConfigWizard_webSite_text);

		createLabel(webSiteGroup,
				PublishingUIResources.publishConfigWizard_title_text);
		titleText = createEditableText(webSiteGroup, "", 360, 1); //$NON-NLS-1$
//		titleText.setText(PublishingUIPreferences.getTitle());
		createLabel(webSiteGroup, ""); //$NON-NLS-1$

		createLabel(webSiteGroup,
				PublishingUIResources.publishConfigWizard_bannerImage_text);
		bannerImageText = createEditableText(webSiteGroup, "", 360, 1); //$NON-NLS-1$
//		bannerImageText.setText(PublishingUIPreferences.getBannerImage());
		selectImageButton = new Button(webSiteGroup, SWT.NONE);
		selectImageButton.setText(AuthoringUIText.SELECT_BUTTON_TEXT);

		createLabel(webSiteGroup,
				PublishingUIResources.publishConfigWizard_aboutHTML_text);
		aboutHTMLText = createEditableText(webSiteGroup, "", 360, 1); //$NON-NLS-1$
//		aboutHTMLText.setText(PublishingUIPreferences.getAboutHTML());
		selectHTMLButton = new Button(webSiteGroup, SWT.NONE);
		selectHTMLButton.setText(AuthoringUIText.SELECT_BUTTON_TEXT);

		createLabel(webSiteGroup,
				PublishingUIResources.publishConfigWizard_feedbackURL_text);
		feedbackURLText = createEditableText(webSiteGroup, "", 360, 1); //$NON-NLS-1$
//		String feedbackURL = PublishingUIPreferences.getFeedbackURL();
//		if (feedbackURL == null || feedbackURL.length() <= 0)
//			feedbackURL = PublishingUIPreferences.getDefaultFeedbackURL();
//		feedbackURLText.setText(feedbackURL);
		createLabel(webSiteGroup, ""); //$NON-NLS-1$

		includeGlossary = createCheckbox(webSiteGroup,
				PublishingUIResources.publishConfigWizard_includeGlossary_text,
				3);
		includeIndex = createCheckbox(webSiteGroup,
				PublishingUIResources.publishConfigWizard_includeIndex_text, 3);

		// override this method to add addtional options
		includeAdditionalPublishingOptions(webSiteGroup);
	}

	protected void includeAdditionalPublishingOptions(Composite container) {
	}

	protected void createPublishingMiscOptionsUI(Composite composite) {
		// Create the Misc group.
		Group validationGroup = new Group(composite, SWT.NULL);
		validationGroup.setLayout(new GridLayout(1, false));
		validationGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		validationGroup
				.setText(PublishingUIResources.publishConfigWizard_validationGroup_text);

		checkExternalLinks = createCheckbox(validationGroup,
				PublishingUIResources.publishConfigWizard_checkHyperlinks_text);

		convertBrokenLinks = createCheckbox(
				validationGroup,
				PublishingUIResources.publishConfigWizard_convertBrokenLinks_text);

		// Create the Misc group.
		Group diagramGroup = new Group(composite, SWT.NULL);
		diagramGroup.setLayout(new GridLayout(1, false));
		diagramGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		diagramGroup
				.setText(PublishingUIResources.publishConfigWizard_diagramGroup_text);

		autoGenerateActivityDiagrams = createCheckbox(
				diagramGroup,
				PublishingUIResources.publishConfigWizard_publish_unopen_activity_dd_text);

		publishUnOpenExtendActivityDiagram = createCheckbox(
				diagramGroup,
				PublishingUIResources.publishConfigWizard_publish_extend_activity_diagram);

		// Create the layout group.
		Group layoutGroup = new Group(composite, SWT.NULL);
		layoutGroup.setLayout(new GridLayout());
		layoutGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		layoutGroup
				.setText(PublishingUIResources.publishConfigWizard_layout_text);

		lightWeightTreeCtr = createCheckbox(layoutGroup,
				PublishingUIResources.publishConfigWizard_lightWeightTree_text);

		extraDescriptorInfoCtr = createCheckbox(
				layoutGroup,
				PublishingUIResources.publishConfigWizard_extraDescriptorInfo_text);
		extraDescriptorInfoCtr
				.setSelection(PublishingUIPreferences
						.getBooleanValue(PublishingPreferencePage.EXTRA_DESCRIPTOR_INFO));
	}

	protected void initializeControls() {
//		includeGlossary.setSelection(PublishingUIPreferences
//				.getIncludeGlossary());
//		includeIndex.setSelection(PublishingUIPreferences.getIncludeIndex());
//		checkExternalLinks.setSelection(PublishingUIPreferences
//				.getCheckExternalLinks());
//		convertBrokenLinks.setSelection(PublishingUIPreferences
//				.getConvertBrokenLinks());
//		autoGenerateActivityDiagrams.setSelection(LibraryUIPreferences
//				.getPublishUnopenActivitydd());
//		publishUnOpenExtendActivityDiagram.setSelection(LibraryUIPreferences
//				.getPublishADForActivityExtension());
//		lightWeightTreeCtr.setSelection(PublishingUIPreferences
//				.getLightWeightTree());
//		extraDescriptorInfoCtr.setSelection(PublishingUIPreferences
//				.getExtraDescriptorInfo());
	}

	public void onEnterPage(Object obj) {
		super.onEnterPage(obj);
		configName = (String)obj;
		String initPath = PublishingUIPreferences.getPublishPath(configName);
		if (initPath == null || initPath.length() <= 0)
			initPath = PublishingUIPreferences.getDefaultPublishPath();
		destinationPathText.setText(initPath);
		defaultPathCheckbox.setSelection(destinationPathText.getText()
				.equals(PublishingUIPreferences.getDefaultPublishPath()));
		destinationPathText.setEnabled(!defaultPathCheckbox.getSelection());

		if (!defaultPathCheckbox.getSelection()) {
			browseButton.setEnabled(true);
		}
		titleText.setText(PublishingUIPreferences.getTitle(configName));
		bannerImageText.setText(PublishingUIPreferences.getBannerImage(configName));
		aboutHTMLText.setText(PublishingUIPreferences.getAboutHTML(configName));
		String feedbackURL = PublishingUIPreferences.getFeedbackURL(configName);
		if (feedbackURL == null || feedbackURL.length() <= 0)
			feedbackURL = PublishingUIPreferences.getDefaultFeedbackURL();
		feedbackURLText.setText(feedbackURL);
		includeGlossary.setSelection(PublishingUIPreferences
				.getIncludeGlossary(configName));
		includeIndex.setSelection(PublishingUIPreferences.getIncludeIndex(configName));
		checkExternalLinks.setSelection(PublishingUIPreferences
				.getCheckExternalLinks(configName));
		convertBrokenLinks.setSelection(PublishingUIPreferences
				.getConvertBrokenLinks(configName));
		autoGenerateActivityDiagrams.setSelection(PublishingUIPreferences
				.getPublishUnopenActivitydd(configName));
		publishUnOpenExtendActivityDiagram.setSelection(PublishingUIPreferences
				.getPublishADForActivityExtension(configName));
		lightWeightTreeCtr.setSelection(PublishingUIPreferences
				.getLightWeightTree(configName));
		extraDescriptorInfoCtr.setSelection(PublishingUIPreferences
				.getExtraDescriptorInfo(configName));
	}

	/**
	 * @see org.eclipse.jface.wizard.WizardPage#isPageComplete()
	 */
	public boolean isPageComplete() {
		if (!displayDestinationGroup) {
			return true;
		}

		if (!isTextNonEmpty(destinationPathText)) {
			setErrorMessage(PublishingUIResources.invalidPathError_msg);
			return false;
		}

		String path = destinationPathText.getText();
		IPath ecPath = Path.fromOSString(path);
		boolean isValid = ecPath.isValidPath(path);
		if (!isValid) {
			setErrorMessage(PublishingUIResources.invalidPathError_msg);
		} else if (!StrUtil.isValidPublishPath(path)) {
			setErrorMessage(PublishingUIResources.invalidPathCharsError_msg);
		} else {
			setErrorMessage(null);
			return true;
		}

		return false;
	}

	/**
	 * @see org.eclipse.jface.wizard.WizardPage#getNextPage()
	 */
	public IWizardPage getNextPage() {
		return null;
	}

	/**
	 * Adds the listeners for the controls on this page.
	 */
	private void addListeners(final Composite composite) {
		if (displayDestinationGroup) {
			destinationPathText.addModifyListener(new ModifyListener() {
				public void modifyText(ModifyEvent e) {
					setPageComplete(isPageComplete());
				}
			});

			browseButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent event) {
					try {
						DirectoryDialog dd = new DirectoryDialog(composite
								.getShell(), SWT.NONE);
						String destination = dd.open();
						if (destination != null) {
							destinationPathText.setText(destination);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});

			defaultPathCheckbox.addListener(SWT.Selection, new Listener() {
				public void handleEvent(Event event) {
					if (defaultPathCheckbox.getSelection()) {
						destinationPathText.setText(PublishingUIPreferences
								.getDefaultPublishPath());
						destinationPathText.setEnabled(false);
						browseButton.setEnabled(false);
					} else {
						String initPath = PublishingUIPreferences
								.getPublishPath(configName);
						if (initPath == null || initPath.length() <= 0)
							initPath = PublishingUIPreferences
									.getDefaultPublishPath();
						destinationPathText.setText(initPath);
						destinationPathText.setEnabled(true);
						browseButton.setEnabled(true);
					}
				}
			});
		}

		selectImageButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				try {
					FileDialog dialog = new FileDialog(composite.getShell(),
							SWT.OPEN);
					dialog.setFilterExtensions(new String[] {
							"*.gif", "*.jpg", "*.bmp" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					String imageFile = dialog.open();
					if (imageFile != null) {
						bannerImageText.setText(imageFile);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});

		selectHTMLButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				try {
					FileDialog dialog = new FileDialog(composite.getShell(),
							SWT.OPEN);
					dialog
							.setFilterExtensions(new String[] {
									"*.htm", "*.html" }); //$NON-NLS-1$ //$NON-NLS-2$
					String htmlFile = dialog.open();
					if (htmlFile != null) {
						aboutHTMLText.setText(htmlFile);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * @see org.eclipse.jface.dialogs.DialogPage#setVisible()
	 */
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		if (visible) {
			Display display = titleText.getDisplay();
			if (!(display == null || display.isDisposed())) {
				display.asyncExec(new Runnable() {
					public void run() {
						titleText.setFocus();
					}
				});
			}
		}
	}

	/**
	 * Gets the user selected publishing options.
	 * 
	 * @return a <code>PublishOptions</code> object
	 */
	public PublishOptions getPublishingOptions() {
		PublishOptions options = new PublishOptions();

		options.publishConfiguration = true;
		if (displayDestinationGroup) {
			options.setPublicationPath(destinationPathText.getText().trim());
		}
		options.setTitle(titleText.getText().trim());
		options.setBannerImage(bannerImageText.getText().trim());
		options.aboutHTML = aboutHTMLText.getText().trim();
		options.feedbackURL = feedbackURLText.getText().trim();
		options.generateGlossary = includeGlossary.getSelection();
		options.generateIndex = includeIndex.getSelection();
		options.checkExtLinks = checkExternalLinks.getSelection();
		options.autoGenerateActivityDiagrams = autoGenerateActivityDiagrams
				.getSelection();
		options
				.setUnopenExtendedActivityDiagram(publishUnOpenExtendActivityDiagram
						.getSelection());
		options.convertBrokenLinks = convertBrokenLinks.getSelection();
		options.showExtraDescriptorInfo = extraDescriptorInfoCtr.getSelection();
		options.generateLightWeightTree = lightWeightTreeCtr.getSelection();

		return options;
	}

}
