/*******************************************************************************
 * 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.jst.j2ee.internal.webservice.command;

import java.util.Collection;
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.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jst.j2ee.webservice.wsclient.WebServicesClient;


public class CommandMoveServiceRefs extends AbstractCommand {
	private EObject source_;
	private EObject target_;
	private EStructuralFeature childFeature_;
	private Object[] children_;
	private boolean isCopy_;
	private Object[] clonedChildren_;
	private EList serviceRefs;

	public CommandMoveServiceRefs(String label, String description, EObject source, EObject target, EStructuralFeature childFeature, Object[] children, boolean isCopy, EList serviceRefs) {
		super(label, description);
		source_ = source;
		target_ = target;
		childFeature_ = childFeature;
		children_ = children;
		isCopy_ = isCopy;
		clonedChildren_ = null;
		this.serviceRefs = serviceRefs;
	}

	private Object cloneObject(Object object) {
		if (object instanceof EList) {
			EList clone = new BasicEList();
			for (Iterator it = ((EList) object).iterator(); it.hasNext();) {
				clone.add(cloneObject(it.next()));
			}
			return clone;
		}
		if (object instanceof EObject) {
			EObject source = (EObject) object;
			EClass eClass = ((EObject) object).eClass();
			EPackage ePackage = eClass.getEPackage();
			EFactory eFactory = ePackage.getEFactoryInstance();
			EObject clone = eFactory.create(eClass);
			EList features = eClass.getEAllStructuralFeatures();
			for (Iterator it = features.iterator(); it.hasNext();) {
				EStructuralFeature feature = (EStructuralFeature) it.next();
				if (source.eIsSet(feature)) {
					Object clonedFeature = cloneObject(source.eGet(feature));
					if (feature.isMany())
						((List) clone.eGet(feature)).addAll((List) clonedFeature);
					else
						clone.eSet(feature, clonedFeature);
				} else
					clone.eUnset(feature);
			}
			return clone;
		}
		if (object != null)
			return new String(object.toString());
		return null;
	}

	/**
	 * Called at most once in {@link #canExecute}to give the command an opportunity to ready itself
	 * for execution. The returned value is stored in {@link #canExecute}. In other words, you can
	 * override this method to initialize and to yield a cached value for the all subsequent calls
	 * to canExecute.
	 * 
	 * @return whether the command is executable.
	 */
	@Override
	protected boolean prepare() {
		return true;
	}

	/**
	 * Returns whether the comamad is valid to <code>execute</code>. The
	 * {@link UnexecutableCommand#INSTANCE}.<code>canExecute()</code> always returns
	 * <code>false</code>. This <b>must </b> be called before calling <code>execute</code>.
	 * 
	 * @return whether the comamad is valid to <code>execute</code>.
	 */
	@Override
	public boolean canExecute() {
		return super.canExecute();
	}

	/**
	 * Performs the command activity required for the effect. The effect of calling
	 * <code>execute</code> when <code>canExecute</code> returns <code>false</code>, or when
	 * <code>canExecute</code> hasn't been called, is undefined.
	 */
	public void execute() {
		if (childFeature_.isMany())
			executeMany();
		else
			executeSingle();
	}

	private void executeSingle() {
		Object child = source_.eGet(childFeature_);
		if (isCopy_)
			target_.eSet(childFeature_, cloneObject(child));
		else {
			source_.eUnset(childFeature_);
			target_.eSet(childFeature_, child);
		}
	}

	private void executeMany() {
		EList sourceList;
		if (source_ instanceof WebServicesClient)
			sourceList = serviceRefs;
		else
			sourceList = (EList) source_.eGet(childFeature_);
		EList targetList;
		if (target_ instanceof WebServicesClient)
			targetList = serviceRefs;
		else
			targetList = (EList) target_.eGet(childFeature_);
		if (isCopy_)
			clonedChildren_ = new Object[children_.length];
		for (int i = 0; i < children_.length; i++) {
			int index = sourceList.indexOf(children_[i]);
			if (index != -1) {
				if (isCopy_) {
					clonedChildren_[i] = cloneObject(children_[i]);
					targetList.add(clonedChildren_[i]);
				} else {
					sourceList.remove(index);
					targetList.add(children_[i]);
				}
			}
		}
	}

	/**
	 * Returns <code>true</code> because most command should be undoable.
	 * 
	 * @return <code>true</code>.
	 */
	@Override
	public boolean canUndo() {
		return true;
	}

	/**
	 * Performs the command activity required to <code>undo</code> the effects of a preceding
	 * <code>execute</code> (or <code>redo</code>). The effect, if any, of calling
	 * <code>undo</code> before <code>execute</code> or <code>redo</code> have been called, or
	 * when canUndo returns <code>false</code>, is undefined.
	 */
	@Override
	public void undo() {
		if (childFeature_.isMany())
			undoSingle();
		else
			undoMany();
	}

	private void undoSingle() {
		Object child = target_.eGet(childFeature_);
		target_.eUnset(childFeature_);
		if (!isCopy_)
			source_.eSet(childFeature_, child);
	}

	private void undoMany() {
		EList sourceList;
		if (source_ instanceof WebServicesClient)
			sourceList = serviceRefs;
		else
			sourceList = (EList) source_.eGet(childFeature_);
		EList targetList;
		if (target_ instanceof WebServicesClient)
			targetList = serviceRefs;
		else
			targetList = (EList) target_.eGet(childFeature_);
		if (isCopy_) {
			if (clonedChildren_ != null) {
				for (int i = 0; i < clonedChildren_.length; i++) {
					targetList.remove(clonedChildren_[i]);
				}
			}
		} else {
			for (int i = 0; i < children_.length; i++) {
				int index = targetList.indexOf(children_[i]);
				if (index != -1) {
					targetList.remove(index);
					sourceList.add(children_[i]);
				}
			}
		}
	}

	/**
	 * Performs the command activity required to <code>redo</code> the effect after undoing the
	 * effect. The effect, if any, of calling <code>redo</code> before <code>undo</code> is
	 * called is undefined. Note that if you implement <code>redo</code> to call
	 * <code>execute</code> then any derived class will be restricted by that decision also.
	 */
	public void redo() {
		execute();
	}

	/**
	 * Returns a collection of things which this command wishes to present as it's result. The
	 * result of calling this before an <code>execute</code> or <code>redo</code>, or after an
	 * <code>undo</code>, is undefined.
	 * 
	 * @return a collection of things which this command wishes to present as it's result.
	 */
	@Override
	public Collection getResult() {
		return super.getResult();
	}

	/**
	 * Returns the collection of things which this command wishes to present as the objects affected
	 * by the command. Typically should could be used as the selection that should be highlighted to
	 * best illustrate the effect of the command. The result of calling this before an
	 * <code>execute</code>,<code>redo</code>, or <code>undo</code> is undefined. The
	 * result may be different after an <code>undo</code> than it is after an <code>execute</code>
	 * or <code>redo</code>, but the result should be the same (equivalent) after either an
	 * <code>execute</code> or <code>redo</code>.
	 * 
	 * @return the collection of things which this command wishes to present as the objects affected
	 *         by the command.
	 */
	@Override
	public Collection getAffectedObjects() {
		return super.getAffectedObjects();
	}

	/**
	 * Called to indicate that the command will never be used again. Calling any other method after
	 * this one has undefined results.
	 */
	@Override
	public void dispose() {
		//Do nothing
	}

	/**
	 * Returns a command that represents the composition of this command with the given command. The
	 * resulting command may just be this, if this command is capabable of composition. Otherwise,
	 * it will be a new command created to compose the two.
	 * <p>
	 * Instead of the following pattern of usage
	 * 
	 * <pre>
	 * Command result = x;
	 * if (condition)
	 * 	result = result.chain(y);
	 * </pre>
	 * 
	 * you should consider using a {@link org.eclipse.emf.common.command.CompoundCommand}and using
	 * {@link org.eclipse.emf.common.command.CompoundCommand#unwrap()}to optimize the result:
	 * 
	 * <pre>
	 * CompoundCommand subcommands = new CompoundCommand();
	 * subcommands.append(x);
	 * if (condition)
	 * 	subcommands.append(y);
	 * Command result = subcommands.unwrap();
	 * </pre>
	 * 
	 * This gives you more control over how the compound command composes it's result and affected
	 * objects.
	 * 
	 * @param command
	 *            the command to chain.
	 * @return a command that represents the composition of this command with the given command.
	 */
	@Override
	public Command chain(Command command) {
		return super.chain(command);
	}
}
