//------------------------------------------------------------------------------
// 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.library.ui;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.epf.common.serviceability.MsgDialog;
import org.eclipse.epf.common.serviceability.VersionUtil;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.persistence.ILibraryResourceSet;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.library.ui.actions.ConfigurationContributionItem;
import org.eclipse.epf.library.ui.dialogs.OpenLibraryDialog;
import org.eclipse.epf.library.ui.dialogs.SelectLibraryDirectoryDialog;
import org.eclipse.epf.library.ui.preferences.LibraryUIPreferences;
import org.eclipse.epf.library.ui.wizards.LibraryBackupUtil;
import org.eclipse.epf.library.xmi.XMILibraryManager;
import org.eclipse.epf.library.xmi.XMILibraryUtil;
import org.eclipse.epf.persistence.MultiFileSaveUtil;
import org.eclipse.epf.persistence.PersistencePlugin;
import org.eclipse.epf.persistence.migration.MappingUtil;
import org.eclipse.epf.persistence.migration.UpgradeCallerInfo;
import org.eclipse.epf.services.Services;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.ICoolBarManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.ToolBarContributionItem;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.osgi.framework.Bundle;

/**
 * The Library UI Manager.
 * 
 * @author Kelvin Low
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class LibraryUIManager {

	private static final String TOOLBAR_CONFIG_CONTRIBUTION_ID = "toolbar.config.contribution"; //$NON-NLS-1$

	private static LibraryUIManager instance = null;

	private static String cmdLineLibPath = null;
	private static String cmdLineDefaultLibPath = null;
	
	private static String appName = "composer";

	private static HashMap typeToManagerDefMap;

	public static boolean DEBUG = LibraryUIPlugin.getDefault().isDebugging();

	/**
	 * Returns the singleton instance.
	 */
	public static LibraryUIManager getInstance() {
		if (instance == null) {
			synchronized (LibraryUIManager.class) {
				if (instance == null) {
					instance = new LibraryUIManager();
				}
			}
		}
		return instance;
	}

	/**
	 * Private default constructor to prevent this class from being
	 * instantiated.
	 */
	private LibraryUIManager() {
		addConfigurationContribution();
	}

	/**
	 * Prompts the user to select a Method Library.
	 */
	public void promptForMethodLibrary() {
		if(!Services.getDefaultLibraryPersistenceType().equals(Services.XMI_PERSISTENCE_TYPE)) {
			ILibraryUIManager manager = getLibraryUIManager(Services.getDefaultLibraryPersistenceType());
			if(manager != null) {
				if(!manager.openLibrary(true)) {
					System.exit(0);
				}
			}
			return;
		}

		
		// Retrieve the Library path that was saved in a previous session.
		String libPath = LibraryUIPreferences.getSavedLibraryPath();
		if (cmdLineLibPath != null) {
			libPath = cmdLineLibPath;
		} else if (libPath == null || libPath.length() == 0) {
			if (cmdLineDefaultLibPath != null) {
				libPath = cmdLineDefaultLibPath;
			}
		}

		// Prompt the user to select a Method Library folder if:
		// (1) The saved or command line Library path is invalid AND
		// (2) The prompt for Method Library at startup preference is set to
		// true (the default)
		if (XMILibraryUtil.isValidLibrary(libPath, true) == Status.OK_STATUS
				&& !LibraryUIPreferences.getPromptForMethodLibraryAtStartup()
				&& !XMILibraryUtil.isMethodLibraryLocked(libPath)) {
			openLibrary(libPath);
			return;
		}

		// Open a dialog to prompt the user to select a Method Librray folder.
		if (XMILibraryUtil.isValidLibrary(libPath) != Status.OK_STATUS) {
			libPath = LibraryUIPreferences.getDefaultLibraryPath();
		}
		
		// bug 151199 - change parent shell to null. dialog is also changed to
		// not be ON_TOP
		OpenLibraryDialog dialog = new OpenLibraryDialog(null, libPath);
		while (dialog.open() == Window.OK) {
			libPath = dialog.getLibraryPath();
			libPath = toAbsoluteLibraryPath(libPath);
			if (XMILibraryUtil.isValidLibrary(libPath, true) == Status.OK_STATUS) {
				if (XMILibraryUtil.isMethodLibraryLocked(libPath)) {
					if (displayLibraryLockedMessage() != 0)
						continue;
				}
				VersionUtil.VersionCheckInfo info = VersionUtil.checkLibraryVersion(
						new File(libPath, XMILibraryManager.LIBRARY_XMI));
				if (info != null && info.result > 0) {
					String message = ""; //$NON-NLS-1$
					if (info.toolID.equals(VersionUtil.getPrimaryToolID())) {
						message = NLS.bind(LibraryUIResources.versionMismatchDialog_text, new Object[] {
								Platform.getProduct().getName(), info.toolVersion});
					} else {
						message = NLS.bind(LibraryUIResources.versionMismatchDialog_text_unknown, new Object[] {
								Platform.getProduct().getName()});
					}
					LibraryUIPlugin.getDefault().getMsgDialog().
						displayError(LibraryUIResources.openLibraryWizard_title, message);
					continue;
				}
				if (XMILibraryUtil.isMethodLibraryUpgradeRequired(libPath)) {
					if (!LibraryUIPlugin
							.getDefault()
							.getMsgDialog()
							.displayConfirmation(
									LibraryUIResources.openLibraryWizard_title,
									LibraryUIResources.upgradeLibraryDialog_text)) {
						continue;
					}
					if (!upgradeLibrary(libPath, null)) {
						continue;
					}
				}
				if (openLibrary(libPath)) {
					return;
				}
			} else {
				MsgDialog msgDialog = LibraryUIPlugin.getDefault()
						.getMsgDialog();
				boolean rc = msgDialog
						.displayConfirmation(
								LibraryUIResources.openLibraryWizard_title,
								NLS
										.bind(
												LibraryUIResources.openLibraryDialog_newLibrary_text,
												new Object[] { libPath }));
				if (!rc)
					continue;
				if (createLibrary(libPath)) {
					return;
				}
			}

			LibraryUIPlugin.getDefault().getMsgDialog().displayError(
					LibraryUIResources.openLibraryWizard_title,
					LibraryUIResources.invalidLibraryPath_msg,
					LibraryUIResources.invalidLibraryPath_reason);
		}
		;

		// if dialog is closed with the OK buttonbeing clicked -- treat it as
		// cancel
		System.exit(0);
	}
	
	private static class ManagerDef {
		Bundle bundle;

		String type;

		String className;
		
		ILibraryUIManager instance;

		/**
		 * @param bundle
		 * @param type
		 * @param className
		 * @param instance
		 */
		private ManagerDef(Bundle bundle, String type, String className) {
			super();
			this.bundle = bundle;
			this.type = type;
			this.className = className;
		}
				
	}
	
	public static ILibraryUIManager getLibraryUIManager(String persistenceType) {
		if (typeToManagerDefMap == null) {
			typeToManagerDefMap = new HashMap();
			// Process the extension point contributors.
			//
			IExtensionRegistry extensionRegistry = Platform
					.getExtensionRegistry();
			IExtensionPoint extensionPoint = extensionRegistry
					.getExtensionPoint(
							"org.eclipse.epf.library.ui", "libraryUIManagers"); //$NON-NLS-1$ //$NON-NLS-2$
			if (extensionPoint != null) {
				IExtension[] extensions = extensionPoint.getExtensions();
				for (int i = 0; i < extensions.length; i++) {
					IExtension extension = extensions[i];
					String pluginId = extension.getNamespaceIdentifier();
					Bundle bundle = Platform.getBundle(pluginId);
					IConfigurationElement[] configElements = extension
							.getConfigurationElements();
					for (int j = 0; j < configElements.length; j++) {
						IConfigurationElement configElement = configElements[j];
						try {
							String className = configElement
									.getAttribute("class"); //$NON-NLS-1$
							String type = configElement
									.getAttribute("type"); //$NON-NLS-1$
							if (className != null
									&& className.trim().length() > 0
									&& type != null
									&& type.trim().length() > 0) {
								typeToManagerDefMap.put(type, new ManagerDef(bundle,
										type, className));
							}
						} catch (Exception e) {
							CommonPlugin.INSTANCE.log(e);
						}
					}
				}
			}
		}
		ManagerDef mgr = (ManagerDef) typeToManagerDefMap.get(persistenceType);
		if (mgr != null) {
			if (mgr.instance == null) {
				try {
					mgr.instance = (ILibraryUIManager) mgr.bundle.loadClass(
							mgr.className).newInstance();
				} catch (Exception e) {
					PersistencePlugin.getDefault().getLogger().logError(e);
					if(DEBUG ) {
						e.printStackTrace();
					}
				}
			}
			return mgr.instance;
		}
		return null;
	}
		
	/**
	 * Opens a Method Library.
	 */
	public void openLibrary() {
		if(!Services.getDefaultLibraryPersistenceType().equals(Services.XMI_PERSISTENCE_TYPE)) {
			ILibraryUIManager manager = getLibraryUIManager(Services.getDefaultLibraryPersistenceType());
			if(manager != null) {
				manager.openLibrary(false);
			}
			return;
		}
		SelectLibraryDirectoryDialog dialog = new SelectLibraryDirectoryDialog(
				Display.getCurrent().getActiveShell());
		String libPath = LibraryUIPreferences.getSavedLibraryPath();
		dialog.setFilterPath(libPath);
		do {
			libPath = dialog.open();
			if (libPath == null) {
				return;
			}
			if (XMILibraryUtil.isValidLibrary(libPath, true) == Status.OK_STATUS) {
				if (XMILibraryUtil.isMethodLibraryLocked(libPath)) {
					if (displayLibraryLockedMessage() != 0)
						continue;
				}
				VersionUtil.VersionCheckInfo info = VersionUtil.checkLibraryVersion(
						new File(libPath, XMILibraryManager.LIBRARY_XMI));
				if (info != null && info.result > 0) {
					String message = ""; //$NON-NLS-1$
					if (info.toolID.equals(VersionUtil.getPrimaryToolID())) {
						message = NLS.bind(LibraryUIResources.versionMismatchDialog_text, new Object[] {
								Platform.getProduct().getName(), info.toolVersion});
					} else {
						message = NLS.bind(LibraryUIResources.versionMismatchDialog_text_unknown, new Object[] {
								Platform.getProduct().getName()});
					}
					LibraryUIPlugin.getDefault().getMsgDialog().
						displayError(LibraryUIResources.openLibraryWizard_title, message);
					return;
				}
				if (XMILibraryUtil.isMethodLibraryUpgradeRequired(libPath)) {
					if (!LibraryUIPlugin
							.getDefault()
							.getMsgDialog()
							.displayConfirmation(
									LibraryUIResources.openLibraryWizard_title,
									LibraryUIResources.upgradeLibraryDialog_text)) {
						return;
					}
					if (!upgradeLibrary(libPath, null)) {
						return;
					}
				}
				if (openLibrary(libPath)) {
					return;
				}
			}
			MsgDialog msgDialog = LibraryUIPlugin.getDefault().getMsgDialog();
			msgDialog.displayError(LibraryUIResources.openLibraryWizard_title,
					LibraryUIResources.invalidLibraryPath_msg,
					LibraryUIResources.invalidLibraryPath_reason);
		} while (libPath != null);
	}

	/**
	 * Opens a Method Library given the Library path.
	 * 
	 * @param path
	 *            Path to a Method Library.
	 * @return <code>true</code> if the Method Library is opened successfully.
	 */
	public boolean openLibrary(final String path) {
		Shell shell = Display.getCurrent().getActiveShell();

		final List errors = new ArrayList();
		// final IStatus[] status = new IStatus[1];

		// Do the work within an operation because this is a long running
		// activity that modifies the workspace.
		WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
			public void execute(IProgressMonitor monitor) {
				String taskName = LibraryUIResources.openingLibraryTask_name;
				monitor.beginTask(taskName, 2);
				try {
					monitor.setTaskName(taskName);
					monitor.worked(1);
					LibraryService.getInstance().closeCurrentMethodLibrary();
					MethodLibrary library = XMILibraryUtil
							.openMethodLibrary(path);
					LibraryService.getInstance().setCurrentMethodLibrary(
							library);
					LibraryUIPreferences.setSavedLibraryPath(path);
					// show Problems View if necessary
					ILibraryResourceSet resourceSet = ((ILibraryResourceSet) LibraryService
							.getInstance().getCurrentLibraryManager()
							.getEditingDomain().getResourceSet());
					if (resourceSet.hasUnresolvedProxy()) {
						SafeUpdateController.asyncExec(new Runnable() {
							public void run() {
								try {
									PlatformUI
											.getWorkbench()
											.getActiveWorkbenchWindow()
											.getActivePage()
											.showView(
													"org.eclipse.ui.views.ProblemView", null, IWorkbenchPage.VIEW_VISIBLE); //$NON-NLS-1$
								} catch (Exception e) {
									// couldn't open the problem view, too bad..
								}
							}
						});
					}
				} catch (Exception e) {
					if (!(e instanceof IOException && e.getMessage()
							.startsWith("###"))) { //$NON-NLS-1$
						LibraryUIPlugin.getDefault().getLogger().logError(e);
					}
					errors.add(e);
				} finally {
					monitor.done();
				}
			}
		};

		try {
			ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell) {
				protected void configureShell(Shell shell) {
					super.configureShell(shell);
					shell.setText(LibraryUIResources.openLibraryWizard_title);
				}
			};
			dialog.run(true, false, operation);
			if (errors.isEmpty()) {
				IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench()
						.getActiveWorkbenchWindow();
				if (workbenchWindow != null) {
					IWorkbenchPage activePage = workbenchWindow.getActivePage();
					if (activePage != null) {
						activePage.closeAllEditors(false);
					}
				}
				return true;
			} else {
				Iterator iter = errors.iterator();
				while (iter.hasNext()) {
					Exception e = (Exception) iter.next();
					if (e instanceof IOException) {
						String message = e.getMessage();
						if (message.startsWith("###")) { //$NON-NLS-1$
							String projectFileName = message.substring(3);

							String prompt = LibraryUIResources
									.bind(
											LibraryUIResources.readOnlyProjectFile_text,
											projectFileName);
							String[] buttonLabels = {
									LibraryUIResources.retryButton_text,
									LibraryUIResources.cancelButton_text };
							MessageDialog msgBox = new MessageDialog(Display
									.getCurrent().getActiveShell(),
									LibraryUIResources.openLibraryWizard_title,
									null, prompt, MessageDialog.WARNING,
									buttonLabels, 0);
							if (msgBox.open() == 0) {
								return openLibrary(path);
							} else {
								return true;
							}
						}
					}
				}
			}
		} catch (Exception e) {
			LibraryUIPlugin.getDefault().getLogger().logError(e);
		}

		return false;
	}

	/**
	 * Creates and opens a new Method Library.
	 * 
	 * @param path
	 *            The Method Library path.
	 * @return <code>true</code> if the Method Library is opened successfully.
	 */
	public boolean createLibrary(String path) {
		try {
			File libraryPath = new File(path);
			if (!libraryPath.exists()) {
				libraryPath.mkdirs();
			}
			XMILibraryUtil.createMethodLibrary(libraryPath.getName(), path);
			LibraryUIPreferences.setSavedLibraryPath(path);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * Adds the Configuration contribution to the workbench toolbar.
	 */
	public void addConfigurationContribution() {
		IWorkbench workbench = LibraryUIPlugin.getDefault().getWorkbench();
		if (workbench != null) {
			IWorkbenchWindow window = (IWorkbenchWindow) workbench
					.getActiveWorkbenchWindow();
			if (window != null && window instanceof ApplicationWindow) {
				// Check to see if the configuration contribution already
				// exists.
				ICoolBarManager coolBar = ((ApplicationWindow)window).getCoolBarManager();
				IContributionItem marker = null;
				IContributionItem coolBarItem = coolBar
						.find(TOOLBAR_CONFIG_CONTRIBUTION_ID);
				if (coolBarItem != null) {
					if (coolBarItem.isVisible()) {
						return;
					}
					IContributionItem[] items = coolBar.getItems();
					for (int i = 0; i < items.length; i++) {
						if (items[i] == coolBarItem) {
							coolBar.remove(TOOLBAR_CONFIG_CONTRIBUTION_ID);
							if (i + 1 < items.length) {
								marker = items[i + 1];
							}
						}
					}
				}

				IToolBarManager toolbarMgr = new ToolBarManager(SWT.FLAT
						| SWT.LEFT);
				ConfigurationContributionItem testItem = new ConfigurationContributionItem(
						null);
				toolbarMgr.add(testItem);
				ToolBarContributionItem contribItem = new ToolBarContributionItem(
						toolbarMgr, TOOLBAR_CONFIG_CONTRIBUTION_ID);
				if (marker != null) {
					coolBar.insertBefore(marker.getId(), contribItem);
				} else {
					coolBar.add(contribItem);
				}
			}
		}
	}

	/**
	 * Upgrades a Method Library to a new meta-model.
	 * 
	 * @param libDir
	 *            Path to a Method Library.
	 * @return <code>true</code> if the given Method Library is sucessfully
	 *         upgraded.
	 */
	public static boolean upgradeLibrary(final String libDir, final UpgradeCallerInfo callerInfo) {								
		Shell shell = Display.getCurrent().getActiveShell();
		if (UpgradeCallerInfo.isUpgradeLibrary(callerInfo)) {
			LibraryBackupUtil.promptBackupLibrary(shell, new File(libDir));
		}
		
		final StringBuffer errMsg = new StringBuffer();
		final boolean[] cancelFlagHolder = { false };

		// Do the work within an operation because this is a long running
		// activity that modifies the workbench.
		WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
			public void execute(IProgressMonitor monitor) {
				String libXmi = MultiFileSaveUtil.DEFAULT_LIBRARY_MODEL_FILENAME;
				if (callerInfo != null && callerInfo.getIsExportedPluginLib()) {
					libXmi = XMILibraryManager.exportFile;
				}
				monitor.beginTask(LibraryUIResources.upgradingLibraryTask_name, 10);
				monitor.worked(1);
				try {
					MappingUtil
							.migrate(
									libDir
											+ "/" + libXmi, monitor, callerInfo); //$NON-NLS-1$
				} 
				catch(OperationCanceledException e) {
					cancelFlagHolder[0] = true;
				}
				catch (Exception e) {
					CommonPlugin.INSTANCE.log(e);
					e.printStackTrace();
					String msg = e.getMessage();
					if (msg == null) {
						msg = LibraryUIResources.upgradeLibraryError_msg;
					}
					errMsg.append(msg);
				} finally {
					monitor.done();
				}
			}
		};

		try {
			// Run the operation and display the progress.
			ProgressMonitorDialog pmDialog = new ProgressMonitorDialog(shell) {			
			    protected Point getInitialSize() {
			        Point calculatedSize = super.getInitialSize();
			        if (calculatedSize.x < 675) {
			        	calculatedSize.x = 675;
					}
			        return calculatedSize;
			    }
			};		    
			pmDialog.run(true, false, operation);
			if(cancelFlagHolder[0]) {
				return false;
			}
			else if (errMsg.length() > 0) {
				LibraryUIPlugin.getDefault().getMsgDialog().displayError(
						LibraryUIResources.upgradeLibraryDialog_title,
						errMsg.toString());
				return false;
			}
			return true;
		} catch (Exception e) {
			LibraryUIPlugin.getDefault().getLogger().logError(e);
			e.printStackTrace();
			LibraryUIPlugin.getDefault().getMsgDialog().displayError(
					LibraryUIResources.upgradeLibraryDialog_title,
					LibraryUIResources.upgradeLibraryError_msg);
			return false;
		}
	}

	/**
	 * Returns the Library path set via the command line option "-library
	 * <path>".
	 */
	public static String getCommandLineLibraryPath() {
		return cmdLineLibPath;
	}

	/**
	 * Sets the Library path via the command line option "-library <path>".
	 */
	public static void setCommandLineLibraryPath(String libPath) {
		cmdLineLibPath = libPath;
		IPath path = Path.fromOSString(libPath);
		if (!path.isAbsolute()) {
			// TODO: Review implementation.
			cmdLineLibPath = System.getProperty("user.dir") + File.separator + libPath; //$NON-NLS-1$
		}
		if (XMILibraryUtil.isValidLibrary(cmdLineLibPath, true) != Status.OK_STATUS) {
			cmdLineLibPath = null;
		}
	}

	/**
	 * Sets the Library path via the command line option "-defaultlibrary <path>".
	 */
	public static void setCommandLineDefaultLibraryPath(String libPath) {
		cmdLineDefaultLibPath = libPath;
		IPath path = Path.fromOSString(libPath);
		if (!path.isAbsolute()) {
			// TODO: Review implementation.
			cmdLineDefaultLibPath = System.getProperty("user.dir") + File.separator + libPath; //$NON-NLS-1$
		}
		System.out.println("cmdLineDefaultLibPath=" + cmdLineDefaultLibPath);
		if (XMILibraryUtil.isValidLibrary(cmdLineDefaultLibPath, true) != Status.OK_STATUS) {
			cmdLineDefaultLibPath = null;
		}
	}
	
	/**
	 * Converts lib path to absolute library path
	 * 
	 * @param libPath
	 * @return Returns absolute library path
	 */
	public static String toAbsoluteLibraryPath(String libPath) {
		String absPath = libPath;

		IPath ecPath = Path.fromOSString(libPath);
		if (!ecPath.isAbsolute()) {
			// TODO: Review implementation.
			absPath = System.getProperty("user.dir") + File.separator + //$NON-NLS-1$
					"Method Libraries" + File.separator + libPath; //$NON-NLS-1$
		}

		return absPath;
	}

	/**
	 * Display library locked message
	 * 
	 */
	public static int displayLibraryLockedMessage() {
		Shell shell = null;
		Image image = null;
		try {
			shell = LibraryUIPlugin.getDefault().getWorkbench().getDisplay()
					.getActiveShell();
			image = shell.getImage();
		} catch (Exception e) {
		}
		MessageDialog msgDlg = new MessageDialog(shell,
				LibraryUIResources.openLibraryWizard_title, image,
				LibraryUIResources.libraryLocked_msg, MessageDialog.ERROR,
				new String[] {
						LibraryUIResources.libraryLocked_openButton_text,
						IDialogConstants.CANCEL_LABEL },
				1);

		return msgDlg.open();
	}

	/**
	 * Returns application name
	 * 
	 */
	public static String getAppName() {
		return appName;
	}

	/**
	 * Set application name
	 * @param appName
	 * 			Application name
	 */
	public static void setAppName(String appName) {
		LibraryUIManager.appName = appName;
	}
}