//------------------------------------------------------------------------------
// 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 java.util.Collection;
import java.util.EventObject;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.ui.action.DeleteAction;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.command.DeleteMethodElementCommand;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.persistence.MultiFileResourceSetImpl;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.jface.operation.IRunnableWithProgress;


/**
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class MethodElementDeleteAction extends DeleteAction implements ILibraryAction {
	protected Collection selection = null;

	protected boolean confirm = true;

	private IProgressMonitor progressMonitor;

	public MethodElementDeleteAction() {
		super();
	}

	/**
	 * Creates a new instance.
	 * 
	 * @param domain
	 */
	public MethodElementDeleteAction(EditingDomain domain) {
		super(domain);
	}

	/**
	 * Creates a new instance.
	 * 
	 * @param domain
	 * @param confirm
	 *            flag indicates whether user confirmation is required. If
	 *            <code>false</code>, executing this command will not
	 *            interact with user and the default behavior will apply.
	 */
	public MethodElementDeleteAction(EditingDomain domain, boolean confirm) {
		this(domain);
		this.confirm = confirm;
	}

	public Command createCommand(Collection selection) {
		this.selection = selection;

		DeleteMethodElementCommand cmd = createMethodElementDeleteCommand();
		cmd
				.addCommandListener(new DeleteMethodElementCommand.CommandListener() {

					public void notifyExecuted(EventObject eventObject) {
						DeleteMethodElementCommand cmd = (DeleteMethodElementCommand) eventObject
								.getSource();
						didDelete(cmd.getResult());
					}

					public void notifyFailure(EventObject eventObject) {
						deleteFailed();
					}

				});
		return cmd;
	}

	protected void deleteFailed() {
	}

	public DeleteMethodElementCommand createMethodElementDeleteCommand() {
		return new DeleteMethodElementCommand(super.createCommand(selection),
				selection) {
			protected void loadOppositeFeatures(List oppositeFeatures,
					Set deletedGUIDs) {
				MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) LibraryService
						.getInstance().getCurrentMethodLibrary().eResource()
						.getResourceSet();
				resourceSet
						.loadOppositeFeatures(oppositeFeatures, deletedGUIDs);
			}
		};
	}

	protected void didDelete(Collection deletedElements) {

	}

	protected String getDeleteConfirmationMessage() {
		return AuthoringUIResources.MethodElementDeleteAction_deleteconfirm_text; //$NON-NLS-1$
	}

	protected boolean confirmDelete() {
		if (!confirm) {
			return true;
		}

		if (selection == null || selection.isEmpty())
			return false;

		int i = 0;
		StringBuffer elementStr = new StringBuffer();

		for (Iterator it = selection.iterator(); it.hasNext();) {
			Object obj = TngUtil.unwrap(it.next());
			if (obj instanceof MethodElement) {
				if (i > 0) {
					elementStr.append(", "); //$NON-NLS-1$
				}
				elementStr.append(((MethodElement) obj).getName());

				i++;
			}
		}

		Object[] args = { elementStr.toString() };
		String msg = AuthoringUIResources.bind(AuthoringUIResources.confirmDeleteDialog_msg, args); // NON-NLS-1$

		String title = AuthoringUIResources.confirmDeleteDialog_title; //$NON-NLS-1$
		boolean deleteOk = AuthoringUIPlugin.getDefault().getMsgDialog()
				.displayConfirmation(title, msg);
		return deleteOk;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.authoring.ui.actions.ILibraryAction#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void setProgressMonitor(IProgressMonitor monitor) {
		progressMonitor = monitor;
	}

	/**
	 * @return the progressMonitor
	 */
	protected IProgressMonitor getProgressMonitor() {
		if(progressMonitor == null) {
			progressMonitor = new NullProgressMonitor();
		}
		return progressMonitor;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.edit.ui.action.CommandActionHandler#run()
	 */
	public void run() {
		LibraryLockingOperationRunner runner = new LibraryLockingOperationRunner();
		runner.setProgressMonitor(getProgressMonitor());
		runner.run(new IRunnableWithProgress() {

			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
				performDelete();
			}
			
		});
	}
	
	protected void performDelete() {
		super.run();
	}
}