//------------------------------------------------------------------------------
// 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.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.DelegatingWrapperItemProvider;
import org.eclipse.emf.edit.provider.IWrapperItemProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.editors.IEditorKeeper;
import org.eclipse.epf.authoring.ui.views.LibraryView;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.edit.FeatureValueWrapperItemProvider;
import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.command.DeleteMethodElementCommand;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.persistence.ILibraryResourceSet;
import org.eclipse.epf.library.ui.actions.MethodElementDeleteAction;
import org.eclipse.epf.library.ui.actions.ProcessDeleteAction;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;

/**
 * Deletes an element in the Library view.
 * 
 * @author Phong Nguyen Le
 * @author Kelvin Low
 * @since 1.0
 */
public class LibraryViewDeleteAction extends MethodElementDeleteAction {
	
	/** 
	 * Delets an element in library view
	 * 
	 */
	public LibraryViewDeleteAction() {
		this(true);
	}
	
	/**
	 * Deletes an element in library view after confirming with user
	 * @param confirm
	 */
	public LibraryViewDeleteAction(boolean confirm) {
		super();
		this.confirm = confirm; 
	}

	/**
	 * @see MethodElementDeleteAction#didDelete(Collection)
	 */
	protected void didDelete(Collection deletedElements) {
		super.didDelete(deletedElements);
		
		// Close all open editors associated with the deleted elements.
		for (Iterator iter = deletedElements.iterator(); iter.hasNext();) {
			Object element = TngUtil.unwrap(iter.next());
			if (element instanceof MethodElement
					&& ((MethodElement) element).eContainer() == null) {
				IEditorKeeper.REFERENCE.getEditorKeeper()
						.closeEditorsOnDeletion((MethodElement) element);
			}
		}
	}
	
	protected static CustomCategory getRootCustomCategory(Object object) {
		for(; object instanceof IWrapperItemProvider; object = ((IWrapperItemProvider)object).getOwner());
		object = TngUtil.unwrap(object);
		return object instanceof CustomCategory && TngUtil.isRootCustomCategory((CustomCategory) object) ?
			(CustomCategory) object : null;
	}

	/**
	 * @see org.eclipse.emf.edit.ui.action.CommandActionHandler#updateSelection(org.eclipse.jface.viewers.IStructuredSelection)
	 */
	public boolean updateSelection(IStructuredSelection selection) {
		ArrayList filteredSelection = new ArrayList();

		for (Iterator iter = selection.iterator(); iter.hasNext();) {
			Object e = iter.next();
			if(e instanceof CustomCategory) {
				filteredSelection.add(e);
				continue;
			}
			Object element = TngUtil.unwrap(e);
			if (element instanceof ItemProviderAdapter
					|| (element instanceof MethodElement && TngUtil
							.isPredefined((MethodElement) element))) {
				continue;
			}
			if (element instanceof CustomCategory) {
				CustomCategory rootCustomCategory = getRootCustomCategory(e);
				CustomCategory cc = (CustomCategory) element;
				if (rootCustomCategory != null && 
						UmaUtil.getMethodPlugin(rootCustomCategory) == UmaUtil.getMethodPlugin(cc)) {
					// selected custome category is in the current plugin.
					// add the element to the selection instead of its
					// wrapper so the element
					// will be deleted permanently from the library
					//
					filteredSelection.add(element);					
				}
			} else {				
				if(e instanceof IWrapperItemProvider) {
					IWrapperItemProvider wrapper = (IWrapperItemProvider) e;
//					if(wrapper.getValue() instanceof IWrapperItemProvider &&
//							!(TngUtil.unwrap(wrapper.getOwner()) instanceof CustomCategory)) {
//						// disallow deleting element when its reference in
//						// CustomCategory tree
//						// that is not directly under a CustomCategory is
//						// selected
//						//
//						continue;
//					}
					
					if (TngUtil.isUnderCustomCategoryTree(wrapper)) {
						// disallow deleting element under a custom category that is not a custom category
						//
						continue;
					}
					else if (wrapper.getFeature() == UmaPackage.Literals.DISCIPLINE_GROUPING__DISCIPLINES 
							|| wrapper.getFeature() == UmaPackage.Literals.ROLE_SET_GROUPING__ROLE_SETS) 
					{
						Object owner = wrapper.getOwner();
						if(owner instanceof EObject && element instanceof EObject && 
								UmaUtil.getMethodPlugin((EObject) owner) == UmaUtil.getMethodPlugin((EObject) element)) {
							// category grouping and category are in the same plugin
							// add the element to the selection instead of its wrapper so the element 
							// will be deleted permanently from the library
							//
							filteredSelection.add(element);
							continue;
						} else {
							continue;
						}
					}
				}
				filteredSelection.add(e);
			}
		}

		if (filteredSelection.isEmpty())
			return false;

		return super
				.updateSelection(new StructuredSelection(filteredSelection));
	}

