//------------------------------------------------------------------------------
// 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.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.ui.preferences.LibraryUIPreferences;
import org.eclipse.epf.publishing.services.PublishOptions;
import org.eclipse.epf.publishing.ui.PublishingUIPlugin;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.jface.preference.IPreferenceStore;


/**
 * Manages the Publishing UI preferences.
 * 
 * @author Kelvin Low
 * @author Jinhua Xi
 * @since 1.0
 * fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=156630
 */
public class PublishingUIPreferences {

	/**
	 * The Publishing UI preference keys.
	 */
//	public static final String PUBLISH_PATH = PublishOptions.PUBLISH_PATH;
//	public static final String PUBLISH_PATH_DEFAULT = "publishPathDefault"; //$NON-NLS-1$
//
//	public static final String TITLE = "title"; //$NON-NLS-1$
//
//	public static final String BANNER_IMAGE = "bannerImage"; //$NON-NLS-1$
//
//	public static final String ABOUT_HTML = "aboutHTML"; //$NON-NLS-1$
//
//	public static final String FEEDBACK_URL = "feedbackURL"; //$NON-NLS-1$	
//	public static final String FEEDBACK_URL_DEFAULT = "feedbackURLDefault"; //$NON-NLS-1$
//
//	public static final String INCLUDE_GLOSSARY = "includeGlossary"; //$NON-NLS-1$
//
//	public static final String INCLUDE_INDEX = "includeIndex"; //$NON-NLS-1$
//
//	public static final String INCLUDE_SEARCH = "includeSearch"; //$NON-NLS-1$
//
//	public static final String INCLUDE_PROCESS_CUSTOMIZATION = "includeProcessCustomization"; //$NON-NLS-1$	
//
//	public static final String CHECK_EXTERNAL_LINKS = "checkExternalLinks"; //$NON-NLS-1$

	private static String defaultPublishPath = null;

	private static String defaultTitle = null;

	private static String defaultBannerImage = null;

	private static String defaultAboutHTML = null;

	private static String defaultFeedbackURL = null;

	static {
		// Initialize the default preference values.
		MethodConfiguration[] configs = LibraryServiceUtil.getMethodConfigurations(
				LibraryService.getInstance().getCurrentMethodLibrary());
		IPreferenceStore store = PublishingUIPlugin.getDefault()
				.getPreferenceStore();
		store.setDefault(PublishOptions.PUBLISH_PATH_DEFAULT, getDefaultPublishPath()); //$NON-NLS-1$
		store.setDefault(PublishOptions.FEEDBACK_URL_DEFAULT, getDefaultFeedbackURL()); //$NON-NLS-1$
		store.setDefault(PublishOptions.EXTRA_DESCRIPTOR_INFO, getExtraDescriptorInfo(null)); //$NON-NLS-1$
		for(int i=0;i<configs.length;i++){
			String configName = configs[i].getName();
			String prefix = getConfigPrefPrefix(configName);
			store.setDefault(prefix+PublishOptions.PUBLISH_PATH, getPublishPath(configName)); //$NON-NLS-1$
			store.setDefault(prefix+PublishOptions.TITLE, getDefaultTitle()); //$NON-NLS-1$	
			store.setDefault(prefix+PublishOptions.BANNER_IMAGE, getDefaultBannerImage()); //$NON-NLS-1$
			store.setDefault(prefix+PublishOptions.ABOUT_HTML, getDefaultAboutHTML()); //$NON-NLS-1$
			store.setDefault(prefix+PublishOptions.FEEDBACK_URL, getFeedbackURL(configName)); //$NON-NLS-1$
			store.setDefault(prefix+PublishOptions.INCLUDE_GLOSSARY, getIncludeGlossary(configName)); //$NON-NLS-1$
			store.setDefault(prefix+PublishOptions.INCLUDE_INDEX, getIncludeIndex(configName)); //$NON-NLS-1$
//			store.setDefault(PublishOptions.INCLUDE_SEARCH, true); //$NON-NLS-1$
//			store.setDefault(PublishOptions.INCLUDE_PROCESS_CUSTOMIZATION, true); //$NON-NLS-1$
			store.setDefault(prefix+PublishOptions.CHECK_EXTERNAL_LINKS, getCheckExternalLinks(configName)); //$NON-NLS-1$
			store.setDefault(prefix+PublishOptions.CONVERT_BROKEN_LINKS, getConvertBrokenLinks(configName)); //$NON-NLS-1$
			store.setDefault(prefix+PublishOptions.LIGHT_WEIGHT_TREE, getLightWeightTree(configName)); //$NON-NLS-1$
			store.setDefault(prefix+PublishOptions.EXTRA_DESCRIPTOR_INFO, getExtraDescriptorInfo(configName)); //$NON-NLS-1$
			store.setDefault(prefix+LibraryUIPreferences.PUBLISH_UNOPEN_ACTIVITY_DD, 
					getPublishUnopenActivitydd(configName)); //$NON-NLS-1$
			store.setDefault(prefix+LibraryUIPreferences.PUBLISH_AD_FOR_ACTIVITY_EXTENSION, 
					getPublishADForActivityExtension(configName)); //$NON-NLS-1$
		}
	}
	
