//------------------------------------------------------------------------------
// 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.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.command.CreateChildCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IUserInteractionHandler;
import org.eclipse.epf.library.edit.command.MethodElementAddCommand;
import org.eclipse.epf.library.edit.command.UserInput;
import org.eclipse.epf.library.edit.navigator.ProcessPackageItemProvider;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.AdapterFactoryItemLabelProvider;
import org.eclipse.epf.library.edit.util.ExtensionManager;
import org.eclipse.epf.library.edit.util.ItemLabelProvider;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.IValidator;
import org.eclipse.epf.library.edit.validation.IValidatorFactory;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.services.Services;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.Element;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessFamily;
import org.eclipse.epf.uma.ProcessPlanningTemplate;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.util.ContentDescriptionFactory;
import org.eclipse.epf.uma.util.MessageException;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.osgi.util.NLS;


/**
 * Executes the Create Process Component command.
 * 
 * @author Phong Nguyen Le
 * @author Kelvin Low
 * @author Shilpa Toraskar
 * @since 1.0
 */
public class CreateProcessComponentCommand extends CreateChildCommand {

	private static final Collection<EClass> ECLASSES = new HashSet<EClass>();

	private Process process;

	private IStatus status;

	static {
		ECLASSES.add(UmaPackage.eINSTANCE.getMethodPackage());
	}

	public static class CompareByName implements Comparator<MethodElement> {

		public int compare(MethodElement obj1, MethodElement obj2) {
			String name1 = ((MethodElement) obj1).getName();
			String name2 = ((MethodElement) obj2).getName();
			return name1.compareToIgnoreCase(name2);
		}
	}

	public class ConfigValidator implements IValidator {

		public IStatus isValid(Object obj) {
			if (obj == null) {
				String msg = LibraryEditResources.noDefaultConfigError_msg;
				return new Status(IStatus.ERROR, LibraryEditPlugin.getDefault()
						.getId(), 0, msg, null);
			}
			return Status.OK_STATUS;
		}

		public String isValid(String name) {
			return null;
		}
	}
	/**
	 * Creates a new instance.
	 */
	public CreateProcessComponentCommand(EditingDomain domain, EObject owner,
			EStructuralFeature feature, Object child, int index,
			Collection<?> selection, Helper helper) {
		super(domain, owner, feature, child, index, selection, helper);
	}

	public boolean canUndo() {
		return false;
	}

