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

import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.validation.UniqueNamePNameHandler;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.TeamProfile;
import org.eclipse.epf.uma.WorkProductDescriptor;


/**
 * Command to drap and drop tasks onto an activity in work breakdown structure
 * 
 * @author Phong Nguyen Le
 * @author Shilpa Toraskar
 * @author Jinhua Xi
 * @since 1.0
 */
public class WBSDropCommand extends BSDropCommand {
	private ArrayList roleDescList;

	private ArrayList wpDescList;

	private HashMap wpDescToDeliverableParts;

	private HashMap wpdToDeliverableDescriptorMap;

	private HashMap roleDescTeamProfileMap;
	
	private IExecutor executor;

	private class Executor implements IExecutor {

		public boolean preExecute() {
			taskDescList = new ArrayList();
			roleDescList = new ArrayList();
			wpDescList = new ArrayList();
			wpDescToDeliverableParts = new HashMap();
			wpdToDeliverableDescriptorMap = new HashMap();
			Set descriptorsToRefresh = synchronize ? batchCommand.getDescriptorsToRefresh() : null;

			List bes = activity.getBreakdownElements();
			UniqueNamePNameHandler uniqueNamesHandler = new UniqueNamePNameHandler(bes, bes);
			
			for (int i = 0; i < dropElements.size(); i++) {
				Task task = (Task) dropElements.get(i);
				TaskDescriptor desc = ProcessCommandUtil.createTaskDescriptor(task,
						activity, roleDescList, wpDescList,
						wpDescToDeliverableParts,
						wpdToDeliverableDescriptorMap, descriptorsToRefresh,
						batchCommand.getObjectToNewFeatureValuesMap(), 
						WBSDropCommand.this.getMethodConfiguration(),
						synchronize,
						synchFeatures);
				if (desc != null) {
					uniqueNamesHandler.ensureUnique(desc);
					taskDescList.add(desc);
				}
			}

			// Add unique name check for roledesc and wp descriptors as well
			for (int i = 0; i < roleDescList.size(); i++) {
				RoleDescriptor roleDesc = (RoleDescriptor) roleDescList.get(i);			
				if (roleDesc != null) {
					uniqueNamesHandler.ensureUnique(roleDesc);	
				}
			}
			for (int i = 0; i < wpDescList.size(); i++) {
				WorkProductDescriptor wpDesc = (WorkProductDescriptor) wpDescList.get(i);			
				if (wpDesc != null) {
					uniqueNamesHandler.ensureUnique(wpDesc);	
				}
			}
			return !taskDescList.isEmpty()
					|| !roleDescList.isEmpty()
					|| !wpDescList.isEmpty()
					|| !wpDescToDeliverableParts.isEmpty()
					|| !wpdToDeliverableDescriptorMap.isEmpty()
					|| batchCommand.canExecute();
		}

		public void doExcecute() {
			// automatically add work product descriptor to deliverable part
			//
			if (!wpdToDeliverableDescriptorMap.isEmpty()) {
				for (Iterator iter = wpdToDeliverableDescriptorMap.entrySet()
						.iterator(); iter.hasNext();) {
					Map.Entry entry = (Map.Entry) iter.next();
					WorkProductDescriptor deliverable = (WorkProductDescriptor) entry
							.getValue();
					if (!deliverable.getDeliverableParts().contains(
							entry.getKey())) {
						try {
							deliverable.getDeliverableParts().add(
									entry.getKey());
						} catch (Exception e) {
							LibraryEditPlugin.INSTANCE
									.log("WBSDropCommand::doExecute - Adding deliverable part to deliverable" + e); //$NON-NLS-1$
						}
					}
				}
			}

			// add task descriptors
			//
			activity.getBreakdownElements().addAll(taskDescList);

			// add role descriptors
			//
			activity.getBreakdownElements().addAll(roleDescList);

			// add work product descriptors
			//
			activity.getBreakdownElements().addAll(wpDescList);

			// add deliverable parts to the work product descriptors
			//
			if (!wpDescToDeliverableParts.isEmpty()) {
				for (Iterator iter = wpDescToDeliverableParts.entrySet()
						.iterator(); iter.hasNext();) {
					Map.Entry entry = (Map.Entry) iter.next();
					WorkProductDescriptor wpDesc = (WorkProductDescriptor) entry
							.getKey();
					wpDesc.getDeliverableParts().addAll(
							(Collection) entry.getValue());
				}
			}

			if(roleDescTeamProfileMap == null) {
				roleDescTeamProfileMap = new HashMap();
				for (Iterator iter = roleDescList.iterator(); iter.hasNext();) {
					RoleDescriptor roleDesc = (RoleDescriptor) iter.next();
					TeamProfile teamProfile = UserInteractionHelper.getTeam(
							activity, roleDesc.getRole());
					if (teamProfile != null) {
						roleDescTeamProfileMap.put(roleDesc, teamProfile);
					}
				}
			}
			// add role descriptors to team profiles
			//
			for (Iterator iter = roleDescTeamProfileMap.entrySet().iterator(); iter
					.hasNext();) {
				Map.Entry entry = (Map.Entry) iter.next();
				TeamProfile team = (TeamProfile) entry.getValue();
				team.getTeamRoles().add(entry.getKey());
			}

			// add new descriptors to activity's package
			//
			ProcessPackage pkg = (ProcessPackage) activity.eContainer();
			if (pkg != null) {
				pkg.getProcessElements().addAll(taskDescList);
				pkg.getProcessElements().addAll(roleDescList);
				pkg.getProcessElements().addAll(wpDescList);
			}
			
		}

