/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.text.edits;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.text.Assert;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;

/**
 * A move source edit denotes the source of a move operation. Move
 * source edits are only valid inside an edit tree if they have a
 * corresponding target edit. Furthermore the corresponding target 
 * edit can't be a direct or indirect child of the source edit. 
 * Violating one of two requirements will result in a <code>
 * MalformedTreeException</code> when executing the edit tree.
 * <p>
 * A move source edit can manage an optional source modifier. A
 * source modifier can provide a set of replace edits which will
 * to applied to the source before it gets inserted at the target
 * position.
 * 
 * @see org.eclipse.text.edits.MoveTargetEdit
 * @see org.eclipse.text.edits.CopySourceEdit
 *  
 * @since 3.0 
 */
public final class MoveSourceEdit extends TextEdit {

	private MoveTargetEdit fTarget;
	private ISourceModifier fModifier;
	
	private String fSourceContent;
	private MultiTextEdit fSourceRoot;
	
	/**
	 * Constructs a new move source edit.
	 * 
	 * @param offset the edit's offset
	 * @param length the edit's length
	 */
	public MoveSourceEdit(int offset, int length) {
		super(offset, length);
	}

	/**
	 * Constructs a new copy source edit.
	 * 
	 * @param offset the edit's offset
	 * @param length the edit's length
	 * @param target the edit's target
	 */
	public MoveSourceEdit(int offset, int length, MoveTargetEdit target) {
		this(offset, length);
		setTargetEdit(target);
	}

	/*
	 * Copy constructor
	 */
	private MoveSourceEdit(MoveSourceEdit other) {
		super(other);
		if (other.fModifier != null)
			fModifier= other.fModifier.copy();
	}
	
	/**
	 * Returns the associated traget edit or <code>null</code>
	 * if no target edit is associated yet.
	 * 
	 * @return the target edit or <code>null</code>
	 */
	public MoveTargetEdit getTargetEdit() {
		return fTarget;
	}
	
	/**
	 * Sets the target edit.
	 * 
	 * @param edit the new target edit.
	 * 
	 * @exception MalformedTreeException is thrown if the target edit
	 *  is a direct or indirect child of the source edit
	 */
	public void setTargetEdit(MoveTargetEdit edit) {
		fTarget= edit;
		fTarget.setSourceEdit(this);
	}
	
	/**
	 * Returns the current source modifier or <code>null</code>
	 * if no source modifier is set.
	 * 
	 * @return the source modifier
	 */
	public ISourceModifier getSourceModifier() {
		return fModifier;
	}
	
	/**
	 * Sets the optional source modifier.
	 * 
	 * @param modifier the source modifier or <code>null</code>
	 *  if no source modification is need. 
	 */
	public void setSourceModifier(ISourceModifier modifier) {
		fModifier= modifier;
	}

	//---- API for MoveTargetEdit ---------------------------------------------
	
	/* package */ String getContent() {
		// The source content can be null if the edit wasn't executed
		// due to an exclusion list of the text edit processor. Return
		// the empty string which can be moved without any harm.
		if (fSourceContent == null)
			return ""; //$NON-NLS-1$
		return fSourceContent;
	}
	
	/* package */ MultiTextEdit getSourceRoot() {
		return fSourceRoot;
	}
	
	/* package */ void clearContent() {
		fSourceContent= null;
		fSourceRoot= null;
	}
	
	//---- Copying -------------------------------------------------------------
	
	/* non Java-doc
	 * @see TextEdit#doCopy
	 */	
	protected TextEdit doCopy() {
		return new MoveSourceEdit(this);
	}

	/* non Java-doc
	 * @see TextEdit#postProcessCopy
	 */	
	protected void postProcessCopy(TextEditCopier copier) {
		if (fTarget != null) {
			MoveSourceEdit source= (MoveSourceEdit)copier.getCopy(this);
			MoveTargetEdit target= (MoveTargetEdit)copier.getCopy(fTarget);
			if (source != null && target != null)
				source.setTargetEdit(target);
		}
	}
	
	//---- Visitor -------------------------------------------------------------
	
	/* (non-Javadoc)
	 * @see TextEdit#accept0
	 */
	protected void accept0(TextEditVisitor visitor) {
		boolean visitChildren = visitor.visit(this);
		if (visitChildren) {
			acceptChildren(visitor);
		}
	}

	//---- consistency check ----------------------------------------------------------------
	
