//------------------------------------------------------------------------------
// 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.preferences;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.epf.authoring.ui.AuthoringUIText;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.publishing.ui.PublishingUIPlugin;
import org.eclipse.epf.publishing.ui.PublishingUIResources;
import org.eclipse.epf.ui.preferences.BasePreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
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.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Text;

/**
 * The Publishing preference page.
 * 
 * @author Kelvin Low
 * @since 1.0
 * 
 * Bugs fixed:
 * <ul>
 * <li>https://bugs.eclipse.org/bugs/show_bug.cgi?id=156957</li>
 * </ul>
 */
public class PublishingPreferencePage extends BasePreferencePage {

	private Composite composite;

	private Text destinationPathText;

	private Text feedbackURLText;

	private Button browseButton;

	private Button extraDescriptorInfoCheckbox;

	/**
	 * Creates and returns the SWT control for the customized body of this
	 * preference page under the given parent composite.
	 * 
	 * @param parent
	 *            the parent composite
	 * @return the new control
	 */
	protected Control createContents(Composite parent) {
		composite = createGridLayoutComposite(parent, 1);

		// Create the Destination path group.
		/*
		 * Group destinationGroup = createGridLayoutGroup(composite,
		 * PublishingUIResources.destinationDirectoryGroup_text, 3);
		 */

		// Create the Published Website group.
		Group webSiteGroup = createGridLayoutGroup(composite,
				PublishingUIResources.publishWebSiteGroup_text, 3);
		createLabel(webSiteGroup,
				PublishingUIResources.preferencePage_defaultPath_text);
		destinationPathText = createEditableText(webSiteGroup);
		browseButton = createButton(webSiteGroup,
				AuthoringUIText.BROWSE_BUTTON_TEXT);
		createLabel(webSiteGroup, PublishingUIResources.feedbackURLLabel_text);
		feedbackURLText = createEditableText(webSiteGroup, 2);

		// Create the Browsing group.
		Group browsingGroup = createGridLayoutGroup(composite, PublishingUIResources.browsingLayoutGroup_text, 1);
		extraDescriptorInfoCheckbox = createCheckbox(browsingGroup,
				PublishingUIResources.publishExtraDescriptorInfoLabel_text, 1);

		initControls();

		addListeners();

		return composite;
	}

	/**
	 * Initializes the preference page controls with data.
	 */
	protected void initControls() {
		destinationPathText.setText(PublishingUIPreferences.getPublishPath());
		feedbackURLText.setText(PublishingUIPreferences.getFeedbackURL());
		extraDescriptorInfoCheckbox.setSelection(PublishingUIPreferences
				.getExtraDescriptorInfo());
	}

	/**
	 * Adds event listeners to the preference page controls.
	 */
	protected void addListeners() {
		destinationPathText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				if (!isPathValid(destinationPathText.getText())) {
					setValid(false);
				} else {
					setValid(true);
				}
			}
		});

		browseButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				openDirectoryDialog();
			}
		});
	}

	/**
	 * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
	 */
	protected void performDefaults() {
		super.performDefaults();
		initializeDefaults();
	}

	/**
	 * @see org.eclipse.jface.preference.PreferencePage#performOk()
	 */
	public boolean performOk() {
		storeValues();
		PublishingUIPreferences.saveAllPreferences();
		
		// update the settings for browsing
		PublishingUIPlugin.getDefault().updateLayoutSettings();

		return true;
	}

	/**
	 * Stores the values of the controls back to the preference store.
	 */
	private void storeValues() {
		PublishingUIPreferences.setPublishPath(destinationPathText.getText()
				.trim());
		PublishingUIPreferences
				.setFeedbackURL(feedbackURLText.getText().trim());
		PublishingUIPreferences
				.setExtraDescriptorInfo(extraDescriptorInfoCheckbox
						.getSelection());

//		// FIXME! Review implementation.
//		// allow to pass the value to the library browsing
//		// System.setProperty(EXTRA_DESCRIPTOR_INFO,
//		// extraDescriptorInfoCtr.getSelection() ? "true" : "false");
//		DefaultContentValidator
//				.setDefaultShowExtraInfoForDescriptors(extraDescriptorInfoCheckbox
//						.getSelection());
	}

	private void initializeDefaults() {
		destinationPathText.setText(PublishingUIPreferences
				.getDefaultPublishPath());
		feedbackURLText
				.setText(PublishingUIPreferences.getDefaultFeedbackURL());
		extraDescriptorInfoCheckbox.setSelection(PublishingUIPreferences
				.getDefaultExtraDescriptorInfo());
	}

	/**
	 * @see org.eclipse.jface.preference.PreferencePage#doGetPreferenceStore()
	 */
	protected IPreferenceStore doGetPreferenceStore() {
		return PublishingUIPlugin.getDefault().getPreferenceStore();
	}

	/**
	 * Validates the user specified destination path.
	 */
	private boolean isPathValid(String path) {
		if (path == null || path.length() <= 0) {
			setErrorMessage(PublishingUIResources.invalidPathError_msg); //$NON-NLS-1$
			return false;
		}

		IPath ecPath = Path.fromOSString(path);
		boolean isValid = ecPath.isValidPath(path);
		if (!isValid) {
			setErrorMessage(PublishingUIResources.invalidPathError_msg); //$NON-NLS-1$
			return false;
		} else if (!StrUtil.isValidPublishPath(path)) {
			setErrorMessage(PublishingUIResources.invalidPathCharsError_msg); //$NON-NLS-1$
			return false;
		}

		setErrorMessage(null);
		return true;
	}

	/**
	 * Opens the directory dialog.
	 */
	private void openDirectoryDialog() {
		try {
			DirectoryDialog dd = new DirectoryDialog(composite.getShell(),
					SWT.NONE);
			String destination = dd.open();
			if (destination != null) {
				destinationPathText.setText(destination);
			}
		} catch (Exception e) {
			PublishingUIPlugin.getDefault().getLogger().logError(e);
		}
	}

}
