//------------------------------------------------------------------------------
// 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 java.util.Map;

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.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.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
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<String, ManagerDef> 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<String, ManagerDef>();
			
			// 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) {
				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, info)) {
					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) {
		Map<String, String> args = new HashMap<String, String>();
		args.put(XMILibraryManager.ARG_LIBRARY_PATH, path);
		return openLibrary(XMILibraryManager.LIBRARY_TYPE, args);
	}
	
	public boolean openLibrary(final String type, final Map args) {
		final String path = (String) args.get(XMILibraryManager.ARG_LIBRARY_PATH);
		
		Shell shell = Display.getCurrent().getActiveShell();

		final List<Exception> errors = new ArrayList<Exception>();

		// 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 = LibraryService.getInstance().openMethodLibrary(type, args);
					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) {
									LibraryUIPlugin.getDefault().getLogger().logError(e);
								}
							}
						});
					}
				} 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;
	}

	/**
	 * 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;
	}
}