//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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.library.ui.preferences;

import java.util.List;

import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.PreferenceUtil;
import org.eclipse.epf.library.ui.LibraryUIPlugin;
import org.eclipse.epf.persistence.MultiFileSaveUtil;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;

/**
 * Manages the Library UI preferences.
 * 
 * @author Kelvin Low
 * @since 1.0
 */
public class LibraryUIPreferences {

	/**
	 * The Library UI preference keys.
	 */
	public static final String PROMPT_FOR_LIBRARY_AT_STARTUP = "promptForLibraryAtStartup"; //$NON-NLS-1$

	public static final String SAVED_LIBRARY_PATH = "savedLibraryPath"; //$NON-NLS-1$

	public static final String PUBLISH_UNOPEN_ACTIVITY_DD = "publishUnopenActivityDetailDiagram"; //$NON-NLS-1$

	public static final String PREF_SWITCH_CONFIG = "switchConfigurationOnProcessActivate"; //$NON-NLS-1$

	public static final String PUBLISH_AD_FOR_ACTIVITY_EXTENSION = "publishActivityDiagramforActivityExtension"; //$NON-NLS-1$

	public static final String APPLICATION_SHORT_NAME = "appname"; //$NON-NLS-1$

	private static final String NEW_LIBRARY_PATHS = "newLibraryPaths"; //$NON-NLS-1$

	private static final String OPEN_LIBRARY_PATHS = "openLibraryPaths"; //$NON-NLS-1$		

	private static final String OPEN_LIBRARY_URIS = "openLibraryURIs"; //$NON-NLS-1$

	static {
		// Initialize the default preference values.
		IPreferenceStore store = LibraryUIPlugin.getDefault()
				.getPreferenceStore();
		store.setDefault(PROMPT_FOR_LIBRARY_AT_STARTUP, true);
		store.setDefault(SAVED_LIBRARY_PATH, ""); //$NON-NLS-1$	
		store.setDefault(PREF_SWITCH_CONFIG, MessageDialogWithToggle.PROMPT);
		store.setDefault(NEW_LIBRARY_PATHS, getDefaultLibraryPath());
		store.setDefault(OPEN_LIBRARY_PATHS, getDefaultLibraryPath());
		store.setDefault(OPEN_LIBRARY_URIS, ""); //$NON-NLS-1$	
	}

	/**
	 * Returns the prompt for Method Library at startup preference.
	 * 
	 * @return <code>true</code> is the preference is set.
	 */
	public static boolean getPromptForMethodLibraryAtStartup() {
		return LibraryUIPlugin.getDefault().getPreferenceStore().getBoolean(
				PROMPT_FOR_LIBRARY_AT_STARTUP);
	}

	/**
	 * Sets the prompt for Method Library at startup preference.
	 * 
	 * @param enabled
	 * 
	 */
	public static void setPromptForMethodLibraryAtStartup(boolean enabled) {
		LibraryUIPlugin.getDefault().getPreferenceStore().setValue(
				PROMPT_FOR_LIBRARY_AT_STARTUP, enabled);
	}

	public static void setPublishUnopenActivitydd(boolean enabled) {
		LibraryUIPlugin.getDefault().getPreferenceStore().setValue(
				PUBLISH_UNOPEN_ACTIVITY_DD, enabled);
	}

	public static boolean getPublishUnopenActivitydd() {
		return LibraryUIPlugin.getDefault().getPreferenceStore().getBoolean(
				PUBLISH_UNOPEN_ACTIVITY_DD);
	}

	/**
	 * Setter method for Publish Activity Diagram for Activity Extension,
	 * 
	 * @param enabled
	 */
	public static void setPublishADForActivityExtension(boolean enabled) {
		LibraryUIPlugin.getDefault().getPreferenceStore().setValue(
				PUBLISH_AD_FOR_ACTIVITY_EXTENSION, enabled);
	}

	/**
	 * getter method for Publish Activity Diagram for Activity Extension flag
	 * from preference store,
	 */
	public static boolean getPublishADForActivityExtension() {
		return LibraryUIPlugin.getDefault().getPreferenceStore().getBoolean(
				PUBLISH_AD_FOR_ACTIVITY_EXTENSION);
	}

	/**
	 * Returns switch configuration value store in preference store
	 * 
	 * @return value - could be ALWAYS, NEVER, PROMPT
	 */
	public static String getSwitchConfig() {
		return LibraryUIPlugin.getDefault().getPreferenceStore().getString(
				PREF_SWITCH_CONFIG);
	}

	/**
	 * Saves switch configuration value in preference store
	 * 
	 * @param value
	 *            Value could be ALWAYS, NEVER, PROMPT
	 */
	public static void setSwitchConfig(String value) {
		LibraryUIPlugin.getDefault().getPreferenceStore().setValue(
				PREF_SWITCH_CONFIG, value);
	}

	/**
	 * Returns the Method Library path that was saved in a previous session.
	 * 
	 * @return The saved library path.
	 */
	public static String getSavedLibraryPath() {
		return LibraryUIPlugin.getDefault().getPreferenceStore().getString(
				SAVED_LIBRARY_PATH);
	}

	/**
	 * Saves a Method Library path to the Library UI preference store.
	 * 
	 * @param libPath
	 *            Path to a Method Library.
	 */
	public static void setSavedLibraryPath(String libPath) {
		String path = libPath;
		if (path.endsWith(MultiFileSaveUtil.DEFAULT_LIBRARY_MODEL_FILENAME)) {
			path = FileUtil.getParentDirectory(path);
		}
		LibraryUIPlugin.getDefault().getPreferenceStore().setValue(
				SAVED_LIBRARY_PATH, path);
		LibraryUIPlugin.getDefault().savePluginPreferences();
	}