	public static boolean getConvertBrokenLinks(String configName) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getBoolean(
				getConfigPrefPrefix(configName)+PublishOptions.CONVERT_BROKEN_LINKS);
	}

	public static void setConvertBrokenLinks(String configName, boolean flag) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+PublishOptions.CONVERT_BROKEN_LINKS, flag);
	}
	
	public static boolean getLightWeightTree(String configName) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getBoolean(
				getConfigPrefPrefix(configName)+PublishOptions.LIGHT_WEIGHT_TREE);
	}

	public static void setLightWeightTree(String configName, boolean flag) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+PublishOptions.LIGHT_WEIGHT_TREE, flag);
	}
	public static boolean getExtraDescriptorInfo(String configName) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getBoolean(
				getConfigPrefPrefix(configName)+PublishOptions.EXTRA_DESCRIPTOR_INFO);
	}

	public static void setExtraDescriptorInfo(String configName, boolean flag) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+PublishOptions.EXTRA_DESCRIPTOR_INFO, flag);
	}
	/**
	 * Returns the publish path that was saved in a previous session.
	 * 
	 * @return The saved publish path.
	 */
	public static String getPublishPath(String configName) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getString(
				getConfigPrefPrefix(configName)+PublishOptions.PUBLISH_PATH);
	}

	/**
	 * Saves the current publish path to preference store.
	 * 
	 * @param path
	 *            A publish path.
	 */
	public static void setPublishPath(String configName, String path) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+PublishOptions.PUBLISH_PATH, path);
	}

	/**
	 * Returns the title that was saved in a previous session.
	 * 
	 * @return The saved title.
	 */
	public static String getTitle(String configName) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getString(
				getConfigPrefPrefix(configName)+PublishOptions.TITLE);
	}

	/**
	 * Saves the current title to preference store.
	 * 
	 * @param title
	 *            A title.
	 */
	public static void setTitle(String configName, String title) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+PublishOptions.TITLE,
				title);
	}

	/**
	 * Returns the banner image that was saved in a previous session.
	 * 
	 * @return The saved banner image.
	 */
	public static String getBannerImage(String configName) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getString(
				getConfigPrefPrefix(configName)+PublishOptions.BANNER_IMAGE);
	}

	/**
	 * Saves the current banner image to preference store.
	 * 
	 * @param image
	 *            The banner image.
	 */
	public static void setBannerImage(String configName, String image) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+PublishOptions.BANNER_IMAGE, image);
	}

	/**
	 * Returns the about HTML that was saved in a previous session.
	 * 
	 * @return The saved about HTML.
	 */
	public static String getAboutHTML(String configName) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getString(
				getConfigPrefPrefix(configName)+PublishOptions.ABOUT_HTML);
	}

	/**
	 * Saves the current about HTML to preference store.
	 * 
	 * @param file
	 *            A HTML file.
	 */
	public static void setAboutHTML(String configName, String file) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+PublishOptions.ABOUT_HTML, file);
	}

	/**
	 * Returns the feedback URL that was saved in a previous session.
	 * 
	 * @return The saved feedback URL.
	 */
	public static String getFeedbackURL(String configName) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getString(
				getConfigPrefPrefix(configName)+PublishOptions.FEEDBACK_URL);
	}

	/**
	 * Saves the current feedback URL to preference store.
	 * 
	 * @param url
	 *            A feedback URL.
	 */
	public static void setFeedbackURL(String configName, String url) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+PublishOptions.FEEDBACK_URL, url);
	}

	/**
	 * Returns the include glossary flag that was saved in a previous session.
	 * 
	 * @return The saved include glossary flag.
	 */
	public static boolean getIncludeGlossary(String configName) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getBoolean(
				getConfigPrefPrefix(configName)+PublishOptions.INCLUDE_GLOSSARY);
	}

	/**
	 * Saves the current include glossary flag to preference store.
	 * 
	 * @param flag
	 *            The include glossary flag.
	 */
	public static void setIncludeGlossary(String configName, boolean flag) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+PublishOptions.INCLUDE_GLOSSARY, flag);
	}

	/**
	 * Returns the include index flag that was saved in a previous session.
	 * 
	 * @return The saved include index flag.
	 */
	public static boolean getIncludeIndex(String configName) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getBoolean(
				getConfigPrefPrefix(configName)+PublishOptions.INCLUDE_INDEX);
	}

	/**
	 * Saves the current include index flag to preference store.
	 * 
	 * @param flag
	 *            The include index flag.
	 */
	public static void setIncludeIndex(String configName, boolean flag) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+PublishOptions.INCLUDE_INDEX, flag);
	}

