//------------------------------------------------------------------------------
// 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.actions.OpenLibraryAction;
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() {
		try {
			OpenLibraryAction action = new OpenLibraryAction();
			action.init(PlatformUI.getWorkbench().getActiveWorkbenchWindow());
			action.run(null);
		}
		catch (Exception e) {
			LibraryUIPlugin.getDefault().getLogger().logError(e);
		}
		
		/*
		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;
	}
}