//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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.authoring.ui.actions;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.persistence.util.LibrarySchedulingRule;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation;

/**
 * Runs operation that locks the library for the duration of its execution
 * 
 * @author Phong Nguyen Le - Aug 14, 2006
 * @since  1.0
 */
public class LibraryLockingOperationRunner implements IRunnableContext {

	private IProgressMonitor progressMonitor;
	
	public LibraryLockingOperationRunner() {
	}	
	
	private void doRun(final IRunnableWithProgress runnable, boolean workUnknown) throws InvocationTargetException,
			InterruptedException {
		IRunnableWithProgress _runnable;
		if(workUnknown) {
			_runnable = new IRunnableWithProgress() {

				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
					monitor.beginTask("", 2); //$NON-NLS-1$
					monitor.worked(1);
					try {
						runnable.run(monitor);
						monitor.worked(2);
					}
					finally {
						monitor.done();
					}
					
				}
				
			};
		}
		else {
			_runnable = runnable;
		}
		WorkspaceModifyDelegatingOperation op = new WorkspaceModifyDelegatingOperation(_runnable, 
				new LibrarySchedulingRule(LibraryService.getInstance().getCurrentMethodLibrary()));
		op.run(getProgressMonitor());
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.operation.IRunnableContext#run(boolean, boolean, org.eclipse.jface.operation.IRunnableWithProgress)
	 */
	public void run(boolean fork, boolean cancelable,
			final IRunnableWithProgress runnable) throws InvocationTargetException,
			InterruptedException {
		doRun(runnable, false);
	}

	public void run(IRunnableWithProgress runnable) {
		try {
			doRun(runnable, true);
		} catch (InvocationTargetException e) {
			Throwable cause = e.getCause();
			if(cause instanceof RuntimeException) {
				throw (RuntimeException)cause;
			}
			else {
				if(cause == null) {
					cause = e;
				}
				AuthoringUIPlugin.getDefault().getLogger().logError(cause);
				try {
					String msg = cause.getMessage() != null ? cause.getMessage() : cause.toString(); 
					AuthoringUIPlugin.getDefault().getMsgDialog().displayError(AuthoringUIResources.errorDialog_title, msg, cause);
				}
				catch(Exception ex) {
					
				}				
			}
		} catch (InterruptedException e) {
			return;
		}
	}
	
	/**
	 * @return
	 */
	public IProgressMonitor getProgressMonitor() {
		if(progressMonitor == null) {
			progressMonitor = new NullProgressMonitor();
		}
		return progressMonitor;
	}

	/**
	 * @param progressMonitor the progressMonitor to set
	 */
	public void setProgressMonitor(IProgressMonitor progressMonitor) {
		this.progressMonitor = progressMonitor;
	}
}
