//------------------------------------------------------------------------------
// 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.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.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.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;

/**
 * The Select Publishing Options page in the Publish Method Configuration
 * wizard.
 * 
 * @author Kelvin Low
 * @author Bingxue Xu
 * @author Jinhua Xi
 * @since 1.0
 * 
 * TODO: Rename this class to PublishConfigSpecifyOptionsPage fix for
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=173817
 */
public class PublishConfigPublishOptionsPage extends BaseWizardPage {

	private Text destinationPathText;

	private Text titleText;

	private Text bannerImageText;

	private Text aboutHTMLText;

	private Text feedbackURLText;

	private Button browseButton;

	private Button defaultPathCheckbox;

	private Button defaultFeedbackCheckbox;

	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;

	// don't want to do this
	// private Button includeEmptyCategoriesCtr;

	protected PublishOptions dataModel = null;

	protected String configName = ""; //$NON-NLS-1$

	private Button publishUnOpenExtendActivityDiagram;

	// private Button createWARCheckBox;
	// private Text webAppNameText;
	// private Label warLabel;
	// private Button includeSearch;
	// private Composite searchComposite;

	// private boolean showSearchChoice = true;
	// private boolean showAppletChoice = true;
	/**
	 * Creates a new instance.
	 */
	public PublishConfigPublishOptionsPage(String pageName,
			boolean displayDestinationGroup, PublishOptions dataModel) {
		super(pageName);
		setTitle(PublishingUIResources.selectPublishingOptionsWizardPage_title);
		setDescription(PublishingUIResources.selectPublishingOptionsWizardPage_text);
		this.displayDestinationGroup = displayDestinationGroup;
		this.dataModel = dataModel;
	}

	/**
	 * Creates a new instance.
	 */
	public PublishConfigPublishOptionsPage(String pageName,
			PublishOptions dataModel) {
		this(pageName, true, dataModel);
	}

