//------------------------------------------------------------------------------
// 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.publishConfigWizard_selectOptionsPage_title); //$NON-NLS-1$
		setDescription(PublishingUIResources.publishConfigWizard_selectOptionsPage_text); //$NON-NLS-1$
		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.publishConfigWizard_destinationGroup_text); //$NON-NLS-1$		

			createLabel(destinationGroup,
					PublishingUIResources.publishConfigWizard_directory_text); //$NON-NLS-1$
			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); //$NON-NLS-1$
			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); //$NON-NLS-1$		

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

		createLabel(webSiteGroup,
				PublishingUIResources.publishConfigWizard_bannerImage_text); //$NON-NLS-1$
		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); //$NON-NLS-1$
		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); //$NON-NLS-1$
		feedbackURLText = createEditableText(webSiteGroup, "", 360, 1); //$NON-NLS-1$
		createLabel(webSiteGroup, ""); //$NON-NLS-1$
		createLabel(webSiteGroup, ""); //$NON-NLS-1$
		defaultFeedbackCheckbox = createCheckbox(webSiteGroup,
				PublishingUIResources.publishConfigWizard_useDefaultFeedback_text, 2);
		// defaultFeedbackCheckbox.setSelection(feedbackURLText.getText()
		// .equals(PublishingUIPreferences.getDefaultFeedbackURL()));
		// feedbackURLText.setEnabled(!defaultFeedbackCheckbox.getSelection());

		includeGlossary = createCheckbox(webSiteGroup,
				PublishingUIResources.publishConfigWizard_includeGlossary_text, 3); //$NON-NLS-1$
		includeIndex = createCheckbox(webSiteGroup,
				PublishingUIResources.publishConfigWizard_includeIndex_text, 3); //$NON-NLS-1$

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

	protected void includeAdditionalPublishingOptions(Composite container) {

//		Composite warComposite = new Composite(container, SWT.NONE);
//		GridLayout warLayout = new GridLayout(2, false);
//		warLayout.marginHeight = 0;
//		warLayout.marginWidth = 0;
//		warComposite.setLayout(warLayout);
//		GridData gridData = new GridData();
//		gridData.horizontalSpan = 3;
//		warComposite.setLayoutData(gridData);
//
//		createWARCheckBox = createCheckbox(warComposite,
//				PublishingUIResources.publishConfigWizard_createWAR_text, 2); //$NON-NLS-1$
//
//		warLabel = createLabel(warComposite,
//				PublishingUIResources.publishConfigWizard_webApplicationName_text); //$NON-NLS-1$
//		gridData = new GridData(GridData.BEGINNING);
//		gridData.horizontalIndent = 30;
//		warLabel.setLayoutData(gridData);
//		webAppNameText = createEditableText(warComposite, "", 295, 1); //$NON-NLS-1$
//
//		searchComposite = new Composite(container, SWT.NONE);
//		GridLayout searchLayout = new GridLayout();
//		searchLayout.marginHeight = 0;
//		searchLayout.marginWidth = 0;
//		searchComposite.setLayout(searchLayout);
//		gridData = new GridData();
//		gridData.horizontalSpan = 3;
//		searchComposite.setLayoutData(gridData);
//
//		includeSearch = createCheckbox(searchComposite,
//				PublishingUIResources.publishConfigWizard_includeSearch_text, 1); //$NON-NLS-1$	
	}

	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); //$NON-NLS-1$	

		checkExternalLinks = createCheckbox(validationGroup,
				PublishingUIResources.publishConfigWizard_checkHyperlinks_text); //$NON-NLS-1$

		convertBrokenLinks = createCheckbox(validationGroup,
				PublishingUIResources.publishConfigWizard_convertBrokenLinks_text); //$NON-NLS-1$

		// 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); //$NON-NLS-1$	

		autoGenerateActivityDiagrams = createCheckbox(diagramGroup,
				PublishingUIResources.publishConfigWizard_publish_unopen_activity_dd_text); //$NON-NLS-1$

		publishUnOpenExtendActivityDiagram = createCheckbox(diagramGroup,
				PublishingUIResources.publishConfigWizard_publish_extend_activity_diagram); //$NON-NLS-1$

		// 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); //$NON-NLS-1$

		lightWeightTreeCtr = createCheckbox(layoutGroup,
				PublishingUIResources.publishConfigWizard_lightWeightTree_text);

		// includeEmptyCategoriesCtr = createCheckbox(
		// layoutGroup,
		// PublishingUIResources.publishConfigWizard_includeEmptyCategories_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;
		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;
//	}
}