//	/**
//	 * Returns the include search that was saved in a previous session.
//	 * 
//	 * @return The saved include search flag.
//	 */
//	public static boolean getIncludeSearch() {
//		return PublishingUIPlugin.getDefault().getPreferenceStore().getBoolean(
//				PublishOptions.INCLUDE_SEARCH);
//	}
//
//	/**
//	 * Saves the current include search flag to preference store.
//	 * 
//	 * @param flag
//	 *            The include search flag.
//	 */
//	public static void setIncludeSearch(boolean flag) {
//		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
//				PublishOptions.INCLUDE_SEARCH, flag);
//	}

//	/**
//	 * Returns the include process customization that was saved in a previous
//	 * session.
//	 * 
//	 * @return The saved include process customization flag.
//	 */
//	public static boolean getIncludeProcessCustomization() {
//		return PublishingUIPlugin.getDefault().getPreferenceStore().getBoolean(
//				PublishOptions.INCLUDE_PROCESS_CUSTOMIZATION);
//	}
//
//	/**
//	 * Saves the current include process customization flag to preference store.
//	 * 
//	 * @param flag
//	 *            The include process customization flag.
//	 */
//	public static void setIncludeProcessCustomization(boolean flag) {
//		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
//				PublishOptions.INCLUDE_PROCESS_CUSTOMIZATION, flag);
//	}

	/**
	 * Returns the check external links flag that was saved in a previous
	 * session.
	 * 
	 * @return The saved check external links flag.
	 */
	public static boolean getCheckExternalLinks(String configName) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getBoolean(
				getConfigPrefPrefix(configName)+PublishOptions.CHECK_EXTERNAL_LINKS);
	}

	/**
	 * Saves the current include process customization flag to preference store.
	 * 
	 * @param flag
	 *            The check external links flag.
	 */
	public static void setCheckExternalLinks(String configName, boolean flag) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+PublishOptions.CHECK_EXTERNAL_LINKS, flag);
	}
	
	/**
	 * Save current publish unopen activity dd flag to preference store
	 * @param configName the configuration name this flag is for
	 * @param flag the publish unopen activity dd flag
	 */
	public static void setPublishUnopenActivitydd(String configName, boolean flag){
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+LibraryUIPreferences.PUBLISH_UNOPEN_ACTIVITY_DD, flag);
	}
	
	/**
	 * return the publish unopen activity dd flag that was saved in previous session
	 * @param configName the configuration name this flag is for
	 * @return the publish unopen activity dd flag
	 */
	public static boolean getPublishUnopenActivitydd(String configName){
		return PublishingUIPlugin.getDefault().getPreferenceStore().getBoolean(
				getConfigPrefPrefix(configName)+LibraryUIPreferences.PUBLISH_UNOPEN_ACTIVITY_DD);
	}
	
	/**
	 * Save current publish AD for activity extension flag to preference store
	 * @param configName the configuration name this flag is for
	 * @param flag the publish AD for activity extension flag
	 */
	public static void setPublishADForActivityExtension(String configName, boolean flag){
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				getConfigPrefPrefix(configName)+LibraryUIPreferences.PUBLISH_AD_FOR_ACTIVITY_EXTENSION, flag);
	}
	
	/**
	 * return the publish AD for activity extension flag that was saved in previous session
	 * @param configName the configuration name this flag is for
	 * @return the publish AD for activity extension flag
	 */
	public static boolean getPublishADForActivityExtension(String configName){
		return PublishingUIPlugin.getDefault().getPreferenceStore().getBoolean(
				getConfigPrefPrefix(configName)+LibraryUIPreferences.PUBLISH_AD_FOR_ACTIVITY_EXTENSION);
	}

	/**
	 * Returns the default publish path.
	 * 
	 * @return The default publish path.
	 */
	public static String getDefaultPublishPath() {
		defaultPublishPath = PublishingUIPlugin.getDefault().getPreferenceStore().getString(
				PublishOptions.PUBLISH_PATH_DEFAULT).trim();
		if (defaultPublishPath == null || defaultPublishPath.length() <= 0) {
			defaultPublishPath = getInitDefaultPublishPath();
		}
		return defaultPublishPath;
	}
	
	public static String getInitDefaultPublishPath() {

			String userHome = System
					.getProperty("user.home").replace('\\', '/'); //$NON-NLS-1$
			String path = PublishingUIPlugin.getDefault().getString(
					"publishPath"); //$NON-NLS-1$
			if (path == null || path.length() == 0 || path.startsWith("[")) { //$NON-NLS-1$
				path = userHome + "/publish"; //$NON-NLS-1$
			} else if (path.startsWith("<user.home>")) { //$NON-NLS-1$
				path = userHome + path.substring(11);
			}
			if (System.getProperty("file.separator").equals("\\")) { //$NON-NLS-1$ //$NON-NLS-2$
				path = path.replace('/', '\\');
			}
			
			int idx = -1;
			if ((idx=path.indexOf("<app.name>")) >= 0) { //$NON-NLS-1$
//				String appNameProper = LibraryUIManager.getAppName();
				String appNameProper = LibraryUIPreferences.getApplicationShortName();
				path = path.substring(0, idx) + appNameProper + path.substring(idx+10);
			}
		
		return path;
	}

	public static void setDefaultPublishPath(String path) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				PublishOptions.PUBLISH_PATH_DEFAULT, path);
	}

	/**
	 * Returns the default title for the published website.
	 * 
	 * @return The default title for the 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;
	}

	/**
	 * Returns the default banner image for the published website.
	 * 
	 * @return The default banner image for the 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;
	}

	/**
	 * Returns the default about HTML for the published website.
	 * 
	 * @return The default about HTML for the 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;
	}

	/**
	 * Returns the default feedback URL.
	 * 
	 * @return The default feedback URL.
	 */
	public static String getDefaultFeedbackURL() {
		defaultFeedbackURL = PublishingUIPlugin.getDefault().getPreferenceStore().getString(
				PublishOptions.FEEDBACK_URL_DEFAULT).trim();
		if (defaultFeedbackURL == null || defaultFeedbackURL.length() <= 0) {
			defaultFeedbackURL = getInitDefaultFeedbackURL();
		}
		return defaultFeedbackURL;
	}
	
	public static String getInitDefaultFeedbackURL() {
			String url = PublishingUIPlugin.getDefault().getString(
					"feedbackURL"); //$NON-NLS-1$
			if (url == null || url.length() == 0 || url.startsWith("[")) { //$NON-NLS-1$
				url = "http://www.published_website.com/feedback"; //$NON-NLS-1$
			}
		
		return url;
	}
	public static void setDefaultFeedbackURL(String path) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				PublishOptions.FEEDBACK_URL_DEFAULT, path);
	}

	// genaric method to get/set values
	public static void setValue(String name, String value) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				name, value);
		
	}
	
	public static void setValue(String name, boolean value) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				name, value);
		
	}
	
	public static String getStringValue(String name) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getString(name);
	}
	
	public static boolean getBooleanValue(String name) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getBoolean(name);
	}
	
	public static void setDefaultValue(String name, String value) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				name, value);
		
	}
	
	public static void setDefaultValue(String name, boolean value) {
		PublishingUIPlugin.getDefault().getPreferenceStore().setValue(
				name, value);
		
	}
	
	public static String getDefaultStringValue(String name) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getString(name);
	}
	
	public static boolean getDefaultBooleanValue(String name) {
		return PublishingUIPlugin.getDefault().getPreferenceStore().getBoolean(name);
	}
	
	public static String getConfigPrefPrefix(String configName){
		try{
			MethodConfiguration config = LibraryServiceUtil.getMethodConfiguration(
					LibraryService.getInstance().getCurrentMethodLibrary(), configName);
			return configName+"."+config.getGuid()+".";
		} catch (Exception e){
			return "";
		}
	}

	public static void saveAllPreferences() {
		PublishingUIPlugin.getDefault().savePluginPreferences();
	}
}
