//------------------------------------------------------------------------------
// 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.epf.common.utils.FileUtil;
import org.eclipse.epf.library.layout.elements.ActivityLayout;
import org.eclipse.epf.library.ui.preferences.LibraryUIPreferences;
import org.eclipse.epf.publishing.ui.PublishingUIPlugin;
import org.eclipse.jface.preference.IPreferenceStore;

/**
 * Manages the Publishing UI preferences.
 * 
 * @author Kelvin Low
 * @author Jinhua Xi
 * @since 1.0
 */
public class PublishingUIPreferences {

	private static final String PUBLISH_ENTIRE_CONFIG = "publishEntireConfig"; //$NON-NLS-1$

	private static final String TITLE = "title"; //$NON-NLS-1$

	private static final String BANNER_IMAGE = "bannerImage"; //$NON-NLS-1$

	private static final String ABOUT_HTML = "aboutHTML"; //$NON-NLS-1$

	private static final String FEEDBACK_URL = "feedbackURL"; //$NON-NLS-1$	

	private static final String INCLUDE_GLOSSARY = "includeGlossary"; //$NON-NLS-1$

	private static final String INCLUDE_INDEX = "includeIndex"; //$NON-NLS-1$

	private static final String CHECK_EXTERNAL_LINKS = "checkExternalLinks"; //$NON-NLS-1$

	private static final String CONVERT_BROKEN_LINKS = "convertBrokenLinks"; //$NON-NLS-1$

	private static final String LIGHT_WEIGHT_TREE = "lightWeightTree"; //$NON-NLS-1$

	private static final String EXTRA_DESCRIPTOR_INFO = "extraDescriptorInfo"; //$NON-NLS-1$

	private static final String PUBLISH_UNOPEN_ACTIVITY_DD = "publishUnopenActivityDD"; //$NON-NLS-1$

	private static final String PUBLISH_AD_FOR_ACTIVITY_EXTENSION = "publishADForActivityExtension"; //$NON-NLS-1$

	private static final String PUBLISH_PATH = "publishPath"; //$NON-NLS-1$

	private static final String PUBLISH_STATIC_WEB_SITE = "publishStaticWebSite"; //$NON-NLS-1$

	private static final String INCLUDE_SERVLET_SEARCH = "includeServletSearch"; //$NON-NLS-1$

	private static final String WEBAPP_NAME = "webAppName"; //$NON-NLS-1$

	private static final String INCLUDE_SEARCH = "includeSearch"; //$NON-NLS-1$

	private static final String INITIALIZED = "initialized"; //$NON-NLS-1$

	private static final String SHOW_RELATED_DESCRIPTORS = "showRelatedDescriptors"; //$NON-NLS-1$

	private static final String SHOW_DESCRIPTORS_IN_NAVIGATIONTREE = "showDescriptorsInNavigationTree"; //$NON-NLS-1$

	private static final String DEFAULT_ACTIVITY_TAB = "defaultActivityTab"; //$NON-NLS-1$

	private static final String DEFAULT_PUBLISH_FOLDER_NAME = "Publish"; //$NON-NLS-1$

	private static String defaultTitle = null;

	private static String defaultBannerImage = null;

	private static String defaultAboutHTML = null;

	private static String defaultFeedbackURL = null;

	private static String defaultPublishPath = null;

	// The plug-in specific preference store.
	private static IPreferenceStore prefStore = PublishingUIPlugin.getDefault()
			.getPreferenceStore();

	static {
		// Initialize the default preference values.
		prefStore.setDefault(PUBLISH_ENTIRE_CONFIG, true);

		prefStore.setDefault(TITLE, getDefaultTitle());
		prefStore.setDefault(BANNER_IMAGE, getDefaultBannerImage());
		prefStore.setDefault(ABOUT_HTML, getDefaultAboutHTML());
		prefStore.setDefault(FEEDBACK_URL, getDefaultFeedbackURL());
		prefStore.setDefault(INCLUDE_GLOSSARY, false);
		prefStore.setDefault(INCLUDE_INDEX, false);
		prefStore.setDefault(CHECK_EXTERNAL_LINKS, false);
		prefStore.setDefault(CONVERT_BROKEN_LINKS, false);
		prefStore.setDefault(PUBLISH_UNOPEN_ACTIVITY_DD, false);
		prefStore.setDefault(PUBLISH_AD_FOR_ACTIVITY_EXTENSION, false);
		prefStore.setDefault(LIGHT_WEIGHT_TREE, true);
		prefStore.setDefault(EXTRA_DESCRIPTOR_INFO,
				getDefaultExtraDescriptorInfo());
		prefStore.setDefault(DEFAULT_ACTIVITY_TAB,
				ActivityLayout.TAB_NAME_ACTIVITY_WBS);

		prefStore.setDefault(PUBLISH_PATH, getDefaultPublishPath());
		prefStore.setDefault(PUBLISH_STATIC_WEB_SITE, true);
		prefStore.setDefault(INCLUDE_SERVLET_SEARCH, true);
		prefStore.setDefault(WEBAPP_NAME, ""); //$NON-NLS-1$			
		prefStore.setDefault(INCLUDE_SEARCH, true);
	}

