//------------------------------------------------------------------------------
// 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_RELATED_LINKS = "showRelatedLinks"; //$NON-NLS-1$

	private static final String SHOW_RELATED_DESCRIPTORS_OPTION = "showRelatedDescriptorsOption"; //$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 related links of role, task and work product in navigate page.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the preference value
	 */
	public static boolean getShowRelatedLinks(String configId) {
		return prefStore.getBoolean(getConfigPrefPrefix(configId)
				+ SHOW_RELATED_LINKS);
	}

	/**
	 * Sets the show related links of role, task and work product in navigate page.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setShowRelatedLinks(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ SHOW_RELATED_LINKS, value);
	}
	
	/**
	 * Sets the show related links in navigate page preference to be
	 * default value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 */
	public static void removeShowRelatedLinks(String configId) {
		prefStore.setToDefault(getConfigPrefPrefix(configId)
				+ SHOW_RELATED_LINKS);
	}

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

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

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

	/**
	 * 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();
	}

}
