//------------------------------------------------------------------------------
// 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.diagram.core.commands;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.command.CopyCommand.Helper;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.epf.common.CommonPlugin;
import org.eclipse.epf.diagram.core.DiagramCorePlugin;
import org.eclipse.epf.diagram.core.part.DiagramEditorInput;
import org.eclipse.epf.diagram.core.part.DiagramEditorInputProxy;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.edit.command.DeleteMethodElementCommand;
import org.eclipse.epf.library.edit.command.INestedCommandProvider;
import org.eclipse.epf.library.edit.command.MethodElementAddCommand;
import org.eclipse.epf.library.edit.command.ResourceAwareCompoundCommand;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.command.ActivityDropCommand;
import org.eclipse.epf.library.edit.process.command.CopyHelper;
import org.eclipse.epf.library.edit.process.command.ProcessDeepCopyCommand;
import org.eclipse.epf.library.edit.ui.IActionTypeProvider;
import org.eclipse.epf.library.edit.util.ActivityHandler;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.edit.domain.TraceableAdapterFactoryEditingDomain;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;

/**
 * @author Shilpa Toraskar
 * @author Phong Nguyen Le
 * @since 1.2
 */
public class NestedCommandProvider implements INestedCommandProvider {

	private static final boolean DEBUG = DiagramCorePlugin.getDefault()
			.isDebugging();

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.library.edit.command.INestedCommandProvider#createNestedCommand(org.eclipse.emf.common.command.Command)
	 */
	public Command createNestedCommand(Command command) {
		if (command instanceof ActivityDropCommand) {
			ActivityDropCommand cmd = (ActivityDropCommand) command;
			if (IActionTypeProvider.COPY == cmd.getType())
				return createNestedCommandForCopy(cmd);
			else if (IActionTypeProvider.DEEP_COPY == cmd.getType())
				return createNestedCommandForDeepCopy(cmd);
		}
		else if (command instanceof ProcessDeepCopyCommand) {
			ProcessDeepCopyCommand cmd = (ProcessDeepCopyCommand) command;
			Process deepCopy = null;
			Collection<?> result = cmd.getResult();
			if(!result.isEmpty()) {
				deepCopy = (Process) result.iterator().next();
			}
			if(deepCopy != null) {
				Collection<Activity> deepCopies = new ArrayList<Activity>();
				deepCopies.add(deepCopy);
				return createNestedCommandForDeepCopy(deepCopies, cmd.getTargetProcess(), 
						cmd.getCopyHelper(), cmd.getMethodConfiguration(), true);
			}
		}
		return null;
	}

	/**
	 * Create nested command for Drag & Drop Copy
	 * 
	 * @param command
	 * @return
	 */
	private Command createNestedCommandForCopy(ActivityDropCommand command) {
		Collection<Resource> modifiedResources = ((ActivityDropCommand) command).getModifiedResources(); 
		if (modifiedResources != null && !modifiedResources.isEmpty()) {
			CompoundCommand cmd = new ResourceAwareCompoundCommand(
					CompoundCommand.MERGE_COMMAND_ALL);

			Helper copiedHelper = command.getActivityHandler().getCopyHelper();
			Activity targetActivity = command.getActivity();
			Process targetProc = TngUtil.getOwningProcess(targetActivity);
			if (targetProc != null) {
				try {
					cmd.append(new CopyDiagramCommand(copiedHelper.values(),
							copiedHelper, targetProc));
				
				} catch (Exception ex) {
					CommonPlugin.getDefault().getLogger().logError(ex);
					if (DEBUG) {
						ex.printStackTrace();
					}
				} finally {
	
				}
			}
			if (!cmd.isEmpty()) {
				return cmd;
			}
		}
		return null;
	}
	
	/**
	 * Created nested command for Drag and Drop Deep copy
	 * 
	 * @param command
	 * @return
	 */
	private Command createNestedCommandForDeepCopy(ActivityDropCommand command) {
		ActivityHandler activityHandler = ((ActivityDropCommand) command)
				.getActivityHandler();
		if (activityHandler != null
				&& !activityHandler.getDeepCopies().isEmpty()) {
			return createNestedCommandForDeepCopy(activityHandler
					.getDeepCopies(), activityHandler.getTargetProcess(),
					activityHandler.getDeepCopyHelper(), activityHandler.getDeepCopyConfig(), false);
		}
		return null;
	}
	
