//------------------------------------------------------------------------------
// 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.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.epf.common.serviceability.MsgBox;
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.ExtensionManager;
import org.eclipse.epf.library.edit.util.Messenger;
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.jface.viewers.LabelProvider;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Shell;


/**
 * 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 ECLASSES = new HashSet();

	private Process process;

	private IStatus status;

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

	public class CompareByName implements Comparator {

		public int compare(Object obj1, Object 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);
		
		Shell shell = MsgBox.getDefaultShell();
		
		// 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;

		List 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 LabelProvider() {
			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 AdapterFactoryLabelProvider(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;
		}

//		boolean canExecute = true;
//		NewProcessComponentDialog dialog = new NewProcessComponentDialog(
//				Display.getCurrent().getActiveShell(), procCtxs, procComp,
//				baseProcesses, plugin, (ProcessPackage) owner);						
//		while (true) {
//			int ret = dialog.open();
//			if (ret == IDialogConstants.CANCEL_ID) {
//				canExecute = false;
//				break;
//			}
//
//			if (procComp.getProcess().getDefaultContext() == null) {
//				Messenger.INSTANCE.showError(
//						LibraryEditResources.createProcess_text,
//						LibraryEditResources.noDefaultConfigError_msg);
//			} else {
//				String msg = IValidatorFactory.INSTANCE.createNameValidator(
//						owner, procComp).isValid(procComp.getName());
//				if (msg == null) {
//					process = procComp.getProcess();
//					break;
//				} else {
//					Messenger.INSTANCE.showError(
//							LibraryEditResources.createProcess_text,
//							msg);
//				}
//			}
//		}

		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() })); //$NON-NLS-1$
		}
	}

	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;
	}
}