	/**
	 * Returns the default Method Library path.
	 * 
	 * @return The default Method Library path.
	 */
	public static String getDefaultLibraryPath() {
		String userHome = System.getProperty("user.home").replace('\\', '/'); //$NON-NLS-1$
		String libraryPath = LibraryUIPlugin.getDefault().getString(
				"libraryPath"); //$NON-NLS-1$
		if (libraryPath == null || libraryPath.length() == 0
				|| libraryPath.startsWith("[")) { //$NON-NLS-1$
			libraryPath = userHome + "/Method Libraries/Library"; //$NON-NLS-1$
		} else if (libraryPath.startsWith("<user.home>")) { //$NON-NLS-1$
			libraryPath = userHome + libraryPath.substring(11);
		}
		if (System.getProperty("file.separator").equals("\\")) { //$NON-NLS-1$ //$NON-NLS-2$
			libraryPath = libraryPath.replace('/', '\\');
		}

		int idx = -1;
		if ((idx = libraryPath.indexOf("<app.name>")) >= 0) { //$NON-NLS-1$
			String appNameProper = LibraryUIPreferences
					.getApplicationShortName();
			libraryPath = libraryPath.substring(0, idx) + appNameProper
					+ libraryPath.substring(idx + 10);
		}

		return libraryPath;
	}

	/**
	 * Returns the application short name passed in the main feature's
	 * plugin_customization.ini.
	 * 
	 * @return The passed-in application short name.
	 */
	public static String getApplicationShortName() {
		String appname = LibraryUIPlugin.getDefault().getPreferenceStore()
				.getString(APPLICATION_SHORT_NAME);
		return appname;
	}

	/**
	 * Gets the new library paths preference.
	 * 
	 * @return an array of method library paths
	 */
	public static String[] getNewLibraryPaths() {
		return PreferenceUtil.getStringValues(LibraryUIPlugin.getDefault()
				.getPreferenceStore(), NEW_LIBRARY_PATHS);
	}

	/**
	 * Gets the new library paths preference.
	 * 
	 * @return a collection of method library paths
	 */
	public static List getNewLibraryPathsList() {
		return PreferenceUtil.getList(LibraryUIPlugin.getDefault()
				.getPreferenceStore(), NEW_LIBRARY_PATHS);
	}

	/**
	 * Adds a method library path to the new library paths preference.
	 * 
	 * @param path
	 *            a method library path
	 */
	public static void addNewLibraryPath(String path) {
		if (path != null) {
			List paths = getNewLibraryPathsList();
			paths.remove(path);
			paths.add(0, path);
			// FIXME! Read from global preference.
			if (paths.size() > 10) {
				paths = paths.subList(0, 10);
				paths.set(9, getDefaultLibraryPath());
			}
			PreferenceUtil.setList(LibraryUIPlugin.getDefault()
					.getPreferenceStore(), NEW_LIBRARY_PATHS, paths);
		}
	}

	/**
	 * Gets the open library paths preference.
	 * 
	 * @return an array of method library paths
	 */
	public static String[] getOpenLibraryPaths() {
		return PreferenceUtil.getStringValues(LibraryUIPlugin.getDefault()
				.getPreferenceStore(), OPEN_LIBRARY_PATHS);
	}

	/**
	 * Gets the open library paths preference.
	 * 
	 * @return a collection of method library paths
	 */
	public static List getOpenLibraryPathsList() {
		return PreferenceUtil.getList(LibraryUIPlugin.getDefault()
				.getPreferenceStore(), OPEN_LIBRARY_PATHS);
	}

	/**
	 * Adds a method library path to the open library paths preference.
	 * 
	 * @param path
	 *            a method library path
	 */
	public static void addOpenLibraryPath(String path) {
		if (path != null) {
			List paths = getOpenLibraryPathsList();
			paths.remove(path);
			paths.add(0, path);
			// FIXME! Read from global preference.
			if (paths.size() > 10) {
				paths = paths.subList(0, 10);
				paths.set(9, getDefaultLibraryPath());
			}
			PreferenceUtil.setList(LibraryUIPlugin.getDefault()
					.getPreferenceStore(), OPEN_LIBRARY_PATHS, paths);
		}
	}

	/**
	 * Gets the open library URIs preference.
	 * 
	 * @return a collection of method library URIs
	 */
	public static String[] getOpenLibraryURIs() {
		return PreferenceUtil.getStringValues(LibraryUIPlugin.getDefault()
				.getPreferenceStore(), OPEN_LIBRARY_URIS);
	}

	/**
	 * Gets the open library URIs preference.
	 * 
	 * @return a collection of method library URIs
	 */
	public static List getOpenLibraryURIsList() {
		return PreferenceUtil.getList(LibraryUIPlugin.getDefault()
				.getPreferenceStore(), OPEN_LIBRARY_URIS);
	}

	/**
	 * Adds a method library URI to the open library URIs preference.
	 * 
	 * @param uri
	 *            a method library URI
	 */
	public static void addOpenLibraryURI(String uri) {
		if (uri != null) {
			List libraryURIs = getOpenLibraryPathsList();
			libraryURIs.remove(uri);
			libraryURIs.add(0, uri);
			// FIXME! Read from global preference.
			if (libraryURIs.size() > 10) {
				libraryURIs = libraryURIs.subList(0, 10);
			}
			PreferenceUtil.setList(LibraryUIPlugin.getDefault()
					.getPreferenceStore(), OPEN_LIBRARY_URIS, libraryURIs);
		}
	}

	/**
	 * Save all preferences
	 * 
	 */
	public static void saveAllPreferences() {
		LibraryUIPlugin.getDefault().savePluginPreferences();
	}

}
