//------------------------------------------------------------------------------
// 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 java.util.List;

import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
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 PUBLISH_PROCESSES = "publishProcesses"; //$NON-NLS-1$
	
	private static final String PUBLISH_INCLUDE_BASE_PROCESS = "publishIncludeBaseProcess"; //$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 FULFILL_DESCRIPTOR_SLOT_BY_CONTENT = "fulfillDescriptorSlotByContent"; //$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(FULFILL_DESCRIPTOR_SLOT_BY_CONTENT,
				getDefaultFulfillDescriptorSlotByContent());
		
		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);
	}
	
	public static List<String> getProcesses(String configId) {
		String guidStr = prefStore.getString(configId + PUBLISH_PROCESSES);
		return TngUtil.convertStringsToList(guidStr);
	}

	public static void setProcesses(String configId, List<String> guidList) {
		String guidStr = TngUtil.convertListToString(guidList);
		prefStore.setValue(configId + PUBLISH_PROCESSES, guidStr);
	}
	
	public static Boolean getIncludeBaseProcesses(String configId) {
		return prefStore.getBoolean(configId + PUBLISH_INCLUDE_BASE_PROCESS);
	}
	
	public static void setIncludeBaseProcesses(String configId, boolean value) {
		prefStore.setValue(configId + PUBLISH_INCLUDE_BASE_PROCESS, value);
	}

	/**
	 * 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 default fulfill descriptor slot by content preference value.
	 * 
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getDefaultFulfillDescriptorSlotByContent() {
		return false;
	}
	
	/**
	 * Gets the fulfill descriptor slot by content preference value.
	 * 
	 * @return the preference value
	 */
	public static boolean getFulfillDescriptorSlotByContent() {
		return prefStore.getBoolean(FULFILL_DESCRIPTOR_SLOT_BY_CONTENT);
	}

	/**
	 * Sets the fulfill descriptor slot by content preference value.
	 * 
	 * @param value
	 *            the preference value
	 */
	public static void setFulfillDescriptorSlotByContent(boolean value) {
		prefStore.setValue(FULFILL_DESCRIPTOR_SLOT_BY_CONTENT, 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();
	}

}
