/*******************************************************************************
 * Copyright (c) 2003, 2004 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) {
		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 (chainedCommand == null)
					chainedCommand = nextCommand;
				else if (nextCommand != null)
					chainedCommand = chainedCommand.chain(nextCommand);
			}
		}
		if (!extendedHelpers.isEmpty()) {
			List copy = new ArrayList();
			copy.addAll(extendedHelpers);
			extendedHelpers.clear();
			chainedCommand = createCommand(chainedCommand, copy);
		}
		return chainedCommand;
	}

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

	/**
	 * 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 String[]{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();
	}

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

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

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

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

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

		public void redo() {
			baseCommand.redo();
		}

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

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

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

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

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