/*******************************************************************************
 * Copyright (c) 2003, 2005 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 API and implementation
 *******************************************************************************/
package org.eclipse.wst.common.internal.emfworkbench.integration;

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

import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
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.AddCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.wst.common.internal.emf.utilities.ExtendedEcoreUtil;

/**
 * Insert the type's description here. Creation date: (4/6/2001 3:40:35 PM)
 * 
 * @author: Administrator
 */
public class ModelModifier {
	private static final String SET_PATTERN = "Set {0}"; //$NON-NLS-1$
	private static final String ADD_PATTERN = "Add {0}"; //$NON-NLS-1$
	private static final String REMOVE_PATTERN = "Remove {0}"; //$NON-NLS-1$
	private static final String DEFAULT_COMMAND_LABEL = "Command"; //$NON-NLS-1$
	private EditingDomain editingDomain;
	private List helpers;
	private List extendedHelpers;
	protected List additionalCommands;
	protected int status;
	public static final int NO_VALUE_CHANGE = 0;
	public static final int VALUE_CHANGE = 1;
	public static final int ERROR = 2;

	/**
	 * J2EEModelModifier constructor comment.
	 */
	public ModelModifier() {
		super();
	}

	/**
	 * J2EEModelModifier constructor comment.
	 * 
	 * @param aDomain
	 *            EditingDomain
	 */
	public ModelModifier(EditingDomain aDomain) {
		setEditingDomain(aDomain);
	}

	/**
	 * Add
	 * 
	 * @aHelper to the list of helper that will be executed.
	 */
	public void addHelper(ModifierHelper aHelper) {
		if (aHelper != null && !getHelpers().contains(aHelper))
			getHelpers().add(aHelper);
	}

	public void addAdditionalCommand(Command aCommand) {
		if (aCommand != null && !getAdditionalCommands().contains(aCommand))
			additionalCommands.add(aCommand);
	}

	/**
	 * Return true if this modifier can create a command that will perform the necessary operation.
	 */
	public boolean canExecuteCommand() {
		return getEditingDomain() != null;
	}

	public int executeWithStatus() {
		try {
			execute();
			return status;
		} finally {
			status = -1;
		}
	}

	/**
	 * Execute this modifier using the recording mechanism of the StructedTextUndoManager. If this
	 * modifier cannot record, try to execute using the CommandStack (if it can execute commands).
	 * Return true if the execution was attempted.
	 * 
	 * @see canExecuteCommand()
	 * @see canRecord()
	 * @see run()
	 */
	public boolean execute(ModifierHelper aHelper) {
		addHelper(aHelper);
		return execute();
	}

	/**
	 * Execute this modifier using the recording mechanism of the StructedTextUndoManager. If this
	 * modifier cannot record, try to execute using the CommandStack (if it can execute commands).
	 * Return true if the execution was attempted.
	 * 
	 * @see canExecuteCommand()
	 * @see canRecord()
	 * @see run()
	 */
	public boolean execute(List someHelpers) {
		setHelpers(someHelpers);
		return execute();
	}

	/**
	 * Execute this modifier by creating a Command that is executed on the CommandStack. If this
	 * modifier cannot execute commands, the execution will not take place. Return true if the
	 * execution was attempted.
	 * 
	 * @see canExecuteCommand()
	 */
	public boolean execute() {
		boolean result = false;
		if (canExecuteCommand()) {
			try {
				Command command = createCommand();
				result = command != null;
				if (result) {
					getCommandStack().execute(command);
				}
			} finally {
				release();
			}
		} else {
			setStatus(ERROR);
		}
		return result;
	}

	protected CommandStack getCommandStack() {
		if (getEditingDomain() != null)
			return getEditingDomain().getCommandStack();
		return null;
	}

	/**
	 * Insert the method's description here. Creation date: (4/6/2001 2:53:17 PM)
	 * 
	 * @return EditingDomain
	 */
	public EditingDomain getEditingDomain() {
		return editingDomain;
	}

	/**
	 * Insert the method's description here. Creation date: (4/10/2001 8:46:35 AM)
	 * 
	 * @return J2EEModifierHelper
	 */
	public ModifierHelper getFirstHelper() {
		if (helpers != null && getHelpers().size() > 0)
			return (ModifierHelper) getHelpers().get(0);
		return null;
	}

	/**
	 * Insert the method's description here. Creation date: (4/10/2001 8:46:35 AM)
	 * 
	 * @return java.util.List
	 */
	public java.util.List getHelpers() {
		if (helpers == null)
			helpers = new ArrayList();
		return helpers;
	}

	public java.util.List getAdditionalCommands() {
		if (additionalCommands == null)
			additionalCommands = new ArrayList();
		return additionalCommands;
	}

	/**
	 * Release all model artifacts.
	 */
	protected void release() {
		setEditingDomain(null);
		setHelpers(null);
	}