	public void execute() {
		MethodLibrary lib = UmaUtil.getMethodLibrary(owner);
		
		Object shell = LibraryEditPlugin.getDefault().getContext();
		
		// The owner must be updatable.
		//
		status = UserInteractionHelper.checkModify(owner, shell);
		if (!status.isOK()) {
			return;
		}

		List configs = lib.getPredefinedConfigurations();
		List methodConfigs = new ArrayList();
		for (Iterator iter = configs.iterator(); iter.hasNext();) {
			Object element = iter.next();
			if (!(element instanceof ProcessFamily)) {
				methodConfigs.add(element);
			}
		}

		if (methodConfigs.isEmpty()) {
			status = new Status(IStatus.ERROR, LibraryEditPlugin.getDefault().getId(),
								0, LibraryEditResources.noConfigError_msg, null);
//			Messenger.INSTANCE.showError(
//					LibraryEditResources.createProcess_text,
//					LibraryEditResources.noConfigError_msg);			
			return;
		}

		ProcessPackageItemProvider adapter = (ProcessPackageItemProvider) helper;

		ArrayList procClasses = new ArrayList();
		if (adapter.getProcessType() == UmaPackage.eINSTANCE
				.getProcessPlanningTemplate()) {
			procClasses.add(DeliveryProcess.class);
			procClasses.add(CapabilityPattern.class);
		}
		MethodPlugin plugin = UmaUtil.getMethodPlugin((Element) owner);		
		List baseProcList = TngUtil.getAvailableBaseProcesses(plugin,
				procClasses);

		// sort by name
		Collections.sort(methodConfigs, new CompareByName());

		MethodConfiguration[] procCtxs = new MethodConfiguration[methodConfigs
				.size()];
		methodConfigs.toArray(procCtxs);

		Process[] baseProcesses = new Process[baseProcList.size()];
		baseProcList.toArray(baseProcesses);

		final ProcessComponent procComp = (ProcessComponent) child;
		EClass procType = adapter.getProcessType();
		procComp.setProcess((Process) UmaFactory.eINSTANCE.create(procType));
		
		IUserInteractionHandler uiHandler = ExtensionManager.getDefaultUserInteractionHandler();
		List userInputs = new ArrayList();
		IValidator nameValidator = IValidatorFactory.INSTANCE.createNameValidator(
				owner, procComp);
		// name
		UserInput nameInput = new UserInput(LibraryEditResources.nameLabel_text, UserInput.TEXT,
				false, null, null, nameValidator, null);
		userInputs.add(nameInput);
		
		// default configuration
		//
		UserInput defaultConfigInput = new UserInput(LibraryEditResources.defaultConfigLabel_text, UserInput.SELECTION,
				false, methodConfigs, new ItemLabelProvider() {
			public String getText(Object element) {
				if (element instanceof MethodElement) {
					return ((MethodElement) element).getName();
				} else {
					return element.toString();
				}
			}
		}, new ConfigValidator(), null);
		userInputs.add(defaultConfigInput);
		// base process
		UserInput baseProcInput = null;
		
		if(procComp.getProcess() instanceof ProcessPlanningTemplate) {
			baseProcInput = new UserInput(LibraryEditResources.basedOnProcessesLabel_text, UserInput.SELECTION,
					true, baseProcList, new AdapterFactoryItemLabelProvider(TngAdapterFactory.INSTANCE
							.getNavigatorView_ComposedAdapterFactory()),  null);
			userInputs.add(baseProcInput);
		}
		
		boolean canExecute = false;
		String msg = NLS.bind(LibraryEditResources.CreateProcessComponentCommand_Message, 
				TngUtil.getTypeText(procType.getName()).toLowerCase());
		
		// request input
		if (uiHandler.requestInput(LibraryEditResources.newProcessComponentDialog_title, 
				msg, userInputs)) {
			String name = (String) nameInput.getInput();
			procComp.setName(name);
			process = procComp.getProcess();
			process.setName(name);
			process.setPresentationName(name);
			process.setDefaultContext((MethodConfiguration) defaultConfigInput.getInput());
			if(baseProcInput != null) {
				List list = (List) baseProcInput.getInput();
				if(!list.isEmpty()) {
					((ProcessPlanningTemplate)procComp).getBasedOnProcesses().addAll(list);
				}
			}
			canExecute = true;
		}

		if (canExecute) {
			// create process component need to update the configuration that
			// has been selected as
			// default context of its process. Check if the configuration file
			// is updatable
			//
			status = UserInteractionHelper.checkModify(procComp.getProcess()
					.getDefaultContext(), shell);
			if (!status.isOK()) {
				return;
			}
			
			super.execute();

			Command cmd = getCommand();
			if (cmd instanceof MethodElementAddCommand) {
				IStatus status = ((MethodElementAddCommand) cmd).getStatus();
				if (status != null && !status.isOK()) {
					this.status = status;
					return;
				}
			}

			final MethodConfiguration procCtx = process.getDefaultContext();
			
			// need to add the parent packages and plugin into the configuration
			// as well
			// New process in new plug-in not automatically visible in
			// configuration view
			List pkgs = procCtx.getMethodPackageSelection();
			for (EObject obj = procComp; obj != null; obj = obj.eContainer()) {
				if (obj instanceof MethodPackage) {
					pkgs.add(obj);
				}
			}
			procCtx.getMethodPluginSelection().add(plugin);
			
			process.getValidContext().add(procCtx);
			process.setPresentation(ContentDescriptionFactory
					.createContentDescription(process));

			Runnable runnable = new Runnable() {
				public void run() {
					// save the resource of parent ProcessPackage
					Resource resource = ((EObject) owner).eResource();
					if (resource != null) {
						ILibraryPersister.FailSafeMethodLibraryPersister persister = Services.getDefaultLibraryPersister()
								.getFailSafePersister();
						try {
							// save the resource of newly created
							// ProcessComponent again after creating process's
							// presentation
							persister.save(procComp.eResource());

							persister.save(resource);

							// save the resource of the process's default
							// context
							persister.save(procCtx.eResource());

							persister.commit();
							
							// create new diagram file
							//
							
						} catch (Exception e) {
							try {
								persister.rollback();
							} catch (Exception ex) {
								LibraryEditPlugin.INSTANCE.log(ex);
								LibraryEditPlugin.INSTANCE.log(e);
							}
							
							status = Status.CANCEL_STATUS;
							throw new MessageException(
									NLS
											.bind(
													LibraryEditResources.saveProcessError_reason,
													procComp.getName()), e);
						}
					}
				}
			};

			UserInteractionHelper
					.runWithProgress(
							runnable,
							MessageFormat
									.format(
											LibraryEditResources.creatingProcessComponentTask_name,
											new Object[] { procComp.getName() })); 
		}
	}

	public void redo() {
		super.redo();
		ProcessComponent procComp = (ProcessComponent) child;
		MethodConfiguration procCtx = process.getDefaultContext();
		if (procCtx instanceof MethodConfiguration) {
			((MethodConfiguration) procCtx).getMethodPackageSelection().add(
					procComp);
		}
	}

	/**
	 * @see org.eclipse.emf.edit.command.CreateChildCommand#undo()
	 */
	public void undo() {
		MethodConfiguration procCtx = process.getDefaultContext();
		if (procCtx instanceof MethodConfiguration) {
			((MethodConfiguration) procCtx).getMethodPackageSelection().remove(
					child);
		}
		super.undo();
	}

	public IStatus getStatus() {
		return status;
	}
}