	/* package */ int traverseConsistencyCheck(TextEditProcessor processor, IDocument document, List sourceEdits) {
		int result= super.traverseConsistencyCheck(processor, document, sourceEdits);
		// Since source computation takes place in a recursive fashion (see
		// performSourceComputation) we only do something if we don't have a 
		// computated source already.
		if (fSourceContent == null) {
			if (sourceEdits.size() <= result) {
				List list= new ArrayList();
				list.add(this);
				for (int i= sourceEdits.size(); i < result; i++)
					sourceEdits.add(null);
				sourceEdits.add(list);
			} else {
				List list= (List)sourceEdits.get(result);
				if (list == null) {
					list= new ArrayList();
					sourceEdits.add(result, list);
				}
				list.add(this);
			}
		}
		return result;
	}
	
	/* package */ void performConsistencyCheck(TextEditProcessor processor, IDocument document) throws MalformedTreeException {
		if (fTarget == null)
			throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveSourceEdit.no_target")); //$NON-NLS-1$
		if (fTarget.getSourceEdit() != this)
			throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveSourceEdit.different_source"));  //$NON-NLS-1$
		/* Causes AST rewrite to fail
		if (getRoot() != fTarget.getRoot())
			throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveSourceEdit.different_tree")); //$NON-NLS-1$
		*/
	}

	//---- source computation --------------------------------------------------------------
	
	/* package */ void traverseSourceComputation(TextEditProcessor processor, IDocument document) {
		if (processor.considerEdit(this)) {
			performSourceComputation(processor, document);
		}
	}
	
	/* package */ void performSourceComputation(TextEditProcessor processor, IDocument document) {
		try {
			TextEdit[] children= removeChildren();
			if (children.length > 0) {
				String content= document.get(getOffset(), getLength());
				EditDocument subDocument= new EditDocument(content);
				fSourceRoot= new MultiTextEdit(getOffset(), getLength());
				fSourceRoot.addChildren(children);
				fSourceRoot.moveTree(-getOffset());
				int processingStyle= getStyle(processor);
				TextEditProcessor subProcessor= TextEditProcessor.createSourceComputationProcessor(subDocument, fSourceRoot, processingStyle);
				subProcessor.performEdits();
				if (needsTransformation())
					applyTransformation(subDocument, processingStyle);
				fSourceContent= subDocument.get();
			} else {
				fSourceContent= document.get(getOffset(), getLength());
				if (needsTransformation()) {
					EditDocument subDocument= new EditDocument(fSourceContent);
					applyTransformation(subDocument, getStyle(processor));
					fSourceContent= subDocument.get();
				}
			}
		} catch (BadLocationException cannotHappen) {
			Assert.isTrue(false);
		}
	}
	
	private int getStyle(TextEditProcessor processor) {
		// we never need undo while performing local edits.
		if ((processor.getStyle() & TextEdit.UPDATE_REGIONS) != 0)
			return TextEdit.UPDATE_REGIONS;
		return TextEdit.NONE;
	}
	
	//---- document updating ----------------------------------------------------------------
	
	/* package */ int performDocumentUpdating(IDocument document) throws BadLocationException {
		document.replace(getOffset(), getLength(), ""); //$NON-NLS-1$
		fDelta= -getLength();
		return fDelta;
	}
	
	//---- region updating --------------------------------------------------------------
	
	/* non Java-doc
	 * @see TextEdit#deleteChildren
	 */	
	/* package */ boolean deleteChildren() {
		return false;
	}
	
	//---- content transformation --------------------------------------------------
	
	private boolean needsTransformation() {
		return fModifier != null;
	}
	
	private void applyTransformation(IDocument document, int style) throws MalformedTreeException {
		if ((style & TextEdit.UPDATE_REGIONS) != 0 && fSourceRoot != null) {
			Map editMap= new HashMap();
			TextEdit newEdit= createEdit(editMap);
			List replaces= new ArrayList(Arrays.asList(fModifier.getModifications(document.get())));
			insertEdits(newEdit, replaces);
			try {
				newEdit.apply(document, style);
			} catch (BadLocationException cannotHappen) {
				Assert.isTrue(false);
			}
			restorePositions(editMap);
		} else {
			MultiTextEdit newEdit= new MultiTextEdit(0, document.getLength());
			TextEdit[] replaces= fModifier.getModifications(document.get());
			for (int i= 0; i < replaces.length; i++) {
				newEdit.addChild(replaces[i]);
			}
			try {
				newEdit.apply(document, style);
			} catch (BadLocationException cannotHappen) {
				Assert.isTrue(false);
			}
		}
	}
	