	/**
	 * Insert the method's description here. Creation date: (4/6/2001 2:53:17 PM)
	 * 
	 * @param newEditingDomain
	 *            EditingDomain
	 */
	public void setEditingDomain(EditingDomain newEditingDomain) {
		editingDomain = newEditingDomain;
	}

	/**
	 * Insert the method's description here. Creation date: (4/10/2001 8:46:35 AM)
	 * 
	 * @param newHelpers
	 *            java.util.List
	 */
	public void setHelpers(java.util.List newHelpers) {
		helpers = newHelpers;
	}

	protected void setStatus(int statusCode) {
		if (statusCode > status)
			status = statusCode;
	}

	/**
	 * Return an AddCommand that will be executed by a CommandStack.
	 */
	protected Command createAddCommand(ModifierHelper aHelper) {
		Object value = getValue(aHelper);
		Command command = null;
		if (valueChanged(aHelper.getOwner(), aHelper.getFeature(), value, false)) {
			command = AddCommand.create(getEditingDomain(), aHelper.getOwner(), aHelper.getFeature(), value);
			((AbstractCommand) command).setLabel(createCommandLabel(ADD_PATTERN, aHelper.getFeature()));
			setStatus(VALUE_CHANGE);
		} else {
			setStatus(NO_VALUE_CHANGE);
		}
		return command;
	}

	/**
	 * Return a Command that will be executed by a CommandStack. The default is to return null.
	 * Subclasses should override this method.
	 */
	public Command createCommand() {
		Command chainedCommand = createCommand(null, getHelpers());
		if (null == chainedCommand && additionalCommands != null && additionalCommands.isEmpty()) {
			setStatus(ERROR);
			return null;
		}
		chainedCommand = appendAdditionalCommands(chainedCommand);
		return chainedCommand;
	}

	protected Command createCommand(Command chainedCommand, List helpersArg) {
		Command innerChainedCommand = chainedCommand;
		if (null == extendedHelpers) {
			extendedHelpers = new ArrayList();
		}

		if (!helpersArg.isEmpty()) {
			Iterator it = helpersArg.iterator();
			Command nextCommand = null;
			while (it.hasNext()) {
				nextCommand = createCommand((ModifierHelper) it.next());
				if (innerChainedCommand == null)
					innerChainedCommand = nextCommand;
				else if (nextCommand != null)
					innerChainedCommand = innerChainedCommand.chain(nextCommand);
			}
		}
		if (!extendedHelpers.isEmpty()) {
			List copy = new ArrayList();
			copy.addAll(extendedHelpers);
			extendedHelpers.clear();
			innerChainedCommand = createCommand(innerChainedCommand, copy);
		}
		return innerChainedCommand;
	}

	protected Command appendAdditionalCommands(Command chainedCommand) {
		Command innerChainedCommand = chainedCommand;
		if (additionalCommands != null && !additionalCommands.isEmpty()) {
			Command command;
			for (int i = 0; i < additionalCommands.size(); i++) {
				command = (Command) additionalCommands.get(i);
				if (innerChainedCommand == null)
					innerChainedCommand = command;
				else
					innerChainedCommand = innerChainedCommand.chain(command);
			}
		}
		return innerChainedCommand;
	}

	/**
	 * Return a Command that will be executed by a CommandStack.
	 */
	protected Command createCommand(ModifierHelper aHelper) {
		if (aHelper == null)
			return null;
		Command command1, command2;
		ModifierHelper ownerHelper = aHelper.getOwnerHelper();
		if (aHelper.shouldUnsetValue() && ownerHelper != null)
			return null; //we are unsetting a value on an owner that does not exist so do not
		// create the owner
		command1 = createCommand(ownerHelper);
		command2 = primCreateCommand(aHelper);

		if (command1 != null) {
			if (command2 == null)
				command2 = command1;
			else
				command2 = command2.chain(command1);
		}
		return command2;
	}

	protected String createCommandLabel(String aPattern, EStructuralFeature feature) {
		String replacement = feature == null ? DEFAULT_COMMAND_LABEL : feature.getName();
		return java.text.MessageFormat.format(aPattern, new Object[]{replacement});
	}

	/**
	 * Return a Command that will be executed by a CommandStack. The default is to return null.
	 * Subclasses should override this method.
	 */
	protected Command createManyCommand(ModifierHelper aHelper) {
		if (aHelper.shouldUnsetValue())
			return createRemoveCommand(aHelper);
		return createAddCommand(aHelper);
	}

	protected EObject createObjectFromHelper(ModifierHelper aHelper) {
		return aHelper.createNewObjectFromFeature();
	}

	
	/**
	 * Used to remove an object on unset.  Makes the object a proxy  
	 * on execute and redo commands.  Undo will remove the proxy.
	 */
	public class ProxyWrappingCommand extends AbstractCommand {
		protected Command baseCommand = null;
		protected EObject eObject = null;
		protected Resource resource = null;

