//------------------------------------------------------------------------------
//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.diagramming.base.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 java.util.Set;

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.CopyCommand.Helper;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.AdapterFactoryTreeIterator;
import org.eclipse.emf.edit.provider.WrapperItemProvider;
import org.eclipse.epf.common.CommonPlugin;
import org.eclipse.epf.diagram.core.DiagramCorePlugin;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.TngAdapterFactory;
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.command.ActivityDropCommand;
import org.eclipse.epf.library.edit.ui.IActionTypeProvider;
import org.eclipse.epf.library.edit.util.ActivityHandler;
import org.eclipse.epf.library.edit.util.ExposedAdapterFactory;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
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.edit.domain.TraceableAdapterFactoryEditingDomain;

/**
 * @author Shilpa Toraskar
 * @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);
		}
		return null;
	}

	/**
	 * Create nested command for Drag & Drop Copy
	 * 
	 * @param command
	 * @return
	 */
	private Command createNestedCommandForCopy(ActivityDropCommand command) {
		ActivityHandler activityHandler = ((ActivityDropCommand) command)
				.getActivityHandler();
		if (activityHandler != null
				&& !activityHandler.getActivities().isEmpty()) {
			CompoundCommand cmd = new ResourceAwareCompoundCommand(
					CompoundCommand.MERGE_COMMAND_ALL);

			Helper copiedHelper = command.getActivityHandler().getCopyHelper();
			Activity targetActivity = command.getActivity();
			Process targetProc = TngUtil.getOwningProcess(targetActivity);
			Set keys = copiedHelper.keySet();

			try {
				Map copyToOriginalMap = new HashMap();
				for (Iterator iter = keys.iterator(); iter.hasNext();) {
					EObject origAct = (EObject) iter.next();
					EObject copyAct = (EObject) copiedHelper.get(origAct);

					if (origAct instanceof Activity
							&& copyAct instanceof Activity) {
						if (DEBUG) {
							System.out.println("OrigAct:" + origAct);
							System.out.println("CopyAct:" + copyAct);
						}

						copyToOriginalMap.put(copyAct, origAct);
					}

				}

				cmd.append(new CopyDiagramCommand(copyToOriginalMap.keySet(),
						copyToOriginalMap, 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()) {
			CompoundCommand cmd = new ResourceAwareCompoundCommand(
					CompoundCommand.MERGE_COMMAND_ALL);
			ExposedAdapterFactory adapterFactory = (ExposedAdapterFactory) TngAdapterFactory.INSTANCE
					.getProcessComposedAdapterFactory();
			MethodConfiguration config = activityHandler.getDeepCopyConfig();
			Process targetProc = activityHandler.getTargetProcess();
			if (config == null) {
				config = targetProc.getDefaultContext();
			}
			IConfigurator configurator = ((IConfigurator) adapterFactory
					.getFilter());
			MethodConfiguration oldConfig = configurator
					.getMethodConfiguration();
			try {
				configurator.setMethodConfiguration(config);
				int size = activityHandler.getDeepCopies().size();
				for (int i = 0; i < size; i++) {
					Activity copyAct = (Activity) activityHandler
							.getDeepCopies().get(i);
					Activity origAct = (Activity) activityHandler
							.getDeepCopyToOriginalMap().get(copyAct);
					org.eclipse.epf.uma.Process srcProc = TngUtil
							.getOwningProcess(origAct);

					Map copyToOriginalMap = new HashMap();

					final Set deepCopySet = new HashSet(activityHandler
							.getDeepCopies());
					boolean sameProcess = srcProc == targetProc;
					Iterator copyTree = new AdapterFactoryTreeIterator(
							adapterFactory, copyAct);
					Iterator originalTree;
					if (sameProcess) {
						originalTree = new AdapterFactoryTreeIterator(
								adapterFactory, origAct) {

							private static final long serialVersionUID = 1L;

							protected Iterator getChildren(Object o) {
								if (deepCopySet.contains(o)) {
									return Collections.EMPTY_LIST.iterator();
								}
								return super.getChildren(o);
							}
						};
					} else {
						originalTree = new AdapterFactoryTreeIterator(
								adapterFactory, origAct);
					}
					while (copyTree.hasNext()) {
						Object copy = copyTree.next();
						Object orig;
						if (sameProcess) {
							do {
								orig = originalTree.next();
							} while (deepCopySet.contains(orig));
						} else {
							orig = originalTree.next();
						}
						if (copy instanceof WrapperItemProvider)
							copy = TngUtil.unwrap(copy);
						if (orig instanceof WrapperItemProvider)
							orig = TngUtil.unwrap(orig);
						copyToOriginalMap.put(copy, orig);
					}
					cmd.append(new CopyDiagramCommand(copyToOriginalMap
							.keySet(), copyToOriginalMap, targetProc));
				}
			} finally {
				configurator.setMethodConfiguration(oldConfig);
			}
			if (!cmd.isEmpty()) {
				return cmd;
			}
		}
		return 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();
				
				// TODO
				// Add condition check for lib. view copy/paste
//				if (true) {
//					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);
						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) {

		return null;
	}

}