	private TextEdit createEdit(Map editMap) {
		MultiTextEdit result= new MultiTextEdit(0, fSourceRoot.getLength());
		editMap.put(result, fSourceRoot);
		createEdit(fSourceRoot, result, editMap);
		return result;
	}
	
	private static void createEdit(TextEdit source, TextEdit target, Map editMap) {
		TextEdit[] children= source.getChildren();
		for (int i= 0; i < children.length; i++) {
			TextEdit child= children[i];
			// a deleted child remains deleted even if the temporary buffer
			// gets modified.
			if (child.isDeleted())
				continue;
			RangeMarker marker= new RangeMarker(child.getOffset(), child.getLength());
			target.addChild(marker);
			editMap.put(marker, child);
			createEdit(child, marker, editMap);
		}
	}
	
	private void insertEdits(TextEdit root, List edits) {
		while(edits.size() > 0) {
			ReplaceEdit edit= (ReplaceEdit)edits.remove(0);
			insert(root, edit, edits);
		}
	}
	private static void insert(TextEdit parent, ReplaceEdit edit, List edits) {
		if (!parent.hasChildren()) {
			parent.addChild(edit);
			return;
		}
		TextEdit[] children= parent.getChildren();
		// First dive down to find the right parent.
		for (int i= 0; i < children.length; i++) {
			TextEdit child= children[i];
			if (child.covers(edit)) {
				insert(child, edit, edits);
				return;
			} else if (edit.covers(child)) {
				parent.removeChild(i);
				edit.addChild(child);
			} else {
				IRegion intersect= intersect(edit, child);
				if (intersect != null) {
					ReplaceEdit[] splits= splitEdit(edit, intersect);
					insert(child, splits[0], edits);
					edits.add(splits[1]);
				}
			}
		}
		parent.addChild(edit);
	}
		
	public static IRegion intersect(TextEdit op1, TextEdit op2) {
		int offset1= op1.getOffset();
		int length1= op1.getLength();
		int end1= offset1 + length1 - 1;
		int offset2= op2.getOffset();
		if (end1 < offset2)
			return null;
		int length2= op2.getLength();
		int end2= offset2 + length2 - 1;
		if (end2 < offset1)
			return null;
		if (offset1 < offset2) {
			int end= Math.max(end1, end2);
			return new Region(offset2, end - offset2 + 1);
		} else {
			int end= Math.max(end1, end2);
			return new Region(offset1, end - offset1 + 1); 
		}
	}
		
	private static ReplaceEdit[] splitEdit(ReplaceEdit edit, IRegion intersect) {
		if (edit.getOffset() != intersect.getOffset()) {
			return splitIntersectRight(edit, intersect);
		} else {
			return splitIntersectLeft(edit, intersect);
		}
	}
		
	private static ReplaceEdit[] splitIntersectRight(ReplaceEdit edit, IRegion intersect) {
		ReplaceEdit[] result= new ReplaceEdit[2];
		// this is the actual delete. We use replace to only deal with one type
		result[0]= new ReplaceEdit(intersect.getOffset(), intersect.getLength(), ""); //$NON-NLS-1$
		result[1]= new ReplaceEdit(
							edit.getOffset(), 
							intersect.getOffset() - edit.getOffset(), 
							edit.getText());
		return result;
	}
		
	private static ReplaceEdit[] splitIntersectLeft(ReplaceEdit edit, IRegion intersect) {
		ReplaceEdit[] result= new ReplaceEdit[2];
		result[0]= new ReplaceEdit(intersect.getOffset(), intersect.getLength(), edit.getText());
		result[1]= new ReplaceEdit(	// this is the actual delete. We use replace to only deal with one type
							intersect.getOffset() + intersect.getLength(), 
							edit.getLength() - intersect.getLength(),
							""); //$NON-NLS-1$
		return result;
	}
		
	private static void restorePositions(Map editMap) {
		for (Iterator iter= editMap.keySet().iterator(); iter.hasNext();) {
			TextEdit marker= (TextEdit)iter.next();
			TextEdit edit= (TextEdit)editMap.get(marker);
			if (marker.isDeleted()) {
				edit.markAsDeleted();
			} else {
				edit.adjustOffset(marker.getOffset() - edit.getOffset());
				edit.adjustLength(marker.getLength() - edit.getLength());
			}
		}
	}		
}
