package org.eclipse.cdt.internal.core.model;

/*
 * (c) Copyright QNX Software Systems Ltd. 2002.
 * All Rights Reserved.
 */
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICModelStatus;
import org.eclipse.cdt.core.model.ICModelStatusConstants;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;

/**
 * This operation copies/moves/renames a collection of resources from their current
 * container to a new container, optionally renaming the
 * elements.
 * <p>Notes:<ul>
 *    <li>If there is already an resource 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>The collection of elements being copied must all share the
 *    same type of container.
 *
 *    <li>This operation can be used to copy and rename elements within
 *    the same container. 
 *
 *    <li>This operation only copies translation units.
 * </ul>
 *
 */
public class CopyResourceElementsOperation extends MultiOperation {

	/**
	 * The list of new resources created during this operation.
	 */
	protected ArrayList fCreatedElements;

	/**
	 * Table specifying deltas for elements being 
	 * copied/moved/renamed. Keyed by elements' project(s), and
	 * values are the corresponding deltas.
	 */
	protected Map fDeltasPerProject= new HashMap(1);

	public CopyResourceElementsOperation(ICElement[] src, ICElement[] dst, boolean force) {
		super(src, dst, force);
	}

	/**
	 * Returns the <code>CElementDelta</code> for <code>cProject</code>,
	 * creating it and putting it in <code>fDeltasPerProject</code> if
	 * it does not exist yet.
	 */
	private CElementDelta getDeltaFor(ICProject cProject) {
		CElementDelta delta = (CElementDelta) fDeltasPerProject.get(cProject);
		if (delta == null) {
			delta = new CElementDelta(cProject);
			fDeltasPerProject.put(cProject, delta);
		}
		return delta;
	}

	/**
	 * @see MultiOperation
	 */
	protected String getMainTaskName() {
		return "operation.copyResourceProgress"; //$NON-NLS-1$
	}

	/**
	 * Sets the deltas to register the changes resulting from this operation
	 * for this source element and its destination.
	 * If the operation is a cross project operation<ul>
	 * <li>On a copy, the delta should be rooted in the dest project
	 * <li>On a move, two deltas are generated<ul>
	 *                      <li>one rooted in the source project
	 *                      <li>one rooted in the destination project</ul></ul>
	 * If the operation is rooted in a single project, the delta is rooted in that project
	 *       
	 */
	protected void prepareDeltas(ICElement sourceElement, ICElement destinationElement) {
		ICProject destProject = destinationElement.getCProject();
		if (isMove()) {
			ICProject sourceProject = sourceElement.getCProject();
			getDeltaFor(sourceProject).movedFrom(sourceElement, destinationElement);
			getDeltaFor(destProject).movedTo(destinationElement, sourceElement);
		} else {
			getDeltaFor(destProject).added(destinationElement);
		}
	}

	/**
	 * Process all of the changed deltas generated by this operation.
	 */
	protected void processDeltas() {
		for (Iterator deltas = this.fDeltasPerProject.values().iterator(); deltas.hasNext();){
			addDelta((ICElementDelta) deltas.next());
		}
	}

	/**
	 * Copies/moves a compilation unit with the name <code>newName</code>
	 * to the destination package.<br>
	 * The package statement in the compilation unit is updated if necessary.
	 * The main type of the compilation unit is renamed if necessary.
	 *
	 * @exception JavaModelException if the operation is unable to
	 * complete
	 */
	private void processResource(ICElement source, ICElement dest) throws CModelException {
		String newName = getNewNameFor(source);
		String destName = (newName != null) ? newName : source.getElementName();

		// copy resource
		IFile sourceResource = (IFile)source.getResource();
		// can be an IFolder or an IProject
		IContainer destFolder = (IContainer)dest.getResource();
		IFile destFile = destFolder.getFile(new Path(destName));
		if (!destFile.equals(sourceResource)) {
			try {
				if (destFile.exists()) {
					if (fForce) {
						// we can remove it
						deleteResource(destFile, false);
					} else {
						// abort
						throw new CModelException(new CModelStatus(ICModelStatusConstants.NAME_COLLISION));
					}
				}
				if (this.isMove()) {
					sourceResource.move(destFile.getFullPath(), fForce, true, getSubProgressMonitor(1));
				} else {
					sourceResource.copy(destFile.getFullPath(), fForce, getSubProgressMonitor(1));
				}
				this.hasModifiedResource = true;
			} catch (CModelException e) {
				throw e;
			} catch (CoreException e) {
				throw new CModelException(e);
			}

			// update new resource content
        
			// register the correct change deltas
			ICElement cdest = CModelManager.getDefault().create(destFile);
			prepareDeltas(source, cdest);
			fCreatedElements.add(cdest);
			//if (newName != null) {
				//the main type has been renamed
				//String oldName = source.getElementName();
				//oldName = oldName.substring(0, oldName.length() - 5);
				//String nName = newName;
				//nName = nName.substring(0, nName.length() - 5);
				//prepareDeltas(source.getType(oldName), cdest.getType(nName));
			//}
		} else {
			if (!fForce) {
				throw new CModelException(new CModelStatus(ICModelStatusConstants.NAME_COLLISION));
			}
			// update new resource content
			// in case we do a saveas on the same resource we have to simply update the contents
			// see http://dev.eclipse.org/bugs/show_bug.cgi?id=9351
		}
	}

	/**
	 * @see MultiOperation
	 * This method delegates to <code>processResource</code> or
	 * <code>processPackageFragmentResource</code>, depending on the type of
	 * <code>element</code>.
	 */
	protected void processElement(ICElement element) throws CModelException {
		ICElement dest = getDestinationParent(element);
		if (element.getElementType() <= ICElement.C_UNIT) {
			processResource(element, dest);
			//fCreatedElements.add(dest.getCompilationUnit(element.getElementName()));
		} else {
			throw new CModelException(new CModelStatus(ICModelStatusConstants.INVALID_ELEMENT_TYPES, element));
		}
	}

	/**
	 * @see MultiOperation
	 * Overridden to allow special processing of <code>CElementDelta</code>s
	 * and <code>fResultElements</code>.
	 */
	protected void processElements() throws CModelException {
		fCreatedElements = new ArrayList(fElementsToProcess.length);
		try {
			super.processElements();
		} catch (CModelException cme) {
			throw cme;
		} finally {
			fResultElements = new ICElement[fCreatedElements.size()];
			fCreatedElements.toArray(fResultElements);
			processDeltas();
		}
	}

	/**
	 * 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 ICModelStatus verify() {
		ICModelStatus status = super.verify();
		if (!status.isOK()) {
			return status;
		}

		if (fRenamingsList != null && fRenamingsList.length != fElementsToProcess.length) {
			return new CModelStatus(ICModelStatusConstants.INDEX_OUT_OF_BOUNDS);
		}
		return CModelStatus.VERIFIED_OK;
	}

	/**
	 * @see MultiOperation
	 */
	protected void verify(ICElement element) throws CModelException {
		if (element == null || !element.exists())
			error(ICModelStatusConstants.ELEMENT_DOES_NOT_EXIST, element);
                
		if (element.isReadOnly() && (isRename() || isMove()))
			error(ICModelStatusConstants.READ_ONLY, element);

		CElement dest = (CElement) getDestinationParent(element);
		verifyDestination(element, dest);
		if (fRenamings != null) {
			verifyRenaming(element);
		}
	}
}
