//------------------------------------------------------------------------------
// 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.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
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.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.epf.common.service.utils.CommandLineRunUtil;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.I18nUtil;
import org.eclipse.epf.common.utils.NetUtil;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceException;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.IRunnableWithProgress;
import org.eclipse.epf.library.layout.LayoutResources;
import org.eclipse.epf.library.persistence.ILibraryResourceSet;
import org.eclipse.epf.library.preferences.LibraryPreferences;
import org.eclipse.epf.library.prefs.PreferenceUtil;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.library.ui.actions.ConfigurationContributionItem;
import org.eclipse.epf.library.ui.dialogs.CopyLibraryDialog;
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.migration.MappingUtil;
import org.eclipse.epf.persistence.migration.UpgradeCallerInfo;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.util.MessageException;
import org.eclipse.jface.action.CoolBarManager;
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.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.osgi.service.datalocation.Location;
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.IEditorReference;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.progress.WorkbenchJob;

/**
 * The default Library UI Manager implementation.
 * <p>
 * A Library Manager provides the user interface for creating and opening a
 * method library.
 * 
 * @author Kelvin Low
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class LibraryUIManager {

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

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

	private static final String CONFIG_VIEW_ID = "org.eclipse.epf.authoring.ui.views.ConfigurationView"; //$NON-NLS-1$

	private static final String PROCESS_EDITOR_ID = "org.eclipse.epf.authoring.ui.editors.ProcessEditor"; //$NON-NLS-1$
	
	private static final String REPORT_PERS_ID = "org.eclipse.birt.report.designer.ui.ReportPerspective"; //$NON-NLS-1$

	private static LibraryUIManager instance = null;
	
	private static boolean skipInstallPathCheck = false;
	
	// The URI of the method library that will be opened regardless of the
	// saved library preferences.
	protected static URI libraryURI;

	// The URI of the method library that will be opened only if there are
	// no saved library preferences.
	protected static URI defaultLibraryURI;
	protected static URI defaultLibraryURI_NL;
	private boolean libraryInitialized = false;
	
	protected ConfigurationContributionItem configCombo = null;

	/**
	 * 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() {
		// Monitor perspective changes to display/hide the configuration combo.
		IWorkbenchWindow window = PlatformUI.getWorkbench()
				.getActiveWorkbenchWindow();
		if (window != null) {
			window.addPerspectiveListener(new IPerspectiveListener() {
				public void perspectiveActivated(IWorkbenchPage page,
						IPerspectiveDescriptor desc) {
					checkConfigurationContribution();
				}

				public void perspectiveChanged(IWorkbenchPage page,
						IPerspectiveDescriptor desc, String id) {
					checkConfigurationContribution();
				}
			});
		}
	}
	
	/**
	 * Creates and opens a new method library.
	 * 
	 * @param path
	 *            the method library path
	 * @return <code>true</code> if the method library is created and 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;
		}
	}
	
	/**
	 * Opens the last opened method library in a non-UI job. If successful,
	 * successRunnable will be run, otherwise nextRunnable will be run.
	 * 
	 * @param path
	 *            URI path to a method library
	 * @return <code>true</code> if the method library is opened successfully
	 */
	private void openLastOpenedLibrary(final Runnable successRunnable, final Runnable nextRunnable) {
		try {
			
			// first check for saved lib in preference
			// so that we don't show progress monitor if there's no lib
			String savedMethodLibraryURI = LibraryPreferences
				.getSavedMethodLibraryURI();
			URI uri = new URI(savedMethodLibraryURI);
			if (uri.getPath().length() == 0) {
				nextRunnable.run();
				return;
			}
			
			final WorkspaceJob openLibraryJob = new WorkspaceJob("Open last opened library") {

				@Override
				public IStatus runInWorkspace(IProgressMonitor monitor)
						throws CoreException {
					try {
						monitor.beginTask(StrUtil.EMPTY_STRING, IProgressMonitor.UNKNOWN);
						LibraryService.getInstance().closeCurrentMethodLibrary();
						LibraryService.getInstance().openLastOpenedMethodLibrary();
					} catch (Exception e) {
						LibraryUIPlugin.getDefault().getLogger().logError(e);
					}
					return Status.OK_STATUS;
				}
				
			};
			BusyIndicatorHelper.setUserInterfaceActive(false);
			final Integer openLibraryJobBusyId = BusyIndicatorHelper.showWhile(PlatformUI.getWorkbench().getDisplay());
			PlatformUI.getWorkbench().getProgressService().showInDialog(null, openLibraryJob);
			openLibraryJob.setSystem(true);
			openLibraryJob.addJobChangeListener(new JobChangeAdapter() {
				@Override
				public void done(IJobChangeEvent event) {
					// UI activation job
					WorkbenchJob reactivateUIJob = new WorkbenchJob(StrUtil.EMPTY_STRING) {

						@Override
						public IStatus runInUIThread(IProgressMonitor monitor) {
							BusyIndicatorHelper.setUserInterfaceActive(true);
							BusyIndicatorHelper.hideWhile(PlatformUI.getWorkbench().getDisplay(), openLibraryJobBusyId);
							// Show Problems View if necessary.
							ILibraryManager libMgr = LibraryService
									.getInstance().getCurrentLibraryManager();
							if(libMgr != null) {
								ILibraryResourceSet resourceSet = (ILibraryResourceSet) libMgr.getEditingDomain().getResourceSet();
								if (resourceSet.hasUnresolvedProxy()) {
									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);
									}
								}
							}

							return Status.OK_STATUS;
						}
						
					};
					reactivateUIJob.setSystem(true);
					reactivateUIJob.schedule();
					
					if(LibraryService.getInstance().getCurrentMethodLibrary() != null) {
						successRunnable.run();
					} else {
						nextRunnable.run();
					}
				}

			});
			openLibraryJob.schedule();
		} catch (Exception e) {
			// don't do anything
			LibraryUIPlugin.getDefault().getLogger().logError(e);
		}		
	}
	
	/**
	 * Opens a method library with the specified library path URI in a non-UI
	 * job. If successful, successRunnable will be run, otherwise nextRunnable
	 * will be run.
	 * 
	 * @param path
	 *            URI path to a method library
	 * @return <code>true</code> if the method library is opened successfully
	 */
	private void openLibrary(final URI uri, final Runnable successRunnable, final Runnable nextRunnable) {
		if(uri == null) {
			if (nextRunnable != null) {
				nextRunnable.run();
			}
			return;
		}
		
		final Map<String, Object> args = new HashMap<String, Object>();
		args.put(XMILibraryManager.ARG_LIBRARY_PATH, new File(uri).getAbsolutePath());
		final List<Exception> errors = new ArrayList<Exception>();

		WorkspaceJob openLibraryJob = new WorkspaceJob(LibraryUIResources.openingLibraryTask_name) {
		
			@Override
			public IStatus runInWorkspace(IProgressMonitor monitor)
					throws CoreException {
				try {
					monitor.beginTask(StrUtil.EMPTY_STRING, IProgressMonitor.UNKNOWN);
					LibraryService.getInstance().closeCurrentMethodLibrary();
					String newPath = handleLibraryOnReadOnlyInstallPath(uri);
					if (newPath != null) {
						args.put(XMILibraryManager.ARG_LIBRARY_PATH, newPath);
					}
					MethodLibrary library = LibraryService.getInstance()
							.openMethodLibrary(XMILibraryManager.LIBRARY_TYPE, args);
					LibraryService.getInstance().setCurrentMethodLibrary(
							library);
					String path = (String) args.get(XMILibraryManager.ARG_LIBRARY_PATH);
					LibraryUIPreferences.setSavedLibraryPath(path);
				} catch (LibraryServiceException e) {
					errors.add(e);
				} finally {
					monitor.done();
				}
				return Status.OK_STATUS;
			}
		
		};
		openLibraryJob.setSystem(true);
		final Integer openLibraryJobBusyId = BusyIndicatorHelper.showWhile(PlatformUI.getWorkbench().getDisplay());
		BusyIndicatorHelper.setUserInterfaceActive(false);
		PlatformUI.getWorkbench().getProgressService().showInDialog(null, openLibraryJob);
		openLibraryJob.addJobChangeListener(new JobChangeAdapter() {
			@Override
			public void done(IJobChangeEvent event) {
				// UI activation job
				WorkbenchJob reactivateUIJob = new WorkbenchJob(StrUtil.EMPTY_STRING) {

					@Override
					public IStatus runInUIThread(IProgressMonitor monitor) {
						BusyIndicatorHelper.setUserInterfaceActive(true);
						BusyIndicatorHelper.hideWhile(PlatformUI.getWorkbench().getDisplay(), openLibraryJobBusyId);
						// Show Problems View if necessary.
						ILibraryManager libMgr = LibraryService
							.getInstance().getCurrentLibraryManager();
						if(libMgr != null) {
							ILibraryResourceSet resourceSet = (ILibraryResourceSet) libMgr.getEditingDomain().getResourceSet();
							if (resourceSet.hasUnresolvedProxy()) {
								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);
								}
							}
						}
						postOpenLibrary(errors, (String) args.get(XMILibraryManager.ARG_LIBRARY_PATH));
						if(errors.isEmpty()) {
							successRunnable.run();
						} else if (nextRunnable != null) {
							nextRunnable.run();
						}
						return Status.OK_STATUS;
					}
					
				};
				reactivateUIJob.setSystem(true);
				reactivateUIJob.schedule();
			}

		});
		openLibraryJob.schedule();
	}

	/**
	 * 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, Object> args = new HashMap<String, Object>();
		args.put(XMILibraryManager.ARG_LIBRARY_PATH, path);
		return openLibrary(XMILibraryManager.LIBRARY_TYPE, args);
	}

	/**
	 * Opens a method library.
	 * 
	 * @param type
	 *            the method library type
	 * @param params
	 *            method library specific arguments
	 * @return <code>true</code> if the method library is opened successfully
	 */
	public boolean openLibrary(final String type, final Map<String, Object> args) {
		final String path = (String) args
				.get(XMILibraryManager.ARG_LIBRARY_PATH);

		final List<Exception> errors = new ArrayList<Exception>();
		
		UserInteractionHelper.getUIHelper().runWithProgress(new IRunnableWithProgress() {

			public void run(IProgressMonitor monitor)
					throws InvocationTargetException, InterruptedException {
				try {
					LibraryService.getInstance().closeCurrentMethodLibrary();
					URI libURI = Path.fromOSString(path).toFile().toURI();
					String newPath = handleLibraryOnReadOnlyInstallPath(libURI);
					if (newPath != null) {
						args.put(XMILibraryManager.ARG_LIBRARY_PATH, newPath);
					}
					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);
				}
			}
			
		}, false, LibraryUIResources.openingLibraryTask_name);
		
		return postOpenLibrary(errors, (String) args.get(XMILibraryManager.ARG_LIBRARY_PATH));
	}

	private boolean postOpenLibrary(List<Exception> errors, String libPath) {
		try {
			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<Exception> iter = errors.iterator();
				while (iter.hasNext()) {
					Exception e = 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(libPath);
							} else {
								return true;
							}
						}
					} else {
						Throwable ex = e;
						for (ex = e; ex != null
								&& !(ex instanceof MessageException); ex = ex
								.getCause())
							;
						String msg = ex != null && ex.getMessage() != null ? ex
								.getMessage() : e.getMessage() != null ? e
								.getMessage() : e.toString();
						LibraryUIPlugin
								.getDefault()
								.getMsgDialog()
								.displayError(
										LibraryUIResources.openLibraryWizard_title,
										msg, e);
					}
				}
			}
		} catch (Exception e) {
			LibraryUIPlugin.getDefault().getLogger().logError(e);
		}

		return false;
	}

	/**
	 * Upgrades a method library to a new meta-model.
	 * 
	 * @param libPath
	 *            path to a method library folder
	 * @return <code>true</code> if the given method library is sucessfully
	 *         upgraded
	 */
	public static boolean upgradeLibrary(final String libPath,
			final UpgradeCallerInfo callerInfo) {
		Shell shell = Display.getCurrent().getActiveShell();
		if (!CommandLineRunUtil.getInstance().isNeedToRun() && UpgradeCallerInfo.isUpgradeLibrary(callerInfo)) {
			LibraryBackupUtil.promptBackupLibrary(shell, new File(libPath));
		}

		String libXmi = MultiFileSaveUtil.DEFAULT_LIBRARY_MODEL_FILENAME;
		if (callerInfo != null && callerInfo.getIsExportedPluginLib()) {
			libXmi = XMILibraryManager.exportFile;
		}
		return upgradeLibrary(new File(libPath, libXmi), callerInfo);
	}

	public static boolean upgradeLibrary(final File libFile,
			final UpgradeCallerInfo callerInfo) {
		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) {
				monitor.beginTask(LibraryUIResources.upgradingLibraryTask_name,
						10);
				monitor.worked(1);
				try {
					MappingUtil.migrate(libFile.getAbsolutePath(), monitor,
							callerInfo);
				} catch (OperationCanceledException e) {
					cancelFlagHolder[0] = true;
				} catch (Exception e) {
					LibraryUIPlugin.getDefault().getLogger().logError(e);
					if (DEBUG) {
						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(Display
					.getCurrent().getActiveShell()) {
				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) {
				IStatus status = new Status(IStatus.ERROR,
						LibraryUIPlugin.PLUGIN_ID, 0, "", null) {//$NON-NLS-1$
					public IStatus[] getChildren() {
						IStatus[] ret = new Status[1];
						IStatus cs = new Status(IStatus.ERROR,
								LibraryUIPlugin.PLUGIN_ID, 0,
								errMsg.toString(), null);
						ret[0] = cs;
						return ret;
					}

					public boolean isMultiStatus() {
						return true;
					}
				};

				LibraryUIPlugin.getDefault().getMsgDialog().displayError(
						LibraryUIResources.upgradeLibraryDialog_title,
						LibraryUIResources.upgradeLibraryError_msg, status);

				return false;
			}
			return true;
		} catch (Exception e) {
			LibraryUIPlugin.getDefault().getLogger().logError(e);
			if (DEBUG) {
				e.printStackTrace();
			}
			LibraryUIPlugin.getDefault().getMsgDialog().displayError(
					LibraryUIResources.upgradeLibraryDialog_title,
					LibraryUIResources.upgradeLibraryError_msg);
			return false;
		}

	}
	
	/**
	 * Sets the path of the method library that will be opened only if there are
	 * no saved library preferences.
	 * 
	 * @param libraryPath
	 *            path to a method library
	 */
	public static void setCommandLineDefaultLibrary(String libraryPath) {
		if (libraryPath != null && libraryPath.length() > 0) {
			IPath path = Path.fromOSString(libraryPath);
			try {
				defaultLibraryURI = path.toFile().toURI();
			} catch (Exception e) {
				defaultLibraryURI = null;
				LibraryPlugin.getDefault().getLogger().logError(e);
			}
		}
	}

	/**
	 * Sets the path of the method library that will be opened regardless of the
	 * saved library preferences.
	 * 
	 * @param libraryPath
	 *            path to a method library
	 */
	public static void setCommandLineLibrary(String libraryPath) {
		if (libraryPath != null && libraryPath.length() > 0) {
			IPath path = Path.fromOSString(libraryPath);
			try {
				libraryURI = path.toFile().toURI();
			} catch (Exception e) {
				libraryURI = null;
				LibraryPlugin.getDefault().getLogger().logError(e);
			}
		}
	}
	
	/**
	 * Checks whether the method configuration combobox should be added to the
	 * system toolbar.
	 * <p>
	 * The method configuration combobox lists all the method configurations in
	 * the current method library.
	 */
	public void checkConfigurationContribution() {
		IWorkbench workbench = LibraryUIPlugin.getDefault().getWorkbench();
		if (workbench != null) {
			IWorkbenchWindow window = (IWorkbenchWindow) workbench
					.getActiveWorkbenchWindow();
			if (window != null && window instanceof ApplicationWindow) {
				ICoolBarManager coolBarMgr = ((ApplicationWindow) window)
						.getCoolBarManager();
				try {
					IWorkbenchPage activePage = window.getActivePage();
					if (activePage != null) {
						if (foundConfigView(activePage)
								|| foundProcessEditor(activePage)
								|| foundPerspective(activePage, REPORT_PERS_ID)) {
							showConfigurationContribution(coolBarMgr);
						} else {
							hideConfigurationContribution(coolBarMgr);
						}
					}
				} catch (Exception e) {
					LibraryUIPlugin.getDefault().getLogger().logError(e);
					if (DEBUG) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	/**
	 * Checks for the presence of the Configuration view in the active workbench
	 * page.
	 */
	private boolean foundConfigView(IWorkbenchPage activePage) {
		if (activePage == null) return false;
		return activePage.findView(CONFIG_VIEW_ID) != null;
	}

	/**
	 * Checks for the presence of a Process editor in the active workbench.
	 * page.
	 */
	private boolean foundProcessEditor(IWorkbenchPage activePage) {
		if (activePage == null) return false;
		IEditorReference[] editorRefs = activePage.findEditors(null,
				PROCESS_EDITOR_ID, IWorkbenchPage.MATCH_ID);
		return editorRefs != null && editorRefs.length > 0;
	}
	
	/**
	 * Checks for the presence of Report Perspective in the active workbench
	 * page. 
	 */
	private boolean foundPerspective(IWorkbenchPage activePage, String persId) {
		if (activePage.getPerspective().getId().equals(persId)) {		
			return true;
		}
		
		return false;
	}

	/**
	 * Displays the method configuration combobox in the system toolbar.
	 */
	private void showConfigurationContribution(ICoolBarManager coolBarMgr)
			throws Exception {
		// Check for the method configuration combobox toolbar.
		IContributionItem configToolBar = coolBarMgr
				.find(TOOLBAR_CONFIG_CONTRIBUTION_ID);

		if (configToolBar != null) {
			// Make sure the toolbar has the method configuration combobox
			// contribution.
			if (configToolBar instanceof ToolBarContributionItem) {
				IToolBarManager toolBarMgr = ((ToolBarContributionItem) configToolBar)
						.getToolBarManager();
				if (toolBarMgr != null) {
					IContributionItem[] toolBarItems = toolBarMgr.getItems();
					if (toolBarItems != null && toolBarItems.length > 0) {
						for (int i = 0; i < toolBarItems.length; i++) {
							toolBarItems[i].setVisible(true);
						}
						configToolBar.setVisible(true);
						updateSystemToolBar(coolBarMgr);
						return;
					}
				}

				// The method configuration combobox toolbar has been restored
				// via a saved perspective, add the method configuration
				// combobox contribution.
				configCombo = new ConfigurationContributionItem(
						null);
				toolBarMgr.add(configCombo);
				configToolBar.setVisible(true);
				updateSystemToolBar(coolBarMgr);
				return;
			}
		}

		IToolBarManager toolBarMgr = new ToolBarManager(SWT.FLAT | SWT.LEFT);
		configCombo = new ConfigurationContributionItem(
				null);
		toolBarMgr.add(configCombo);
		ToolBarContributionItem configComboToolBar = new ToolBarContributionItem(
				toolBarMgr, TOOLBAR_CONFIG_CONTRIBUTION_ID);
		coolBarMgr.add(configComboToolBar);
	}

	/**
	 * Hides the method configuration combobox from the system toolbar.
	 */
	private void hideConfigurationContribution(ICoolBarManager coolBarMgr)
			throws Exception {
		// Check for the method configuration combobox toolbar.
		IContributionItem configToolBar = coolBarMgr
				.find(TOOLBAR_CONFIG_CONTRIBUTION_ID);

		if (configToolBar == null) {
			return;
		}

		// Hide the method configuration combobox contribution from the toolbar.
		if (configToolBar instanceof ToolBarContributionItem) {
			IToolBarManager toolBarMgr = ((ToolBarContributionItem) configToolBar)
					.getToolBarManager();
			IContributionItem[] toolBarItems = toolBarMgr.getItems();
			for (int i = 0; i < toolBarItems.length; i++) {
				toolBarItems[i].setVisible(false);
			}
		}

		// Hide the method configuration combobox toolbar contribution.
		configToolBar.setVisible(false);

		// Update the the system tool bar.
		updateSystemToolBar(coolBarMgr);
	}

	/**
	 * Updates the system tool bar.
	 */
	private void updateSystemToolBar(ICoolBarManager coolBarMgr) {
		if (coolBarMgr instanceof CoolBarManager) {
			((CoolBarManager) coolBarMgr).update(true);
		}
	}

	/**
	 * Adds a part listener so the library will open upon "startup"
	 * "startup" means when the view with the specified id is first
	 * visible
	 */
	public void addMethodViewPartListener(final String id) {
		IWorkbench workbench = LibraryUIPlugin.getDefault().getWorkbench();
		if (workbench != null) {
			IWorkbenchWindow window = (IWorkbenchWindow) workbench
					.getActiveWorkbenchWindow();
			if (window != null && window instanceof ApplicationWindow) {
				try {
					final IWorkbenchPage activePage = window.getActivePage();
					activePage.addPartListener(new IPartListener2() {

						public void partActivated(
								IWorkbenchPartReference partRef) {
						}

						public void partBroughtToTop(
								IWorkbenchPartReference partRef) {
						}

						public void partClosed(IWorkbenchPartReference partRef) {
						}

						public void partDeactivated(
								IWorkbenchPartReference partRef) {
						}

						public void partHidden(IWorkbenchPartReference partRef) {
						}

						public void partInputChanged(
								IWorkbenchPartReference partRef) {
						}

						public void partOpened(IWorkbenchPartReference partRef) {
						}

						public void partVisible(IWorkbenchPartReference partRef) {
							if (partRef.getId().equals(id)) {
								activePage.removePartListener(this);
								startupOpenLibrary();
							}
						}
						
					});
				} catch (Exception e) {
					LibraryUIPlugin.getDefault().getLogger().logError(e);
					if (DEBUG) {
						e.printStackTrace();
					}
				}
			}
		}

	}
	
	
	/**
	 * Opens the library upon startup
	 * 1.  First tries to open the library specified by -library
	 * 2.  Then tries to open the last opened library
	 * 3.  Finally, tries to open the library specified by -defaultlibrary
	 */
	public void startupOpenLibrary() {
		if (libraryInitialized == true) {
			return;
		}
		libraryInitialized = true;
		try {
			String savedMethodLibraryURI = LibraryPreferences.getSavedMethodLibraryURI();
			final boolean hasSavedUri = savedMethodLibraryURI != null && savedMethodLibraryURI.length() > 0;
			
			final String lastSavedConfigName = PreferenceUtil.getSavedLastConfig();
			
			final Runnable successRunnable = new Runnable() {

				public void run() {
					if (LibraryService.getInstance().getCurrentMethodLibrary() != null) {
						MethodConfiguration savedConfig = LibraryServiceUtil
								.getMethodConfiguration(LibraryService.getInstance()
								.getCurrentMethodLibrary(), lastSavedConfigName);
						if (savedConfig != null) {
							LibraryService.getInstance().setCurrentMethodConfiguration(savedConfig);
						}
					}
				}
				
			};
			
			final Runnable openDefaultLibraryRunnable = new Runnable() {

				public void run() {
					if (defaultLibraryURI != null && !hasSavedUri) {
						// Try loading the NL library first.
						Locale locale = Locale.getDefault();
						String defaultLibraryStr = new File(defaultLibraryURI)
								.getAbsolutePath();
						String localizedLibPath = I18nUtil.getLocalizedFile(
								FileUtil.removeAllSeparator(defaultLibraryStr),
								locale);
						if (localizedLibPath != null) {
							defaultLibraryURI_NL = StrUtil.toURI(localizedLibPath);
						}
						
						final URI defautlLibUrl = defaultLibraryURI_NL != null ? defaultLibraryURI_NL : defaultLibraryURI;
						if (defautlLibUrl != null) {
//							openLibrary(defautlLibUrl, successRunnable, new Runnable() {
//								public void run() {
//									openLibrary(defautlLibUrl, successRunnable, null);
//								}
//							});
							openLibrary(defautlLibUrl, successRunnable, null);
						}
						
					}
				}
				
			};
			
			openLibrary(libraryURI, successRunnable, new Runnable() {

				public void run() {
					openLastOpenedLibrary(successRunnable, openDefaultLibraryRunnable);
				}

			});
			
//			if (libraryURI != null && openLibrary(libraryURI)) {
//			} else if (openLastOpenedLibrary()) {
//			} else if (defaultLibraryURI != null && !hasSavedUri) {
//				// Try loading the NL library first.
//				Locale locale = Locale.getDefault();
//				String defaultLibraryStr = new File(defaultLibraryURI)
//						.getAbsolutePath();
//				String localizedLibPath = I18nUtil.getLocalizedFile(
//						FileUtil.removeAllSeparator(defaultLibraryStr),
//						locale);
//				if (localizedLibPath != null) {
//					defaultLibraryURI_NL = StrUtil.toURI(localizedLibPath);
//				}
//				if (defaultLibraryURI_NL != null && openDefaultLibrary(defaultLibraryURI_NL)) {
//				} else {
//					openDefaultLibrary(defaultLibraryURI);
//				}
//			}
			
			
		} catch (Exception e) {
			LibraryUIPlugin.getDefault().getLogger().logError(e);
		}
	}
	
	/**
	 * 
	 * @param path
	 * @return null if path is not on install path or not read-only or if user 
	 * declines to copy the library to a writable location. Returns
	 * a new path if the user wishes to open the library in a different location
	 * 
	 */
	private String handleLibraryOnReadOnlyInstallPath(URI libURI) {
		if (isSkipInstallPathCheck()) {
			return null;
		}
		try {
			boolean readOnly = false;
			
			// determine if path is in Installation directory
			File libPathFile = new File(libURI);
			if (!libPathFile.exists()) {
				return null;
			}
			Location installLocation = Platform.getInstallLocation();
			URL installLocationURL = installLocation.getURL();
			URI installLocationURI = new URI(NetUtil.encodeFileURL(installLocationURL.toExternalForm()));
			File installLocFile = new File(installLocationURI);
			String canonicalLibPath = NetUtil.decodedFileUrl(libPathFile.getCanonicalPath());
			String canonicalInstallPath = NetUtil.decodedFileUrl(installLocFile.getCanonicalPath());;

			if (!canonicalLibPath.startsWith(canonicalInstallPath)) {
				return null;
			}
			// show dialog, allow copy to new path

			final String defaultCopyPath = new File(new File(LibraryUIPreferences.getDefaultLibraryPath()).getParent(), libPathFile.getName()).getAbsolutePath();

			final StringBuffer newPath = new StringBuffer();
			
			UserInteractionHelper.getUIHelper().runSafely(new Runnable() {
				public void run() {
					String title = LibraryUIResources.copyLibraryDialog_title;
					String message = LibraryUIResources.copyLibraryDialog_text_readOnlyLib;
					CopyLibraryDialog dlg = new CopyLibraryDialog(Display.getCurrent().getActiveShell(), title,
							message, defaultCopyPath);

					if (dlg.open() == Dialog.OK) {
						newPath.append(dlg.getPath());
					}
				}
			}, true);
			if (newPath.length() > 0) {
				copyLibrary(libPathFile, new File(newPath.toString()));
				return newPath.toString();
			} else {
				return null;
			}

		} catch (URISyntaxException uriEx) {
			LibraryUIPlugin.getDefault().getLogger().logError(uriEx);
			return null;
		} catch (IOException ioEx) {
			LibraryUIPlugin.getDefault().getLogger().logError(ioEx);
			return null;
		}
	}
	
	/**
	 * Back up library 
	 * 
	 * @param source
	 * @param dest
	 */
	private static void copyLibrary(final File source, final File dest) {
		Runnable runnable = new Runnable() {
			public void run() {
				try {
					// excude the non-library files that might be locked by rmc.
					// these files may cause backup to fail due to file lock.
					String excludes = ".lock"; //$NON-NLS-1$
					LayoutResources.copyDir(source, dest, "**", excludes); //$NON-NLS-1$
				} catch (RuntimeException e) {
					e.printStackTrace();
				}
			}
		};

		UserInteractionHelper.runWithProgress(runnable,
				LibraryUIResources.copyLibraryTask_name);
	}

	/**
	 * 
	 * @return the current MethodConfiguration dropdown box
	 */
	public ConfigurationContributionItem getConfigCombo() {
		return configCombo;
	}

	public static boolean isSkipInstallPathCheck() {
		return skipInstallPathCheck;
	}

	public static void setSkipInstallPathCheck(boolean skipInstallPathCheck) {
		LibraryUIManager.skipInstallPathCheck = skipInstallPathCheck;
	}
		
}