		public ProxyWrappingCommand(Command baseCommand, EObject eObject) {
			this.baseCommand = baseCommand;
			this.eObject = eObject;
			this.resource = eObject.eResource();
		}

		@Override
		public boolean canExecute() {
			return baseCommand.canExecute();
		}

		public void execute() {
			ExtendedEcoreUtil.becomeProxy(eObject, resource);
			baseCommand.execute();
		}

		@Override
		public boolean canUndo() {
			return baseCommand.canUndo();
		}

		@Override
		public void undo() {
			baseCommand.undo();
			ExtendedEcoreUtil.removeProxy(eObject, resource);
		}

		public void redo() {
			ExtendedEcoreUtil.becomeProxy(eObject, resource);
			baseCommand.redo();
		}

		@Override
		public Collection getResult() {
			return baseCommand.getResult();
		}

		@Override
		public Collection getAffectedObjects() {
			return baseCommand.getAffectedObjects();
		}

		@Override
		public String getLabel() {
			return baseCommand.getLabel();
		}

		@Override
		public String getDescription() {
			return baseCommand.getDescription();
		}

		@Override
		public void dispose() {
			super.dispose();
			baseCommand.dispose();
		}
	}

	/**
	 * Return a Remove Command that will be executed by a CommandStack.
	 */
	protected Command createRemoveCommand(ModifierHelper aHelper) {
		Object value = getValue(aHelper);
		Command command = null;
		EStructuralFeature feature = aHelper.getFeature();
		if (valueChanged(aHelper.getOwner(), feature, value, true)) {
			if (isValueEqual(aHelper, value)) {
				command = RemoveCommand.create(getEditingDomain(), aHelper.getOwner(), feature, (Collection) value);
			} else {
				command = RemoveCommand.create(getEditingDomain(), aHelper.getOwner(), feature, value);
			}
			((AbstractCommand) command).setLabel(createCommandLabel(REMOVE_PATTERN, feature));
			setStatus(VALUE_CHANGE);
		} else {
			setStatus(NO_VALUE_CHANGE);
		}
		return command;
	}

	private boolean isValueEqual(ModifierHelper aHelper, Object value) {
		return aHelper.getOwner().eGet(aHelper.getFeature()) == value;
	}

	/**
	 * Return a SetCommand that will be executed by a CommandStack.
	 */
	protected Command createSingleCommand(ModifierHelper aHelper) {
		Object value = getValue(aHelper);
		Command command = null;
		if (valueChanged(aHelper.getOwner(), aHelper.getFeature(), value, aHelper.shouldUnsetValue())) {
			command = SetCommand.create(getEditingDomain(), aHelper.getOwner(), aHelper.getFeature(), value);
			((AbstractCommand) command).setLabel(createCommandLabel(SET_PATTERN, aHelper.getFeature()));
			setStatus(VALUE_CHANGE);
		} else {
			setStatus(NO_VALUE_CHANGE);
		}
		return command;
	}

	protected Object createValueFromHelper(ModifierHelper aHelper) {
		EObject newObject = createObjectFromHelper(aHelper);
		setNewObjectAttributes(newObject, aHelper);
		return newObject;
	}

	protected boolean enumValueChanged(EObject anObject, EStructuralFeature aFeature, Object aValue) {
		if (!anObject.eIsSet(aFeature))
			return true;
		Enumerator existingEnumerator = (Enumerator) anObject.eGet(aFeature);
		Enumerator newEnumerator = getEnumerator(aFeature, aValue);
		return existingEnumerator != newEnumerator;
	}

	private Enumerator getEnumerator(EStructuralFeature aFeature, Object aValue) {
		if (aValue instanceof Enumerator)
			return (Enumerator) aValue;
		EEnum anEnum = (EEnum) aFeature.getEType();
		EEnumLiteral literal = null;
		if (aValue instanceof String)
			literal = anEnum.getEEnumLiteral((String) aValue);
		else if (aValue instanceof Integer)
			literal = anEnum.getEEnumLiteral(((Integer) aValue).intValue());
		if (literal != null)
			return literal.getInstance();
		return null;
	}

	protected Object getValue(ModifierHelper aHelper) {
		if (aHelper.mustCreateValue()) {
			Object value = createValueFromHelper(aHelper);
			aHelper.setValue(value);
		}
		return aHelper.getValue();
	}

	protected boolean manyValueChanged(EObject anObject, EStructuralFeature aFeature, Object aValue, boolean isUnset) {
		List list = (List) anObject.eGet(aFeature);
		if (isUnset)
			return list.contains(aValue) || (list == aValue && !list.isEmpty());
		return !list.contains(aValue);
	}

