/*******************************************************************************
 * Copyright (c) 2000, 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.jdt.internal.core;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModelStatus;
import org.eclipse.jdt.core.IJavaModelStatusConstants;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IParent;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
import org.eclipse.jdt.internal.compiler.util.Util;
import org.eclipse.jdt.internal.core.util.Messages;

/**
 * This operation copies/moves a collection of elements from their current
 * container to a new container, optionally renaming the
 * elements.
 * <p>Notes:<ul>
 *    <li>If there is already an element with the same name in
 *    the new container, the operation either overwrites or aborts,
 *    depending on the collision policy setting. The default setting is
 *	  abort.
 *
 *    <li>When constructors are copied to a type, the constructors
 *    are automatically renamed to the name of the destination
 *    type.
 *
 *	  <li>When main types are renamed (move within the same parent),
 *		the compilation unit and constructors are automatically renamed
 *
 *    <li>The collection of elements being copied must all share the
 *    same type of container (for example, must all be type members).
 *
 *    <li>The elements are inserted in the new container in the order given.
 *
 *    <li>The elements can be positioned in the new container - see #setInsertBefore.
 *    By default, the elements are inserted based on the default positions as specified in
 * 	the creation operation for that element type.
 *
 *    <li>This operation can be used to copy and rename elements within
 *    the same container. 
 *
 *    <li>This operation only copies elements contained within compilation units. 
 * </ul>
 *
 */