	/**
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(Composite)
	 */
	public void createControl(Composite parent) {

		// if (PublishManager.getAppletSearchPath()==null) showSearchChoice =
		// false;
		// if (PublishManager.getAppletPath()==null) showAppletChoice = false;

		// Create the composite to hold the widgets.
		Composite composite = new Composite(parent, SWT.NULL);
		composite.setLayout(new GridLayout(1, false));

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

		createDestinationGroupUI(composite);
		createPublishingOptionsUI(composite);
		createPublishingMiscOptionsUI(composite);
		initializeControls();
		addListeners(composite);

		setControl(composite);
	}

	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.destinationDirectoryGroup_text);

			createLabel(destinationGroup, PublishingUIResources.pathLabel_text);
			destinationPathText = createEditableText(destinationGroup,
					"", 360, 1); //$NON-NLS-1$

			browseButton = new Button(destinationGroup, SWT.NONE);
			browseButton.setText(AuthoringUIText.BROWSE_BUTTON_TEXT);
			browseButton.setEnabled(false);

			createLabel(destinationGroup, ""); //$NON-NLS-1$
			defaultPathCheckbox = createCheckbox(destinationGroup,
					PublishingUIResources.useDefaultPathCheckbox_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.publishWebSiteGroup_text);

		createLabel(webSiteGroup, PublishingUIResources.titleLabel_text);
		titleText = createEditableText(webSiteGroup, "", 360, 1); //$NON-NLS-1$
		createLabel(webSiteGroup, ""); //$NON-NLS-1$

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

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

		createLabel(webSiteGroup, PublishingUIResources.feedbackURLLabel_text);
		feedbackURLText = createEditableText(webSiteGroup, "", 360, 1); //$NON-NLS-1$
		createLabel(webSiteGroup, ""); //$NON-NLS-1$
		createLabel(webSiteGroup, ""); //$NON-NLS-1$
		defaultFeedbackCheckbox = createCheckbox(webSiteGroup,
				PublishingUIResources.useDefaultFeedbackLabel_text, 2);

		includeGlossary = createCheckbox(webSiteGroup,
				PublishingUIResources.publishGlossaryLabel_text, 3);
		includeIndex = createCheckbox(webSiteGroup,
				PublishingUIResources.publishIndexLabel_text, 3);

		// override this method to add additional 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.validationGroup_text);

		checkExternalLinks = createCheckbox(validationGroup,
				PublishingUIResources.checkExternalLinksLabel_text);

		convertBrokenLinks = createCheckbox(validationGroup,
				PublishingUIResources.convertBrokenLinksLabel_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.diagramGroup_text);

		autoGenerateActivityDiagrams = createCheckbox(diagramGroup,
				PublishingUIResources.publishActivityDetailDiagramsLabel_text);

		publishUnOpenExtendActivityDiagram = createCheckbox(diagramGroup,
				PublishingUIResources.publishExtendedActivityDiagramsLabel_text);

		// 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.layoutGroup_text);

		lightWeightTreeCtr = createCheckbox(layoutGroup,
				PublishingUIResources.publishLightWeightTreeLabel_text);

		extraDescriptorInfoCtr = createCheckbox(layoutGroup,
				PublishingUIResources.publishExtraDescriptorInfoLabel_text);

		extraDescriptorInfoCtr
				.setSelection(PublishingUIPreferences.getExtraDescriptorInfo());
	}

	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;
		try {
			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);
			}
		} catch (Exception e) {
		}
		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);
		defaultFeedbackCheckbox.setSelection(feedbackURLText.getText().equals(
				PublishingUIPreferences.getDefaultFeedbackURL()));
		feedbackURLText.setEnabled(!defaultFeedbackCheckbox.getSelection());
		includeGlossary.setSelection(PublishingUIPreferences
				.getIncludeGlossary(configName));
		includeIndex.setSelection(PublishingUIPreferences
				.getIncludeIndex(configName));

		// createWARCheckBox.setSelection(PublishingUIPreferences.getIncludeSearch(configName));
		// String webAppName =
		// PublishingUIPreferences.getWebAppName(configName);
		// if (webAppName != null && webAppName.length() > 0) {
		// webAppNameText.setText(webAppName);
		// }
		// webAppNameText.setEnabled(createWARCheckBox.getSelection());
		//
		// includeSearch.setSelection(PublishingUIPreferences.getIncludeSearch(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); //$NON-NLS-1$
			return false;
		}

		String path = destinationPathText.getText();
		IPath ecPath = Path.fromOSString(path);
		boolean isValid = ecPath.isValidPath(path);
		if (!isValid) {
			setErrorMessage(PublishingUIResources.invalidPathError_msg); //$NON-NLS-1$
		} else if (!StrUtil.isValidPublishPath(path)) {
			setErrorMessage(PublishingUIResources.invalidPathCharsError_msg); //$NON-NLS-1$
		} 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);
					}
				}
			});
		}

		// createWARCheckBox.addListener(SWT.Selection, new Listener() {
		// public void handleEvent(Event event) {
		// webAppNameText.setEnabled(createWARCheckBox.getSelection());
		// }
		// });

		defaultFeedbackCheckbox.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				if (defaultFeedbackCheckbox.getSelection()) {
					feedbackURLText.setText(PublishingUIPreferences
							.getDefaultFeedbackURL());
					feedbackURLText.setEnabled(false);
				} else {
					String initUrl = PublishingUIPreferences
							.getFeedbackURL(configName);
					if (initUrl == null || initUrl.length() <= 0)
						initUrl = PublishingUIPreferences
								.getDefaultFeedbackURL();
					feedbackURLText.setText(initUrl);
					feedbackURLText.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();
					}
				});
			}
		}
	}

	/**
	 * Returns the publishing options.
	 */
	public PublishOptions getPublishingOptions() {
		if (displayDestinationGroup) {
			dataModel.setPublicationPath(destinationPathText.getText().trim());
		}
		dataModel.setTitle(titleText.getText().trim());
		dataModel.setBannerImage(bannerImageText.getText().trim());
		dataModel.aboutHTML = aboutHTMLText.getText().trim();
		dataModel.feedbackURL = feedbackURLText.getText().trim();
		dataModel.generateGlossary = includeGlossary.getSelection();
		dataModel.generateIndex = includeIndex.getSelection();
		// dataModel.generateSearchDB = includeSearch.getSelection();
		dataModel.checkExtLinks = checkExternalLinks.getSelection();
		dataModel.autoGenerateActivityDiagrams = autoGenerateActivityDiagrams
				.getSelection();
		dataModel
				.setUnopenExtendedActivityDiagram(publishUnOpenExtendActivityDiagram
						.getSelection());
		dataModel.convertBrokenLinks = convertBrokenLinks.getSelection();
		dataModel.showExtraDescriptorInfo = extraDescriptorInfoCtr
				.getSelection();
		dataModel.generateLightWeightTree = lightWeightTreeCtr.getSelection();
		// dataModel.includeEmptyCategories =
		// includeEmptyCategoriesCtr.getSelection();

		return dataModel;
	}

	// public Composite getSearchComposite() {
	// return searchComposite;
	// }
	//	
	// public Button getIncludeSearch() {
	// return includeSearch;
	// }
}