		public void doUndo() {
			
			// remove work product descriptors
			//
			activity.getBreakdownElements().removeAll(wpDescList);

			// remove role descriptors
			//
			activity.getBreakdownElements().removeAll(roleDescList);

			// remove task descriptors
			//
			activity.getBreakdownElements().removeAll(taskDescList);

			// remove deliverable parts to the work product descriptors
			//
			if (!wpDescToDeliverableParts.isEmpty()) {
				for (Iterator iter = wpDescToDeliverableParts.entrySet()
						.iterator(); iter.hasNext();) {
					Map.Entry entry = (Map.Entry) iter.next();
					WorkProductDescriptor wpDesc = (WorkProductDescriptor) entry
							.getKey();
					wpDesc.getDeliverableParts().removeAll(
							(Collection) entry.getValue());
				}
			}

			// remove work product descriptor from deliverable part
			//
			if (!wpdToDeliverableDescriptorMap.isEmpty()) {
				for (Iterator iter = wpdToDeliverableDescriptorMap.entrySet()
						.iterator(); iter.hasNext();) {
					Map.Entry entry = (Map.Entry) iter.next();
					WorkProductDescriptor deliverable = (WorkProductDescriptor) entry
							.getValue();
					deliverable.getDeliverableParts().remove(entry.getKey());
				}
			}

			// remove role descriptors from team profiles
			//
			for (Iterator iter = roleDescTeamProfileMap.entrySet().iterator(); iter
					.hasNext();) {
				Map.Entry entry = (Map.Entry) iter.next();
				TeamProfile team = (TeamProfile) entry.getValue();
				team.getTeamRoles().remove(entry.getKey());
			}

			// remove descriptors from activity's package
			//
			ProcessPackage pkg = (ProcessPackage) activity.eContainer();
			if (pkg != null) {
				pkg.getProcessElements().removeAll(taskDescList);
				pkg.getProcessElements().removeAll(roleDescList);
				pkg.getProcessElements().removeAll(wpDescList);
			}
		}

	};

	/**
	 * @param act
	 *            the activity that the given tasks are dropped on
	 * @param tasks
	 *            the tasks to drop on the given activity
	 */
	public WBSDropCommand(Activity act, List tasks) {
		super(act, tasks);
		for (Iterator iter = dropElements.iterator(); iter.hasNext();) {
			Object element = iter.next();
			if (!(element instanceof Task)) {
				iter.remove();
			}
		}
	}

	/**
	 * @param activity
	 * @param dropElements
	 * @param synch
	 */
	public WBSDropCommand(Activity activity, List dropElements, boolean synch) {
		super(activity, dropElements, synch);
	}

	/**
	 * @param activity
	 * @param dropElements
	 * @param config
	 * @param synchFeatures
	 */
	public WBSDropCommand(Activity activity, List dropElements,
			MethodConfiguration config, Set synchFeatures) {
		super(activity, dropElements, config, synchFeatures);
	}

	public IExecutor getExecutor() {
		if (executor == null) {
			executor = new Executor();
		}
		return executor;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.command.BSDropCommand#preExecute()
	 */
	protected boolean preExecute() {
		if (!super.preExecute())
			return false;

		return getExecutor().preExecute();
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.command.BSDropCommand#doExecute()
	 */
	protected void doExecute() {
		executor.doExcecute();
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.AbstractCommand#getAffectedObjects()
	 */
	public Collection getAffectedObjects() {
		if (taskDescList != null) {
			return taskDescList;
		}

		return super.getAffectedObjects();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.command.BSDropCommand#doUndo()
	 */
	protected void doUndo() {
		executor.doUndo();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.process.command.BSDropCommand#dispose()
	 */
	public void dispose() {
		if (roleDescList != null) {
			roleDescList.clear();
		}
		if (roleDescTeamProfileMap != null) {
			roleDescTeamProfileMap.clear();
		}
		if (wpDescList != null) {
			wpDescList.clear();
		}
		if (wpDescToDeliverableParts != null) {
			wpDescToDeliverableParts.clear();
		}
		if (wpdToDeliverableDescriptorMap != null) {
			wpdToDeliverableDescriptorMap.clear();
		}

		super.dispose();
	}
}