public class CopyElementsOperation extends MultiOperation implements SuffixConstants {

	
	private Map sources = new HashMap();
/**
 * When executed, this operation will copy the given elements to the
 * given containers.  The elements and destination containers must be in
 * the correct order. If there is > 1 destination, the number of destinations
 * must be the same as the number of elements being copied/moved/renamed.
 */
public CopyElementsOperation(IJavaElement[] elementsToCopy, IJavaElement[] destContainers, boolean force) {
	super(elementsToCopy, destContainers, force);
}
/**
 * When executed, this operation will copy the given elements to the
 * given container.
 */
public CopyElementsOperation(IJavaElement[] elementsToCopy, IJavaElement destContainer, boolean force) {
	this(elementsToCopy, new IJavaElement[]{destContainer}, force);
}
/**
 * Returns the <code>String</code> to use as the main task name
 * for progress monitoring.
 */
protected String getMainTaskName() {
	return Messages.operation_copyElementProgress; 
}
/**
 * Returns the nested operation to use for processing this element
 */
protected JavaModelOperation getNestedOperation(IJavaElement element) {
	try {
		IJavaElement dest = getDestinationParent(element);
		switch (element.getElementType()) {
			case IJavaElement.PACKAGE_DECLARATION :
				return new CreatePackageDeclarationOperation(element.getElementName(), (ICompilationUnit) dest);
			case IJavaElement.IMPORT_DECLARATION :
				return new CreateImportOperation(element.getElementName(), (ICompilationUnit) dest);
			case IJavaElement.TYPE :
				if (isRenamingMainType(element, dest)) {
					IPath path = element.getPath();
					String extension = path.getFileExtension();
					return new RenameResourceElementsOperation(new IJavaElement[] {dest}, new IJavaElement[] {dest.getParent()}, new String[]{getNewNameFor(element) + '.' + extension}, this.force); //$NON-NLS-1$
				} else {
					return new CreateTypeOperation(dest, getSourceFor(element) + Util.LINE_SEPARATOR, this.force);
				}
			case IJavaElement.METHOD :
				return new CreateMethodOperation((IType) dest, getSourceFor(element) + Util.LINE_SEPARATOR, this.force);
			case IJavaElement.FIELD :
				return new CreateFieldOperation((IType) dest, getSourceFor(element) + Util.LINE_SEPARATOR, this.force);
			case IJavaElement.INITIALIZER :
				return new CreateInitializerOperation((IType) dest, getSourceFor(element) + Util.LINE_SEPARATOR);
			default :
				return null;
		}
	} catch (JavaModelException npe) {
		return null;
	}
}
/**
 * Returns the cached source for this element or compute it if not already cached.
 */
private String getSourceFor(IJavaElement element) throws JavaModelException {
	String source = (String) this.sources.get(element);
	if (source == null && element instanceof IMember) {
		source = ((IMember)element).getSource();
		this.sources.put(element, source);
	}
	return source;
}
/**
 * Returns <code>true</code> if this element is the main type of its compilation unit.
 */
protected boolean isRenamingMainType(IJavaElement element, IJavaElement dest) throws JavaModelException {
	if ((isRename() || getNewNameFor(element) != null)
		&& dest.getElementType() == IJavaElement.COMPILATION_UNIT) {
		String typeName = dest.getElementName();
		typeName = org.eclipse.jdt.internal.core.util.Util.getNameWithoutJavaLikeExtension(typeName);
		return element.getElementName().equals(typeName) && element.getParent().equals(dest);
	}
	return false;
}
/**
 * Copy/move the element from the source to destination, renaming
 * the elements as specified, honoring the collision policy.
 *
 * @exception JavaModelException if the operation is unable to
 * be completed
 */
protected void processElement(IJavaElement element) throws JavaModelException {
	JavaModelOperation op = getNestedOperation(element);
	boolean createElementInCUOperation =op instanceof CreateElementInCUOperation;
	if (op == null) {
		return;
	}
	if (createElementInCUOperation) {
		IJavaElement sibling = (IJavaElement) this.insertBeforeElements.get(element);
		if (sibling != null) {
			((CreateElementInCUOperation) op).setRelativePosition(sibling, CreateElementInCUOperation.INSERT_BEFORE);
		} else
			if (isRename()) {
				IJavaElement anchor = resolveRenameAnchor(element);
				if (anchor != null) {
					((CreateElementInCUOperation) op).setRelativePosition(anchor, CreateElementInCUOperation.INSERT_AFTER); // insert after so that the anchor is found before when deleted below
				}
			}
		String newName = getNewNameFor(element);
		if (newName != null) {
			((CreateElementInCUOperation) op).setAlteredName(newName);
		}
	}
	executeNestedOperation(op, 1);

	JavaElement destination = (JavaElement) getDestinationParent(element);
	ICompilationUnit unit= destination.getCompilationUnit();
	if (!unit.isWorkingCopy()) {
		unit.close();
	}

	if (createElementInCUOperation && isMove() && !isRenamingMainType(element, destination)) {
		DeleteElementsOperation deleteOp = new DeleteElementsOperation(new IJavaElement[] { element }, this.force);
		executeNestedOperation(deleteOp, 1);
	}
}
/**
 * Returns the anchor used for positioning in the destination for 
 * the element being renamed. For renaming, if no anchor has
 * explicitly been provided, the element is anchored in the same position.
 */
private IJavaElement resolveRenameAnchor(IJavaElement element) throws JavaModelException {
	IParent parent = (IParent) element.getParent();
	IJavaElement[] children = parent.getChildren();
	for (int i = 0; i < children.length; i++) {
		IJavaElement child = children[i];
		if (child.equals(element)) {
			return child;
		}
	}
	return null;
}
/**
 * Possible failures:
 * <ul>
 *  <li>NO_ELEMENTS_TO_PROCESS - no elements supplied to the operation
 *	<li>INDEX_OUT_OF_BOUNDS - the number of renamings supplied to the operation
 *		does not match the number of elements that were supplied.
 * </ul>
 */
protected IJavaModelStatus verify() {
	IJavaModelStatus status = super.verify();
	if (!status.isOK()) {
		return status;
	}
	if (this.renamingsList != null && this.renamingsList.length != this.elementsToProcess.length) {
		return new JavaModelStatus(IJavaModelStatusConstants.INDEX_OUT_OF_BOUNDS);
	}
	return JavaModelStatus.VERIFIED_OK;
}
/**
 * @see MultiOperation
 *
 * Possible failure codes:
 * <ul>
 *
 *	<li>ELEMENT_DOES_NOT_EXIST - <code>element</code> or its specified destination is
 *		is <code>null</code> or does not exist. If a <code>null</code> element is
 *		supplied, no element is provided in the status, otherwise, the non-existant element
 *		is supplied in the status.
 *	<li>INVALID_ELEMENT_TYPES - <code>element</code> is not contained within a compilation unit.
 *		This operation only operates on elements contained within compilation units.
 *  <li>READ_ONLY - <code>element</code> is read only.
 *	<li>INVALID_DESTINATION - The destination parent specified for <code>element</code>
 *		is of an incompatible type. The destination for a package declaration or import declaration must
 *		be a compilation unit; the destination for a type must be a type or compilation
 *		unit; the destinaion for any type member (other than a type) must be a type. When
 *		this error occurs, the element provided in the operation status is the <code>element</code>.
 *	<li>INVALID_NAME - the new name for <code>element</code> does not have valid syntax.
 *      In this case the element and name are provided in the status.

 * </ul>
 */
protected void verify(IJavaElement element) throws JavaModelException {
	if (element == null || !element.exists())
		error(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, element);

	if (element.getElementType() < IJavaElement.TYPE)
		error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);

	if (element.isReadOnly())
		error(IJavaModelStatusConstants.READ_ONLY, element);

	IJavaElement dest = getDestinationParent(element);
	verifyDestination(element, dest);
	verifySibling(element, dest);
	if (this.renamingsList != null) {
		verifyRenaming(element);
	}
}
}
