//------------------------------------------------------------------------------
// 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.uma.edit.domain;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.command.CopyCommand.Helper;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.epf.uma.MethodElement;

/**
 * A traceable adapter factory editing domain used for copying method elements.
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class TraceableAdapterFactoryEditingDomain extends
		AdapterFactoryEditingDomain {

	// Maps copied method elements to their original counterparts.
	// Note: Copied elements are copies of the clipboard copies.
	private HashMap<Object, Object> copyToOriginalMap = null;

	// Maps original elements to their clipboard copies.
	private Map<Object, Object> originalToClipboardMap = null;
	
	private Map<EObject, EObject> clipboardToOriginalMap;

	/**
	 * Creates a new instance.
	 * 
	 * @param adapterFactory
	 *            an adapter factory used to create the adapter to which calls
	 *            are delegated
	 * @param commandStack
	 *            a command stack
	 */
	public TraceableAdapterFactoryEditingDomain(AdapterFactory adapterFactory,
			CommandStack commandStack) {
		super(adapterFactory, commandStack);
	}

	/**
	 * Creates a new instance.
	 * 
	 * @param adapterFactory
	 *            an adapter factory used to create the adapter to which calls
	 *            are delegated
	 * @param commandStack
	 *            a command stack
	 * @param resourceToReadOnlyMap
	 *            controls whether the domain is read only
	 */
	public TraceableAdapterFactoryEditingDomain(AdapterFactory adapterFactory,
			CommandStack commandStack, Map resourceToReadOnlyMap) {
		super(adapterFactory, commandStack, resourceToReadOnlyMap);
	}

	/**
	 * Creates a new instance.
	 * 
	 * @param adapterFactory
	 *            an adapter factory used to create the adapter to which calls
	 *            are delegated
	 * @param commandStack
	 *            a command stack
	 * @param resourceSet
	 *            a resource set
	 */
	public TraceableAdapterFactoryEditingDomain(AdapterFactory adapterFactory,
			CommandStack commandStack, ResourceSet resourceSet) {
		super(adapterFactory, commandStack, resourceSet);
	}

	/**
	 * Returns a map containing the copied elements mapped to their original
	 * counterparts.
	 * 
	 * @return a map containing the copied elements mapped to their original
	 *         counterparts
	 */
	public Map<?, ?> getCopyToOriginalMap() {
		if (copyToOriginalMap == null) {
			copyToOriginalMap = new HashMap<Object, Object>();
		}
		return copyToOriginalMap;
	}
	
	
	/**
	 * Returns a map containing the original elements mapped to their copied 
	 * counterparts on clipboard
	 * 
	 * @return a map containing the original elements mapped to their copied 
	 *         counterparts
	 */
	public Map getOriginalToClipboardMap() {
		if (originalToClipboardMap == null) {
			originalToClipboardMap = new HashMap();
		}
		return originalToClipboardMap;
	}

	/**
	 * Used by the CreateCopyCommand. Adds infomation to construct maps that
	 * keep track of the original method elements and their copies.
	 * 
	 * @param c
	 *            a collection to store the mapping info
	 * @param copyHelper
	 *            a helper class that is used to keep track of copied objects
	 *            and their associated copies
	 */
	public void addCopyInfo(Collection c, Helper copyHelper) {
		if (isNewCopy(c, copyHelper)) {
			addNewCopy(c, copyHelper);
			return;
		} else {
			chainCopy(c, copyHelper);
			return;
		}
	}

	/**
	 * Adds a new element that is being copied to the clipboard.
	 */
	private void addNewCopy(Collection c, Helper copyHelper) {
		// this means we are copying the Collection c to the clipboard
		if (originalToClipboardMap == null)
			originalToClipboardMap = new HashMap();
		if(clipboardToOriginalMap == null) {
			clipboardToOriginalMap = new HashMap<EObject, EObject>();
		}
		Iterator iter = copyHelper.keySet().iterator();
		while (iter.hasNext()) {
			EObject key = (EObject) iter.next();
			EObject value = (EObject) copyHelper.get(key);
			originalToClipboardMap.put(key, value);
			clipboardToOriginalMap.put(value, key);
		}
	}

	/**
	 * Creates a map from the copied elements to their original counterparts.
	 */
	private void chainCopy(Collection c, Helper copyHelper) {
		// chain the maps - change the copyToOriginalMap
		if (originalToClipboardMap != null) {
			if (copyToOriginalMap == null)
				copyToOriginalMap = new HashMap();
			Iterator iter = originalToClipboardMap.keySet().iterator();
			while (iter.hasNext()) {
				Object o2CKey = iter.next();
				Object o2CValue = originalToClipboardMap.get(o2CKey);
				Object copyValue = copyHelper.get(o2CValue);
				if (copyValue == null) {
					// error
					continue;
				}
				if (o2CKey instanceof MethodElement)
					copyToOriginalMap.put(copyValue, o2CKey);
			}
		}
	}

	private boolean isNewCopy(Collection c, Helper copyHelper) {
		// originalToClipboardMap was set to null at start of copy command
		if (originalToClipboardMap == null)
			return true;

		// iterate through copyHelper map, see if any copyHelper keys are o2C
		// values, which means we are copying clipboard
		Iterator iter = copyHelper.keySet().iterator();
		while (iter.hasNext()) {
			Object clipKey = iter.next();
			if (!originalToClipboardMap.containsValue(clipKey))
				return true;
		}

		return false;
	}

	/**
	 * Initializes the copy maps. It should be called within the copy action.
	 */
	public void resetCopyMaps() {
		if (originalToClipboardMap != null) {
			originalToClipboardMap.clear();
			originalToClipboardMap = null;
		}
		if(clipboardToOriginalMap != null) {
			clipboardToOriginalMap.clear();
			clipboardToOriginalMap = null;
		}
		if (copyToOriginalMap != null) {
			copyToOriginalMap.clear();
			copyToOriginalMap = null;
		}
	}

	public Map<EObject, EObject> getClipboardToOriginalMap() {
		return clipboardToOriginalMap;
	}
}
