//------------------------------------------------------------------------------
// 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.library.edit.process.command;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.command.IdentityCommand;
import org.eclipse.emf.common.command.UnexecutableCommand;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.command.DragAndDropCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.epf.library.edit.command.IResourceAwareCommand;
import org.eclipse.epf.library.edit.command.ResourceAwareCompoundCommand;
import org.eclipse.epf.library.edit.util.ExposedAdapterFactory;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.DependencyChecker;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.Viewer;


/**
 * Abstract drag and drop command for process authoring
 * 
 * @author Phong Nguyen Le
 * @author Shilpa Toraskar
 * @since 1.0
 */
public abstract class BSDragAndDropCommand extends DragAndDropCommand implements
		IResourceAwareCommand {

	/**
	 * @param domain
	 * @param owner
	 * @param location
	 * @param operations
	 * @param operation
	 * @param collection
	 */
	public BSDragAndDropCommand(EditingDomain domain, Object owner,
			float location, int operations, int operation, Collection collection) {
		super(domain, owner, location, operations, operation, collection);
	}

	protected boolean prepareDropCopyOn() {
		return prepareDropLinkOn();
	}

	protected boolean prepareDropLinkOn() {
		dragCommand = IdentityCommand.INSTANCE;
		dropCommand = UnexecutableCommand.INSTANCE;

		ArrayList list = new ArrayList();
		ArrayList actList = new ArrayList();
		for (Iterator iter = collection.iterator(); iter.hasNext();) {
			Object obj = iter.next();
			obj = TngUtil.unwrap(obj);
			if (TngUtil.isLocked((EObject) owner))
				return false;
			if (accept(obj)) {
				list.add(obj);
			}
			// else if(obj instanceof Process) {
			// // disallow drop a process as an activity
			// }
			else if (obj instanceof Activity && owner instanceof Activity) {
				Activity target = (Activity) owner;
				if (DependencyChecker.newCheckAct) {
					if (! DependencyChecker.checkCircularForMovingVariabilityElement
							(target, Collections.singletonList(obj), true)) {
						return false;
					}					
				} else if (!DependencyChecker.checkCircularDependency((Activity) obj, target).isOK()){
					return false;
				}
				
//				Process srcProc = TngUtil.getOwningProcess((BreakdownElement) obj);
//				Process targetProc = TngUtil.getOwningProcess(target);
//
//				if (!(srcProc instanceof DeliveryProcess && targetProc instanceof CapabilityPattern)) {
//					actList.add(obj);
//				}
				
				// no more check to prevent applying an activity of a delivery process onto a capability patter
				// since introduction of deep-copy. Deep copy can always be applied regardless of source and target
				// processes.
				//
				actList.add(obj);
			}
		}

		boolean result;
		if (list.isEmpty() && actList.isEmpty()) {
			result = false;
		} else {
			CompoundCommand cmd = new ResourceAwareCompoundCommand();
			if (!list.isEmpty()) {
				cmd.append(createDropCommand(owner, list));
			}
			if (!actList.isEmpty()) {
				if (owner instanceof Activity)
					cmd.append(new ActivityDropCommand((Activity) owner, actList,
						getTargetViewer(), ((AdapterFactoryEditingDomain)domain).getAdapterFactory()));
			}
			dropCommand = cmd;
			result = dropCommand.canExecute();
		}
		return result;
	}

	private Viewer getTargetViewer() {
		if (domain instanceof AdapterFactoryEditingDomain) {
			Process proc = TngUtil.getOwningProcess((BreakdownElement) owner);
			AdapterFactory adapterFactory = ((AdapterFactoryEditingDomain) domain)
					.getAdapterFactory();
			if (adapterFactory instanceof ExposedAdapterFactory) {
				for (Iterator iter = Collections.unmodifiableList(
						((ExposedAdapterFactory) adapterFactory)
								.getChangeListeners()).iterator(); iter
						.hasNext();) {
					Object listener = iter.next();
					if (listener instanceof IContentProvider && listener instanceof IViewerProvider) {					
						Viewer viewer = ((IViewerProvider) listener).getViewer();
						if (viewer.getInput() instanceof ProcessComponent
								&& ((ProcessComponent) viewer.getInput())
										.getProcess() == proc)
							return viewer;
					}
				}
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.command.IResourceAwareCommand#getModifiedResources()
	 */
	public Collection getModifiedResources() {
		if (dropCommand instanceof IResourceAwareCommand) {
			return ((IResourceAwareCommand) dropCommand).getModifiedResources();
		}
		return Collections.EMPTY_LIST;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.edit.command.DragAndDropCommand#getAffectedObjects()
	 */
	public Collection getAffectedObjects() {
		return dropCommand.getAffectedObjects();		
	}

	protected abstract boolean accept(Object obj);

	protected abstract Command createDropCommand(Object owner, List dropSrc);

}