	/**
	 * Gets the publish entire configuration preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getPublishEntireConfig(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ PUBLISH_ENTIRE_CONFIG);
		} else {
			return prefStore.getBoolean(PUBLISH_ENTIRE_CONFIG);
		}
	}

	/**
	 * Sets the publish entire configurationpreference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setPublishEntireConfig(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ PUBLISH_ENTIRE_CONFIG, value);
	}

	/**
	 * Sets the publish entire configuration preference to be default value
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removePublishEntireConfig(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId)
				+ PUBLISH_ENTIRE_CONFIG);
	}

	/**
	 * Gets the default title for a published website.
	 * 
	 * @return the default title for a published website
	 */
	public static String getDefaultTitle() {
		if (defaultTitle == null) {
			String url = PublishingUIPlugin.getDefault().getString("title"); //$NON-NLS-1$
			if (url == null || url.length() == 0 || url.startsWith("[")) { //$NON-NLS-1$
				url = ""; //$NON-NLS-1$
			}
			defaultTitle = url;
		}
		return defaultTitle;
	}

	/**
	 * Gets the web site title preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the web site title
	 */
	public static String getTitle(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId) + TITLE);
		} else {
			return prefStore.getString(TITLE);
		}
	}

	/**
	 * Sets the web site title preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param title
	 *            the web site title
	 */
	public static void setTitle(String configId, String title) {
		prefStore.setValue(getConfigPrefPrefix(configId) + TITLE, title);
	}

	/**
	 * Sets the web site title preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeTitle(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId) + TITLE);
	}

	/**
	 * Gets the default banner image for a published website.
	 * 
	 * @return the default banner image for a published website
	 */
	public static String getDefaultBannerImage() {
		if (defaultBannerImage == null) {
			String image = PublishingUIPlugin.getDefault().getString(
					"bannerImage"); //$NON-NLS-1$
			if (image == null || image.length() == 0 || image.startsWith("[")) { //$NON-NLS-1$
				image = ""; //$NON-NLS-1$
			}
			defaultBannerImage = image;
		}
		return defaultBannerImage;
	}

	/**
	 * Gets the banner image preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the banner image
	 */
	public static String getBannerImage(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId)
					+ BANNER_IMAGE);
		} else {
			return prefStore.getString(BANNER_IMAGE);
		}
	}

	/**
	 * Sets the banner image preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param image
	 *            the banner image URL
	 */
	public static void setBannerImage(String configId, String image) {
		prefStore.setValue(getConfigPrefPrefix(configId) + BANNER_IMAGE, image);
	}

	/**
	 * Sets the banner image preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeBannerImage(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId) + BANNER_IMAGE);
	}

	/**
	 * Gets the default about HTML for a published website.
	 * 
	 * @return the default about HTML for a published website
	 */
	public static String getDefaultAboutHTML() {
		if (defaultAboutHTML == null) {
			String file = PublishingUIPlugin.getDefault()
					.getString("aboutHTML"); //$NON-NLS-1$
			if (file == null || file.length() == 0 || file.startsWith("[")) { //$NON-NLS-1$
				file = ""; //$NON-NLS-1$
			}
			defaultAboutHTML = file;
		}
		return defaultAboutHTML;
	}

	/**
	 * Gets the about HTML preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the about HTML file path
	 */
	public static String getAboutHTML(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId)
					+ ABOUT_HTML);
		} else {
			return prefStore.getString(ABOUT_HTML);
		}
	}

	/**
	 * Sets the about HTML preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param path
	 *            the about HTML file path
	 */
	public static void setAboutHTML(String configId, String path) {
		prefStore.setValue(getConfigPrefPrefix(configId) + ABOUT_HTML, path);
	}

	/**
	 * Sets the about HTML preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeAboutHTML(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId) + ABOUT_HTML);
	}

	/**
	 * Gets the default feedback URL for a published website.
	 * 
	 * @return the default feedback URL for a published website
	 */
	public static String getDefaultFeedbackURL() {
		if (defaultFeedbackURL == null) {
			defaultFeedbackURL = "http://www.published_website.com/feedback"; //$NON-NLS-1$
		}
		return defaultFeedbackURL;
	}

	/**
	 * Gets the feedback URL preference value.
	 * 
	 * @return the feedback URL
	 */
	public static String getFeedbackURL() {
		return prefStore.getString(FEEDBACK_URL);
	}

	/**
	 * Sets the feedback URL preference value.
	 * 
	 * @param url
	 *            the feedback URL
	 */
	public static void setFeedbackURL(String url) {
		prefStore.setValue(FEEDBACK_URL, url);
	}

	/**
	 * Gets the feedback URL preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the feedback URL
	 */
	public static String getFeedbackURL(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId)
					+ FEEDBACK_URL);
		} else {
			return prefStore.getString(FEEDBACK_URL);
		}
	}

	/**
	 * Sets the feedback URL preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param url
	 *            the feedback URL
	 */
	public static void setFeedbackURL(String configId, String url) {
		prefStore.setValue(getConfigPrefPrefix(configId) + FEEDBACK_URL, url);
	}

	/**
	 * Sets the feedback URL preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeFeedbackURL(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId) + FEEDBACK_URL);
	}

	/**
	 * Gets the include glossary preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getIncludeGlossary(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ INCLUDE_GLOSSARY);
		} else {
			return prefStore.getBoolean(INCLUDE_GLOSSARY);
		}
	}

	/**
	 * Sets the include glossary preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setIncludeGlossary(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId) + INCLUDE_GLOSSARY,
				value);
	}

	/**
	 * Sets the include glossary preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeIncludeGlossary(String configId) {
		prefStore
				.setToDefault(getConfigPrefPrefix(configId) + INCLUDE_GLOSSARY);
	}

	/**
	 * Gets the include index preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getIncludeIndex(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ INCLUDE_INDEX);
		} else {
			return prefStore.getBoolean(INCLUDE_INDEX);
		}
	}

	/**
	 * Sets the include index preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setIncludeIndex(String configId, boolean value) {
		prefStore
				.setValue(getConfigPrefPrefix(configId) + INCLUDE_INDEX, value);
	}

	/**
	 * Sets the include index preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeIncludeIndex(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId) + INCLUDE_INDEX);
	}

	/**
	 * Gets the check external links preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getCheckExternalLinks(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ CHECK_EXTERNAL_LINKS);
		} else {
			return prefStore.getBoolean(CHECK_EXTERNAL_LINKS);
		}
	}

	/**
	 * Sets the check external links preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setCheckExternalLinks(String configId, boolean value) {
		prefStore.setValue(
				getConfigPrefPrefix(configId) + CHECK_EXTERNAL_LINKS, value);
	}

	/**
	 * Sets the check external links preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeCheckExternalLinks(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId)
				+ CHECK_EXTERNAL_LINKS);
	}

	/**
	 * Gets the convert broken links preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getConvertBrokenLinks(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ CONVERT_BROKEN_LINKS);
		} else {
			return prefStore.getBoolean(CONVERT_BROKEN_LINKS);
		}
	}

	/**
	 * Sets the convert broken links preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setConvertBrokenLinks(String configId, boolean value) {
		prefStore.setValue(
				getConfigPrefPrefix(configId) + CONVERT_BROKEN_LINKS, value);
	}

	/**
	 * Sets the convert broken links preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeConvertBrokenLinks(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId)
				+ CONVERT_BROKEN_LINKS);
	}

	/**
	 * Gets the publish unopen activity detail diagrams preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getPublishUnopenActivityDD(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ PUBLISH_UNOPEN_ACTIVITY_DD);
		} else {
			return prefStore.getBoolean(PUBLISH_UNOPEN_ACTIVITY_DD);
		}
	}

	/**
	 * Sets the publish unopen activity detail diagrams preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setPublishUnopenActivityDD(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ PUBLISH_UNOPEN_ACTIVITY_DD, value);
	}

	/**
	 * Sets the publish unopen activity detail diagrams preference to be default
	 * value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removePublishUnopenActivityDD(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId)
				+ PUBLISH_UNOPEN_ACTIVITY_DD);
	}

	/**
	 * Gets the publish activiy diagrams for base activities with unmodified
	 * extension preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getPublishADForActivityExtension(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ PUBLISH_AD_FOR_ACTIVITY_EXTENSION);
		} else {
			return prefStore.getBoolean(PUBLISH_AD_FOR_ACTIVITY_EXTENSION);
		}
	}

	/**
	 * Sets the publish activiy diagrams for base activities with unmodified
	 * extension preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setPublishADForActivityExtension(String configId,
			boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ PUBLISH_AD_FOR_ACTIVITY_EXTENSION, value);
	}

	/**
	 * Sets the publish activiy diagrams for base activities with unmodified
	 * extension preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removePublishADForActivityExtension(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId)
				+ PUBLISH_AD_FOR_ACTIVITY_EXTENSION);
	}

	/**
	 * Gets the light weight tree preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getLightWeightTree(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ LIGHT_WEIGHT_TREE);
		} else {
			return prefStore.getBoolean(LIGHT_WEIGHT_TREE);
		}
	}

	/**
	 * Sets the light weight tree preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setLightWeightTree(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId) + LIGHT_WEIGHT_TREE,
				value);
	}

	/**
	 * Sets the light weight tree preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeLightWeightTree(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId)
				+ LIGHT_WEIGHT_TREE);
	}

	/**
	 * Gets the default extra descriptor info preference value.
	 * 
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getDefaultExtraDescriptorInfo() {
		return false;
	}

	/**
	 * Gets the extra descriptor info preference value.
	 * 
	 * @return the preference value
	 */
	public static boolean getExtraDescriptorInfo() {
		return prefStore.getBoolean(EXTRA_DESCRIPTOR_INFO);
	}

	/**
	 * Sets the default extra descriptor info preference value.
	 * 
	 * @param value
	 *            the preference value
	 */
	public static void setExtraDescriptorInfo(boolean value) {
		prefStore.setValue(EXTRA_DESCRIPTOR_INFO, value);
	}

	/**
	 * Gets the extra descriptor info preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getExtraDescriptorInfo(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ EXTRA_DESCRIPTOR_INFO);
		} else {
			return prefStore.getBoolean(EXTRA_DESCRIPTOR_INFO);
		}
	}

	/**
	 * Sets the extra descriptor info preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setExtraDescriptorInfo(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ EXTRA_DESCRIPTOR_INFO, value);
	}

	/**
	 * Sets the extra descriptor info preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeExtraDescriptorInfo(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId)
				+ EXTRA_DESCRIPTOR_INFO);
	}

	/**
	 * Gets the default path for a published web site.
	 * 
	 * @return the default path for a published web site.
	 */
	public static String getDefaultPublishPath() {
		if (defaultPublishPath == null) {
			defaultPublishPath = System.getProperty("user.home"); //$NON-NLS-1$
			String appName = LibraryUIPreferences.getApplicationShortName();
			if (appName != null && appName.length() > 0) {
				defaultPublishPath = defaultPublishPath + FileUtil.FILE_SEP
						+ appName + FileUtil.FILE_SEP
						+ DEFAULT_PUBLISH_FOLDER_NAME;
			} else {
				defaultPublishPath = defaultPublishPath + FileUtil.FILE_SEP
						+ DEFAULT_PUBLISH_FOLDER_NAME;
			}
		}
		return defaultPublishPath;
	}

	/**
	 * Gets the publish path preference value.
	 * 
	 * @return the publish path
	 */
	public static String getPublishPath() {
		return prefStore.getString(PUBLISH_PATH);
	}

	/**
	 * Sets the publish path preference value.
	 * 
	 * @param path
	 *            the publish path
	 */
	public static void setPublishPath(String path) {
		prefStore.setValue(PUBLISH_PATH, path);
	}

	/**
	 * Gets the publish path preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the publish path
	 */
	public static String getPublishPath(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId)
					+ PUBLISH_PATH);
		} else {
			return prefStore.getString(PUBLISH_PATH);
		}
	}

	/**
	 * Sets the publish path preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param path
	 *            the publish path
	 */
	public static void setPublishPath(String configId, String path) {
		prefStore.setValue(getConfigPrefPrefix(configId) + PUBLISH_PATH, path);
	}

	/**
	 * Sets the publish path preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removePublishPath(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId) + PUBLISH_PATH);
	}

	/**
	 * Gets the publish static web site preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getPublishStaticWebSite(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ PUBLISH_STATIC_WEB_SITE);
		} else {
			return prefStore.getBoolean(PUBLISH_STATIC_WEB_SITE);
		}
	}

	/**
	 * Sets the publish static web site preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setPublishStaticWebSite(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ PUBLISH_STATIC_WEB_SITE, value);
	}

	/**
	 * Sets the publish static web site preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removePublishStaticWebSite(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId)
				+ PUBLISH_STATIC_WEB_SITE);
	}

	/**
	 * Gets the include applet search preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getIncludeServletSearch(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ INCLUDE_SERVLET_SEARCH);
		} else {
			return prefStore.getBoolean(INCLUDE_SERVLET_SEARCH);
		}
	}

	/**
	 * Sets the include servlet search preference value..
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setIncludeServletSearch(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ INCLUDE_SERVLET_SEARCH, value);
	}

	/**
	 * Sets the include servlet search preference to be default value..
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeIncludeServletSearch(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId)
				+ INCLUDE_SERVLET_SEARCH);
	}

	/**
	 * Gets the include search preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getIncludeSearch(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ INCLUDE_SEARCH);
		} else {
			return prefStore.getBoolean(INCLUDE_SEARCH);
		}
	}

	/**
	 * Sets the include search preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setIncludeSearch(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId) + INCLUDE_SEARCH,
				value);
	}

	/**
	 * Sets the include search preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeIncludeSearch(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId) + INCLUDE_SEARCH);
	}

	/**
	 * Gets the web application name preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the preference value
	 */
	public static String getWebAppName(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId)
					+ WEBAPP_NAME);
		} else {
			return prefStore.getString(WEBAPP_NAME);
		}
	}

	/**
	 * Sets the web application name preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param name
	 *            the web application name
	 */
	public static void setWebAppName(String configId, String name) {
		prefStore.setValue(getConfigPrefPrefix(configId) + WEBAPP_NAME, name);
	}

	/**
	 * Sets the web application name preference to be default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeWebAppName(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId) + WEBAPP_NAME);
	}

	/**
	 * Gets the method configuration specific preference prefix.
	 * 
	 * @param configId
	 *            the name of a method configuration
	 * @return a preference prefix assigned to the configuration
	 */
	public static String getConfigPrefPrefix(String configId) {
		return configId + "."; //$NON-NLS-1$
	}

	/**
	 * Gets the configuration specific preferences initialized preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the preference value
	 */
	public static boolean getConfigPrefInitialized(String configId) {
		return prefStore
				.getBoolean(getConfigPrefPrefix(configId) + INITIALIZED);
	}

	/**
	 * Sets the configuration specific preferences initialized preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setConfigPrefInitialized(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId) + INITIALIZED, value);
	}

	/**
	 * Sets the configuration specific preferences initialized preference to be
	 * default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeConfigPrefInitialized(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId) + INITIALIZED);
	}

	/**
	 * Gets the show related descriptors in content page preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the preference value
	 */
	public static boolean getShowRelatedDescriptors(String configId) {
		return prefStore.getBoolean(getConfigPrefPrefix(configId)
				+ SHOW_RELATED_DESCRIPTORS);
	}

	/**
	 * Sets the show related descriptors in content page preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setShowRelatedDescriptors(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ SHOW_RELATED_DESCRIPTORS, value);
	}

	/**
	 * Sets the show related descriptors in content page preference to be
	 * default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeShowRelatedDescriptors(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId)
				+ SHOW_RELATED_DESCRIPTORS);
	}

	/**
	 * Gets the show descriptors in navigation tree preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the preference value
	 */
	public static boolean getShowDescriptorsInNavigationTree(String configId) {
		return prefStore.getBoolean(getConfigPrefPrefix(configId)
				+ SHOW_DESCRIPTORS_IN_NAVIGATIONTREE);
	}

	/**
	 * Sets the show descriptors in navigation tree preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setShowDescriptorsInNavigationTree(String configId,
			boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ SHOW_DESCRIPTORS_IN_NAVIGATIONTREE, value);
	}

	/**
	 * Sets the show descriptors in navigation tree preference to be default
	 * value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeShowDescriptorsInNavigationTree(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId)
				+ SHOW_DESCRIPTORS_IN_NAVIGATIONTREE);
	}

	/**
	 * Gets the default activity tab preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the default activity tab name
	 */
	public static String getDefaultActivityTab(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId)
					+ DEFAULT_ACTIVITY_TAB);
		} else {
			return prefStore.getString(DEFAULT_ACTIVITY_TAB);
		}
	}

	/**
	 * Sets the default activity tab preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param tabName
	 *            the default activity tab name
	 */
	public static void setDefaultActivityTab(String configId, String tabName) {
		prefStore.setValue(
				getConfigPrefPrefix(configId) + DEFAULT_ACTIVITY_TAB, tabName);
	}

	/**
	 * Saves all the preferences.
	 */
	public static void saveAllPreferences() {
		PublishingUIPlugin.getDefault().savePluginPreferences();
	}

}
