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

import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.Transaction;
import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain;
import org.eclipse.epf.common.CommonPlugin;
import org.eclipse.epf.diagram.core.DiagramCorePlugin;
import org.eclipse.epf.diagram.core.bridge.BridgeHelper;
import org.eclipse.epf.diagram.core.services.DiagramHelper;
import org.eclipse.epf.diagram.core.services.DiagramManager;
import org.eclipse.epf.diagram.model.NamedNode;
import org.eclipse.epf.diagram.model.NodeContainer;
import org.eclipse.epf.library.edit.command.IResourceAwareCommand;
import org.eclipse.epf.library.edit.util.IDiagramManager;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.uml2.uml.ActivityParameterNode;
import org.eclipse.uml2.uml.StructuredActivityNode;

/**
 * 
 * It does copy the diagram for the activity
 * 
 * @author Shilpa Toraskar
 * @since 1.2
 */
public class CopyDiagramCommand extends AbstractCommand implements
		IResourceAwareCommand {

	private Collection elements;

	private Map copyToOriginalMap;

	private Collection<Diagram> copiedElements;

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

	private Process targetProcess;

	private DiagramManager mgr;
	private InternalTransactionalEditingDomain domain;

	/**
	 * 
	 */
	public CopyDiagramCommand(Collection elements, Map copyToOriginalMap,
			Process targetProcess) {
		this.elements = elements;
		this.copyToOriginalMap = copyToOriginalMap;
		this.targetProcess = targetProcess;

		// get diagram manager and domain
		mgr = DiagramManager.getInstance(targetProcess);
		domain = mgr.getEditingDomain();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.Command#execute()
	 */
	public void execute() {
		redo();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.Command#redo()
	 */
	public void redo() {
		
		if (copiedElements == null) {
			copiedElements = new ArrayList<Diagram>();
		} else {
			copiedElements.clear();
		}

		try {
			for (Iterator iter = elements.iterator(); iter.hasNext();) {
				Object e = (Object) iter.next();
				Object orig = copyToOriginalMap.get(e);
				if (orig != null && orig instanceof Activity && e != null
						&& e instanceof Activity) {
					Activity copyActivity = (Activity) e;
					Activity origActivity = (Activity) orig;

					Collection diagrams = DiagramHelper
							.getDiagrams(origActivity);
					if (diagrams != null && !diagrams.isEmpty()) {
						for (Iterator itor = diagrams.iterator(); itor
								.hasNext();) {
							Diagram diagram = (Diagram) itor.next();
							if (diagram != null) {
								// copy the diagram
								Diagram diagramCopy = (Diagram) DiagramHelper
										.copyDiagram(domain, diagram);

								// update children references
								updateReferences(diagramCopy);

								Transaction tx = domain.startTransaction(false,
										Collections.EMPTY_MAP);

								// associate with the activity
								int diagramType = DiagramHelper
										.getDiagramType(diagramCopy);
								mgr.associate(diagramCopy, diagramType,
										(Activity) copyActivity);

								tx.commit();

								copiedElements.add(diagramCopy);
							}
						}
					}
				}
			}
		} catch (Exception ex) {
			CommonPlugin.getDefault().getLogger().logError(ex);
			if (DEBUG) {
				ex.printStackTrace();
			}
		} finally {
		}
	}

	/**
	 * Update eAnnotations references
	 * 
	 * @param copy
	 */
	public void updateReferences(Diagram copy) {
		int diagramType = DiagramHelper.getDiagramType(copy);
		for (Iterator itor = copy.getChildren().iterator(); itor.hasNext();) {

			Node node = (Node) itor.next();
			EObject obj = node.getElement();

			if (diagramType == IDiagramManager.ACTIVITY_DIAGRAM) {
				if (obj instanceof StructuredActivityNode
						|| obj instanceof ActivityParameterNode) {
					EModelElement modelElement = (EModelElement) obj;
					MethodElement me = BridgeHelper
							.getMethodElementFromAnnotation(modelElement,
									targetProcess.eResource().getResourceSet());

					Object mappedMethodElement = getCopiedElement(
							copyToOriginalMap, me);
					if (mappedMethodElement != null) {
						BridgeHelper.addEAnnotation(modelElement,
								(MethodElement) mappedMethodElement);
					}

				}
			} else if (diagramType == IDiagramManager.ACTIVITY_DETAIL_DIAGRAM) {
				if (obj instanceof NodeContainer) {
					NodeContainer nodeContainer = (NodeContainer) obj;
					// do mapping for nodecontainer
					MethodElement me = nodeContainer.getLinkedElement();
					Object mappedMethodElement = getCopiedElement(
							copyToOriginalMap, me);
					if (mappedMethodElement != null) {
						nodeContainer
								.setLinkedElement((MethodElement) mappedMethodElement);
					}

					// do mapping for its children
					List nodes = nodeContainer.getNodes();

					for (int i = 0; i < nodes.size(); i++) {
						NamedNode namedNode = (NamedNode) nodes.get(i);
						me = namedNode.getLinkedElement();

						mappedMethodElement = getCopiedElement(
								copyToOriginalMap, me);
						if (mappedMethodElement != null) {
							namedNode
									.setLinkedElement((MethodElement) mappedMethodElement);
						}
					}
				}
			} else if (diagramType == IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM) {
				if (obj instanceof NamedNode) {
					NamedNode namedNode = (NamedNode) obj;
					MethodElement me = namedNode.getLinkedElement();

					Object mappedMethodElement = getCopiedElement(
							copyToOriginalMap, me);
					if (mappedMethodElement != null) {
						namedNode
								.setLinkedElement((MethodElement) mappedMethodElement);
					}
				}
			}
		}
	}

	/**
	 * Get copied element from the map
	 * 
	 * @param copiedMap
	 * @param element
	 * @return
	 */
	private Object getCopiedElement(Map copiedMap, Object element) {
		Set keys = copiedMap.keySet();
		for (Iterator itor = keys.iterator(); itor.hasNext();) {
			Object key = itor.next();
			Object value = copiedMap.get(key);
			if (value.equals(element))
				return key;
		}

		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.AbstractCommand#prepare()
	 */
	protected boolean prepare() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.AbstractCommand#undo()
	 */
	public void undo() {
		if (!(copiedElements == null || copiedElements.isEmpty())) {
			try {
				Transaction tx = domain.startTransaction(false,
						Collections.EMPTY_MAP);
				for (Iterator iter = copiedElements.iterator(); iter.hasNext();) {
					Diagram diagram = (Diagram) iter.next();

					mgr.getResource().getContents()
							.remove(diagram.getElement());
					mgr.getResource().getContents().remove(diagram);
				}
				copiedElements.clear();
				tx.commit();
			} catch (Exception ex) {
				CommonPlugin.getDefault().getLogger().logError(ex);
				if (DEBUG) {
					ex.printStackTrace();
				}
			} finally {

			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.library.edit.command.IResourceAwareCommand#getModifiedResources()
	 */
	public Collection getModifiedResources() {
		if (copiedElements == null || copiedElements.isEmpty()) {
			// command is not executed yet
			return Collections.EMPTY_LIST;
		}
		HashSet<Object> modifiedResources = new HashSet<Object>();

		for (Iterator iter = copiedElements.iterator(); iter.hasNext();) {
			Diagram diagram = (Diagram) iter.next();
			if(diagram != null && diagram.eResource() != null)
				modifiedResources.add(diagram.eResource());
		}

		return modifiedResources;
	}
	
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.AbstractCommand#dispose()
	 */
	public void dispose() {
		if (mgr != null)
			mgr.release();

		super.dispose();
	}
}
