//------------------------------------------------------------------------------
// 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.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.Status;
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.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.MethodLibrary;
import org.eclipse.epf.uma.util.MessageException;
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.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;

/**
 * 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();

	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;

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

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

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

	}

	/**
	 * Gets 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>".
	 * 
	 * @param libPath
	 *            path to a method library
	 */
	public static void setCommandLineLibraryPath(String libPath) {
		cmdLineLibPath = libPath;
		IPath path = Path.fromOSString(libPath);
		if (!path.isAbsolute()) {
			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>".
	 * 
	 * @param libPath
	 *            path to a method library
	 */
	public static void setCommandLineDefaultLibraryPath(String libPath) {
		cmdLineDefaultLibPath = libPath;
		IPath path = Path.fromOSString(libPath);
		if (!path.isAbsolute()) {
			cmdLineDefaultLibPath = System.getProperty("user.dir") + File.separator + libPath; //$NON-NLS-1$
		}
		if (DEBUG) {
			System.out
					.println("cmdLineDefaultLibPath=" + cmdLineDefaultLibPath);
		}
		if (XMILibraryUtil.isValidLibrary(cmdLineDefaultLibPath, true) != Status.OK_STATUS) {
			cmdLineDefaultLibPath = null;
		}
	}

	/**
	 * Adds the method configuration combobox to the system toolbar.
	 * <p>
	 * The method configuration combobox lists all the method configurations in
	 * the current method library.
	 */
	public void addConfigurationContribution() {
		try {
			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 item = new ConfigurationContributionItem(
							null);
					toolbarMgr.add(item);
					ToolBarContributionItem contribItem = new ToolBarContributionItem(
							toolbarMgr, TOOLBAR_CONFIG_CONTRIBUTION_ID);
					if (marker != null) {
						coolBar.insertBefore(marker.getId(), contribItem);
					} else {
						coolBar.add(contribItem);
					}
				}
			}
		} catch (Exception e) {
			LibraryUIPlugin.getDefault().getLogger().logError(e);
			if (DEBUG) {
				e.printStackTrace();
			}
		}
	}

}