	/**
	 * Return a Command that will be executed by a CommandStack. The default is to return null.
	 * Subclasses should override this method.
	 */
	protected Command primCreateCommand(ModifierHelper aHelper) {
		Command command = doCreateCommand(aHelper);
		if (aHelper.shouldUnsetValue()) {
			Object value = aHelper.getValue();
			if (value instanceof EObject && !((EObject) value).eIsProxy()) {
				command = new ProxyWrappingCommand(command, (EObject) value);
			}
		}
		return command;
	}

	protected Command doCreateCommand(ModifierHelper aHelper) {
		if (!aHelper.isComplete()) {
			setStatus(ERROR);
			return null;
		}
		Command command = null;
		if (aHelper.getFeature().isMany())
			command = createManyCommand(aHelper);
		else
			command = createSingleCommand(aHelper);

		if (null != command) {
			List localHelpers = ModifierHelperRegistry.getInstance().getHelpers(aHelper);
			if (null != localHelpers) {
				extendedHelpers.addAll(localHelpers);
			}
		}
		return command;

	}

	/**
	 * Run using
	 * 
	 * @aHelper. This will set a MOF attibute value to the owner of the helper.
	 */
	protected void primRun(ModifierHelper aHelper) {
		if (aHelper.isComplete()) {
			Object value = getValue(aHelper);
			if (valueChanged(aHelper.getOwner(), aHelper.getFeature(), value, aHelper.shouldUnsetValue()))
				setObjectAttribute(aHelper.getOwner(), aHelper.getFeature(), value, aHelper.shouldUnsetValue());
		}
	}

	/**
	 * The default is to do nothing. Subclasses should override this method if they are using
	 * recordable commands. The implementation of this method should update the MOF model directly.
	 * Any modification will be recorded.
	 */
	public void run() {
		if (!getHelpers().isEmpty()) {
			Iterator it = getHelpers().iterator();
			while (it.hasNext())
				run((ModifierHelper) it.next());
		}
	}

	/**
	 * Run using
	 * 
	 * @aHelper's ownerHelper first before running with
	 * @aHelper.
	 */
	protected void run(ModifierHelper aHelper) {
		if (aHelper != null) {
			run(aHelper.getOwnerHelper());
			primRun(aHelper);
		}
	}

	protected void setNewObjectAttributes(EObject anObject, ModifierHelper aHelper) {
		HashMap attributes = aHelper.getAttributes();
		Iterator it = attributes.keySet().iterator();
		EStructuralFeature feature;
		Object value = null;
		while (it.hasNext()) {
			feature = (EStructuralFeature) it.next();
			value = attributes.get(feature);
			setObjectAttribute(anObject, feature, value, false);
		}
	}

	protected void setObjectAttribute(EObject anObject, EStructuralFeature aFeature, Object aValue, boolean shouldUnsetValue) {
		if (aFeature.isMany())
			setObjectManyAttribute(anObject, aFeature, aValue, shouldUnsetValue);
		else
			setObjectSingleAttribute(anObject, aFeature, aValue, shouldUnsetValue);
	}

	protected void setObjectEnumAttribute(EObject anObject, EStructuralFeature aFeature, Object aValue) {
		Enumerator enumerator = getEnumerator(aFeature, aValue);
		anObject.eSet(aFeature, enumerator);
	}

	protected void setObjectManyAttribute(EObject anObject, EStructuralFeature aFeature, Object aValue, boolean shouldUnsetValue) {
		List list = (List) anObject.eGet(aFeature);
		if (shouldUnsetValue)
			list.remove(aValue);
		else
			list.add(aValue);
	}

	protected void setObjectSingleAttribute(EObject anObject, EStructuralFeature aFeature, Object aValue, boolean shouldUnsetValue) {
		if (shouldUnsetValue)
			anObject.eUnset(aFeature);
		else if (aFeature.getEType() instanceof EEnum)
			setObjectEnumAttribute(anObject, aFeature, aValue);
		else
			anObject.eSet(aFeature, aValue);
	}

	protected boolean singleValueChanged(EObject anObject, EStructuralFeature aFeature, Object aValue, boolean isUnset) {
		if (aFeature.getEType() instanceof EEnum)
			return enumValueChanged(anObject, aFeature, aValue);

		Object existingValue = anObject.eGet(aFeature);
		if (existingValue == null && aValue == null)
			return false;
		if (existingValue != null && !existingValue.equals(aValue))
			return true;
		if (aValue != null && !aValue.equals(existingValue))
			return true;
		return false;
	}

	protected boolean valueChanged(EObject anObject, EStructuralFeature aFeature, Object aValue, boolean isUnset) {
		if (aFeature.isMany())
			return manyValueChanged(anObject, aFeature, aValue, isUnset);
		return singleValueChanged(anObject, aFeature, aValue, isUnset);
	}
}