	private Command createNestedCommandForDeepCopy(
			Collection<Activity> deepCopies, final Process targetProc,
			CopyHelper copyHelper, MethodConfiguration config,
			boolean saveDiagram) {
		CompoundCommand cmd;
		if (saveDiagram) {
			cmd = new ResourceAwareCompoundCommand(
					CompoundCommand.MERGE_COMMAND_ALL) {
				@Override
				public void execute() {
					super.execute();

					// save diagram file
					//
					if (org.eclipse.epf.diagram.core.services.DiagramManager
							.hasDiagramManager(targetProc)) {
						org.eclipse.epf.diagram.core.services.DiagramManager mgr = org.eclipse.epf.diagram.core.services.DiagramManager
								.getInstance(targetProc, this);
						ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil
								.getPersisterFor(targetProc.eResource())
								.getFailSafePersister();
						try {
							Resource resource = mgr.getResource();
							persister.save(resource);
							persister.commit();
						} catch (Exception e) {
							DiagramCorePlugin.getDefault().getLogger()
									.logError(e);
							try {
								persister.rollback();
							} catch (Exception ex) {
								DiagramCorePlugin.getDefault().getLogger()
										.logError(ex);
							}
						} finally {
							mgr.removeConsumer(this);
						}
					}
				}
			};
		} else {
			cmd = new ResourceAwareCompoundCommand(
					CompoundCommand.MERGE_COMMAND_ALL);
		}
		for (Activity copyAct : deepCopies) {
			Activity origAct = (Activity) copyHelper.getOriginal(copyAct);
			Process srcProc = TngUtil.getOwningProcess(origAct);
			Map<Activity, Activity> copyToOriginalMap = new HashMap<Activity, Activity>();
			Iterator<BreakdownElement> copyTree = new AbstractTreeIterator<BreakdownElement>(
					copyAct) {

				@Override
				protected Iterator<? extends BreakdownElement> getChildren(
						Object object) {
					if (object instanceof Activity) {
						return ((Activity) object).getBreakdownElements()
								.iterator();
					}
					return Collections.EMPTY_LIST.iterator();
				}

			};
			while (copyTree.hasNext()) {
				BreakdownElement e = copyTree.next();
				if (e instanceof Activity) {
					Object orig = copyHelper.getOriginal(e);
					if (orig == null) {
						System.out
								.println("NestedCommandProvider.createNestedCommandForDeepCopy(): FATAL ERROR: could not find source activity of deep copy: " + e); //$NON-NLS-1$
					} else {
						copyToOriginalMap.put((Activity) e, (Activity) orig);
					}
				}
			}
			cmd.append(new CopyDiagramForDeepCopyCommand(copyToOriginalMap.keySet(),
					copyToOriginalMap, srcProc, targetProc, copyHelper, config));
		}
		return !cmd.isEmpty() ? cmd : null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.library.edit.command.INestedCommandProvider#createRelatedObjects(java.util.Collection,
	 *      org.eclipse.emf.common.command.Command)
	 */
	public Command createRelatedObjects(Collection createdElements,
			Command createCommand) {

		CompoundCommand cmd = new ResourceAwareCompoundCommand(
				CompoundCommand.MERGE_COMMAND_ALL);
		if (createCommand instanceof MethodElementAddCommand) {

			MethodElementAddCommand meCommand = ((MethodElementAddCommand) createCommand);
			Command addCommand = meCommand.getCommand();
			if (addCommand instanceof AddCommand) {
				EditingDomain ed = ((AddCommand) addCommand).getDomain();
				
				if (((AddCommand)addCommand).getOwner() instanceof ProcessPackage) {
					if (ed instanceof TraceableAdapterFactoryEditingDomain) {
						Map copyToOriginalMap = ((TraceableAdapterFactoryEditingDomain) ed)
								.getCopyToOriginalMap();
						if (!copyToOriginalMap.isEmpty()) {
							Collection affects = meCommand.getAffectedObjects();
							for (Iterator iter = affects.iterator(); iter
									.hasNext();) {
								MethodElement element = (MethodElement) iter
										.next();
								if (element instanceof ProcessComponent) {
									cmd.append(new CopyDiagramCommand(
											copyToOriginalMap.keySet(),
											copyToOriginalMap,
											((ProcessComponent) element)
													.getProcess()));
								}
							}
						}
					}
				} else {
					// Copy/paste within the process editor
					if (ed instanceof TraceableAdapterFactoryEditingDomain) {
						Map originalToCopyMap = ((TraceableAdapterFactoryEditingDomain) ed)
								.getOriginalToClipboardMap();
						Map copyToOriginalMap = new HashMap();
						Object owner = ((AddCommand) addCommand).getOwner();
						Process targetProc = TngUtil.getOwningProcess(owner);
						if (targetProc != null) {
							for (Iterator iter = originalToCopyMap.keySet()
									.iterator(); iter.hasNext();) {
								Object key = iter.next();
								Object val = originalToCopyMap.get(key);
	
								copyToOriginalMap.put(val, key);
							}
	
							cmd.append(new CopyDiagramCommand(copyToOriginalMap.keySet(),
									copyToOriginalMap, targetProc));
						}
					}
				}
			}
		}
		if (!cmd.isEmpty()) {
			return cmd;
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.library.edit.command.INestedCommandProvider#removeRelatedObjects(java.util.Collection,
	 *      org.eclipse.emf.common.command.Command)
	 */
	public Command removeRelatedObjects(Collection deletedElements,
			Command deleteCommand) {
		CompoundCommand cmd = new ResourceAwareCompoundCommand(
				CompoundCommand.MERGE_COMMAND_ALL);
		if(deleteCommand instanceof DeleteMethodElementCommand){
			Command removeCommand = ((DeleteMethodElementCommand)deleteCommand).getCommand();
			List<RemoveCommand> removeCommands = null;
			if(removeCommand instanceof RemoveCommand){
				removeCommands = Collections.singletonList((RemoveCommand)removeCommand);
			}
			else if(removeCommand instanceof CompoundCommand) {
				removeCommands = new ArrayList<RemoveCommand>();
				for (Command command : ((CompoundCommand)removeCommand).getCommandList()) {
					if(command instanceof RemoveCommand) {
						removeCommands.add((RemoveCommand) command);
					}
				}
			}
			if(removeCommands != null && !removeCommands.isEmpty()) {
				Object owner = removeCommands.get(0).getOwner();
				if(owner instanceof Activity) {
					Process process = TngUtil.getOwningProcess((Activity)owner);
					Collection<Activity> allElements = new HashSet<Activity>();
					for (Iterator iter = deletedElements.iterator(); iter
					.hasNext();) {
						Object element = iter.next();
						if (element instanceof Activity) {
							Iterator iterator = new AbstractTreeIterator<Object>(element) {

								private static final long serialVersionUID = 1L;

								@Override
								protected Iterator<? extends Object> getChildren(
										Object object) {
									if(object instanceof Activity) {
										return ((Activity)object).getBreakdownElements().iterator();
									}
									else {
										return Collections.emptyList().iterator();
									}
								}

							};
							while(iterator.hasNext()) {
								Object e = iterator.next();
								if(e instanceof Activity) {
									allElements.add((Activity) e);
								}
							}
						} 
					}					
					if(!allElements.isEmpty()){
						cmd.append(new DeleteDiagramCommand(allElements, process));
					}

					for (RemoveCommand command : removeCommands) {
						if(command.getOwner() instanceof Activity) {
							DeleteDiagramNodeCommand deleteDiagramNodeCommand = new DeleteDiagramNodeCommand(
									(Activity) command.getOwner(), command.getCollection());
							if(deleteDiagramNodeCommand.canExecute()) {
								cmd.append(deleteDiagramNodeCommand);
							}
						}
					}
				}
			}
		}
		if(!deletedElements.isEmpty()){
			for (Iterator iter = deletedElements.iterator(); iter.hasNext();) {
				Object element = (Object) iter.next();
				if(element instanceof ProcessComponent){
					ProcessComponent pc = (ProcessComponent)element;
					Process process = pc.getProcess();
					closeDiagramEditors(process);
				}
			}
		}
		if(!cmd.isEmpty()){
			return cmd;
		}
		return null;
	}
	
	/**
	 * Closes Diagram Editors if the owning process is deleted.
	 * @param process
	 */
	private void closeDiagramEditors(Process process) {
		IWorkbenchPage workbenchPage = PlatformUI.getWorkbench()
				.getActiveWorkbenchWindow().getActivePage();
		IEditorReference[] editorReferences = workbenchPage
				.getEditorReferences();
		ArrayList<IEditorReference> editorsToClose = new ArrayList<IEditorReference>();
		for (int i = 0; i < editorReferences.length; i++) {
			IEditorReference editorRef = editorReferences[i];
			IEditorInput editorInput;
			try {
				editorInput = editorRef.getEditorInput();
				if (editorInput instanceof DiagramEditorInputProxy) {
					DiagramEditorInput input = ((DiagramEditorInputProxy) editorInput)
							.getDiagramEditorInput();
					Object wrapper = input.getWrapper();
					Object owningProcess = null;
					if (wrapper != null) {
						if (wrapper instanceof BreakdownElementWrapperItemProvider) {
							owningProcess = TngUtil
									.getOwningProcess(((BreakdownElementWrapperItemProvider) wrapper));
						}
					} else {
						wrapper = input.getMethodElement();
						if (wrapper instanceof BreakdownElement) {
							owningProcess = TngUtil
									.getOwningProcess(((BreakdownElement) wrapper));
						}
					}
					if (owningProcess == owningProcess) {
						editorsToClose.add(editorRef);
					}
				}
			} catch (PartInitException e) {
				DiagramCorePlugin.getDefault().getLogger().logError(e);
			}
		}
		if(!editorsToClose.isEmpty()) {
			IEditorReference[] refs = new IEditorReference[editorsToClose.size()];
			editorsToClose.toArray(refs);
			workbenchPage.closeEditors(refs, false);
		}
	}
}
