//------------------------------------------------------------------------------
// 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 org.eclipse.epf.common.utils.FileUtil;
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 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$

	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);
	}

	/**
	 * 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 Path
	 *            to a Method Library.
	 */
	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);
	}

	public static String getSwitchConfig() {
		return LibraryUIPlugin.getDefault().getPreferenceStore().getString(
				PREF_SWITCH_CONFIG);
	}

	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);
	}

	/**
	 * 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('/', '\\');
		}
		return libraryPath;
	}

}