	/**
	 * @see org.eclipse.epf.library.ui.actions.MethodElementDeleteAction#performDelete()
	 */
	protected void performDelete() {
		HashSet configsToDelete = new HashSet();
		HashSet modifiedResources = new HashSet();
		ILibraryPersister persister = LibraryServiceUtil.getCurrentPersister();
		if (selection != null && selection.size() > 0) {
			for (Iterator iter = selection.iterator(); iter.hasNext();) {
				Object object = TngUtil.unwrap(iter.next());
				if (object instanceof MethodConfiguration) {
					configsToDelete.add(object);
				}
				if (object instanceof EObject && !persister.hasOwnResourceWithoutReferrer(object)) {
					EObject container = ((EObject) object).eContainer();
					if (container != null && container.eResource() != null) {
						modifiedResources.add(container.eResource());
					}
				}
			}
		}

		// Avoid deleting the default configuration of a process.
		if (!configsToDelete.isEmpty()) {
			HashSet configGUIDsToDelete = new HashSet();
			for (Iterator iter = configsToDelete.iterator(); iter.hasNext();) {
				MethodConfiguration config = (MethodConfiguration) iter.next();
				configGUIDsToDelete.add(config.getGuid());
			}
			ILibraryResourceSet resourceSet = (ILibraryResourceSet) LibraryService
					.getInstance().getCurrentMethodLibrary().eResource()
					.getResourceSet();
			resourceSet
					.loadOppositeFeatures(
							Collections
									.singletonList(AssociationHelper.MethodConfiguration_DependentProcesses),
							configGUIDsToDelete);

			for (Iterator iter = configsToDelete.iterator(); iter.hasNext();) {
				MethodConfiguration config = (MethodConfiguration) iter.next();

				List references = AssociationHelper
						.getDependentProcesses(config);
				if (references != null && references.size() > 0) {
					String processName = ((org.eclipse.epf.uma.Process) references
							.get(0)).getName();
					AuthoringUIPlugin
							.getDefault()
							.getMsgDialog()
							.displayWarning(
									AuthoringUIResources.deleteDialog_title, 
									AuthoringUIResources.deleteConfigError_msg, 
									AuthoringUIResources
											.bind(
													AuthoringUIResources.deleteConfigError_reason,
													processName)); 
					return;
				}

			}

		}

		IStatus status = UserInteractionHelper.checkModify(modifiedResources,
				LibraryEditPlugin.getDefault().getContext());
		if (!status.isOK()) {
			AuthoringUIPlugin.getDefault().getMsgDialog().display(
					AuthoringUIResources.deleteDialog_title, 
					status);
			return;
		}

		if (confirmDelete()) {
			// Collect the information of Refreshable Objects
			// ( Reference Objects should be refreshed in navigation tree) -
			ArrayList refreshList = new ArrayList();
			for (Iterator iter = selection.iterator(); iter.hasNext();) {
				Object deletingObject = TngUtil.unwrap(iter.next());
				if (deletingObject instanceof MethodElement) {
					// check for variability
					if (deletingObject instanceof VariabilityElement) {
						for (Iterator iterator = TngUtil
								.getGeneralizers((VariabilityElement) deletingObject); iterator
								.hasNext();) {
							Object aReference = iterator.next();
							refreshList.add(aReference);
						}
					}
					
					IEditorKeeper.REFERENCE.getEditorKeeper().closeEditors(deletingObject, false);
				}
			}

			DeleteMethodElementCommand cmd = (DeleteMethodElementCommand) (command instanceof DeleteMethodElementCommand ? command : null);
			
			// execute actual delete command.
			command.execute();

			// delete the referencing descriptors if there is any
			//
			if(cmd != null) {
				Collection<Descriptor> descriptorsToDelete = cmd.getDescriptorsToDelete();
				if(descriptorsToDelete != null && !descriptorsToDelete.isEmpty()) {
					ProcessDeleteAction.delete(descriptorsToDelete);
				}
			}

			// Refresh the refreshlist objects in navigation tree.
			if (refreshList.size() > 0) {
				TreeViewer viewer = ((TreeViewer) (LibraryView.getView()
						.getViewer()));
				for (Iterator iter = refreshList.iterator(); iter.hasNext();) {
					viewer.refresh(iter.next());
				}
			}			
		}
	}

	/**
	 * Notify propery change with old and new value
	 * 
	 * @param propertyName
	 * 			property name for which value is going to change
	 * @param oldValue
	 * 			Old value of the property
	 * @param newValue
	 * 			New value of the property
	 */
	public void notifyPropertyChange(String propertyName, Object oldValue,
			Object newValue) {
		super.firePropertyChange(propertyName, oldValue, newValue);
	}

	/**
	 * Handle the special case of customcategory Copy/Delete action If parent of
	 * customcategory selected, ignore the customcategory, otherwise compound
	 * command creates a command for parent and a command for child,
	 * CompoundCommand will execute both commands, command for parent will
	 * remove parent itself and removes child too, next it try to execute
	 * command for child, command will fail because child got remove in command
	 * for parent. 
	 * TODO: handle properly in RemoveCommand for this case instead here.
	 */
	public void filterCustomCategorySelection(Object e, List filteredSelection) {
		if (e instanceof FeatureValueWrapperItemProvider) {
			filteredSelection.add(e);
		} else {
			Object owner = ((DelegatingWrapperItemProvider) e).getOwner();
			while (owner instanceof DelegatingWrapperItemProvider) {
				if (owner instanceof FeatureValueWrapperItemProvider) {
					if (!filteredSelection.contains(owner)) {
						filteredSelection.add(e);
					}
					break;
				} else {
					if (filteredSelection.contains(owner))
						break;
					owner = ((DelegatingWrapperItemProvider) owner).getOwner();
					if (!(owner instanceof FeatureValueWrapperItemProvider)) {
						if (!filteredSelection.contains(owner)) {
							filteredSelection.add(e);
							break;
						}
					}
				}
			}
		}
	}

}