/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.range;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.gef.EditPart;
import org.eclipse.jst.pagedesigner.parts.DocumentEditPart;
import org.eclipse.jst.pagedesigner.parts.TextEditPart;
import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
import org.eclipse.jst.pagedesigner.viewer.DesignRange;
import org.eclipse.jst.pagedesigner.viewer.TextPosition;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

/**
 * @author mengbo
 */
public class RangeUtil {
	/**
	 * append the child after the reference node as next sibling.
	 * 
	 * @param child
	 *            can't be null
	 * @param reference
	 *            can't be null
	 */
	public static Node appendAfter(Node child, Node reference) {
		Node next = reference.getNextSibling();
		if (next == null)
			return reference.getParentNode().appendChild(child);
		else
			return reference.getParentNode().insertBefore(child, next);
	}

	public static Node insertBefore(Node child, Node reference) {
		return reference.getParentNode().insertBefore(child, reference);
	}

	/**
	 * Insert a node into the specified position. The node can be an element or
	 * DocumentFragment.
	 * 
	 * @param node
	 * @param position
	 */
	public static Node insertElement(DesignPosition position, Element node) {
		EditPart containerEditPart = position.getContainerPart();
		int offset = position.getOffset();

		if (containerEditPart instanceof TextEditPart) {
			TextEditPart textPart = (TextEditPart) containerEditPart;
			String textData = textPart.getTextData();
			Node textNode = (Node) textPart.getModel();
			if (offset == 0)
				return insertBefore(node, textNode);
			else if (offset == textData.length())
				return appendAfter(node, textNode);
			else {
				// inserting the element in the middle of text.
				String before = textData.substring(0, offset);
				String after = textData.substring(offset);

				// XXX: don't know whether setNodeValue() will do all those
				// escape or not.
				textNode.setNodeValue(after);
				Node newnode = insertBefore(node, textNode);

				// XXX: don't know whether createTextNode() will do all those
				// escape or not
				Text t = textNode.getOwnerDocument().createTextNode(before);

				insertBefore(t, newnode);
				return newnode;
			}
		} else {
			return insertIntoEditPart(containerEditPart, node, offset);
		}
	}

	/**
	 * @param containerEditPart
	 * @param node
	 * @param offset
	 * @return
	 */
	private static Node insertIntoEditPart(EditPart containerEditPart,
			Node node, int offset) {
		Node parent = (Node) containerEditPart.getModel();
		List childParts = containerEditPart.getChildren();
		if (offset >= childParts.size()) {
			// to the end of parent
			return parent.appendChild(node);
		} else {
			Node child = (Node) ((EditPart) childParts.get(offset)).getModel();
			return insertBefore(node, child);
		}
	}

	public static TextPosition insertText(DesignPosition position, String data) {
		EditPart containerEditPart = position.getContainerPart();

		position = moveIntoText(position);
		int offset = position.getOffset();

		if (position.getContainerPart() instanceof TextEditPart) {
			// it is guaranteeed that now the containing edit part is text node.
			TextEditPart textPart = (TextEditPart) position.getContainerPart();
			String textData = textPart.getTextData();
			String before = textData.substring(0, offset);
			String after = textData.substring(offset);
			if (data.startsWith(" ") && before.endsWith(" ")) {
				before = before.substring(0, before.length() - 1) + "&nbsp;";
			}
			if (after.startsWith(" ") && data.endsWith(" ")) {
				data = data.substring(0, data.length() - 1) + (char) 160;
			}
			String nextData = before + data + after;
			IDOMText text = (IDOMText) textPart.getModel();
			text.setData(nextData);
			return new TextPosition(text, offset + data.length());
		} else {
			// can't merge into a neighboring text node. So create a text node
			// of it's own
			EditPart part = position.getContainerPart();
			Node parent = (Node) part.getModel();
			Text text = parent.getOwnerDocument().createTextNode(data);
			insertIntoEditPart(part, text, offset);
			return new TextPosition((IDOMText) text, offset);
		}
	}

	/**
	 * Try to make the position move into a text node.
	 * 
	 * @param position
	 * @return
	 */
	public static DesignPosition moveIntoText(DesignPosition position) {
		EditPart container = position.getContainerPart();
		if (container instanceof TextEditPart)
			return position;
		if (position.getOffset() > 0) {
			EditPart pre = (EditPart) container.getChildren().get(
					position.getOffset() - 1);
			if (pre instanceof TextEditPart) {
				return new DesignPosition(pre, ((TextEditPart) pre)
						.getTextData().length());
			}
		}
		if (position.getOffset() < container.getChildren().size()) {
			EditPart next = (EditPart) container.getChildren().get(
					position.getOffset());
			if (next instanceof TextEditPart) {
				return new DesignPosition(next, 0);
			}
		}
		return position;
	}

	/**
	 * try to move the position up to not inside a text. if the position is at 0
	 * index or last index of a text node, then try to move it up.
	 * 
	 * @param position
	 * @return
	 */
	public static DesignPosition moveOutFromText(DesignPosition position) {
		EditPart container = position.getContainerPart();
		if (container instanceof TextEditPart) {
			int offset = position.getOffset();
			String text = ((TextEditPart) container).getTextData();
			if (offset == 0) {
				return new DesignPosition(container.getParent(), container
						.getParent().getChildren().indexOf(container));
			} else if (offset == text.length()) {
				return new DesignPosition(container.getParent(), container
						.getParent().getChildren().indexOf(container) + 1);
			}
		}
		return position;
	}

	public static void insertDocumentFragment(DesignPosition position,
			DocumentFragment fragment) {
		// FIXME: NOT DONE.
	}

	/**
	 * Test whether the range intersect with the part.
	 * 
	 * @param range
	 * @param part
	 */
	public static boolean intersect(DesignRange range, EditPart part) {
		if (range == null || !range.isValid())
			return false;
		range = normalize(range);
		if (part instanceof DocumentEditPart)
			return true;
		EditPart parent = part.getParent();
		int index = parent.getChildren().indexOf(part);
		DesignPosition left = new DesignPosition(parent, index);
		DesignPosition right = new DesignPosition(parent, index + 1);
		int compare = compareDesignPosition(left, range.getEndPosition());
		if (compare == 1 || compare == 0 || compare == Integer.MIN_VALUE)
			return false;

		compare = compareDesignPosition(right, range.getStartPosition());
		if (compare == -1 || compare == 0 || compare == Integer.MIN_VALUE)
			return false;

		return true;
	}

	/**
	 * make sure the start position is before end position. If the original
	 * range is already normalized, then the original range will be returned
	 * without constructing a new one.
	 * 
	 * @param range
	 * @return
	 */
	public static DesignRange normalize(DesignRange range) {
		if (range == null || !range.isValid()) {
			return range;
		}
		int result = compareDesignPosition(range.getStartPosition(), range
				.getEndPosition());
		if (result == 1)
			return new DesignRange(range.getEndPosition(), range
					.getStartPosition());
		else
			return range;
	}

	/**
	 * 
	 * @param p1
	 * @param p2
	 * @return 0 means equal. 1 Means p1 is after p2. -1 means p1 is before p2.
	 *         Integer.MIN_VALUE means some error and can't compare.
	 */
	public static int compareDesignPosition(DesignPosition p1, DesignPosition p2) {
		if (!p1.isValid() || !p2.isValid())
			return Integer.MIN_VALUE;
		if (p1.equals(p2))
			return 0;
		int offset1 = p1.getOffset();
		int offset2 = p2.getOffset();
		List a1 = getAncesters(p1.getContainerPart());
		List a2 = getAncesters(p2.getContainerPart());
		if (a1 == null || a2 == null)
			return Integer.MIN_VALUE;
		if (a1.get(0) != a2.get(0))
			return Integer.MIN_VALUE; // not same DocumentEditPart
		for (int i = 1;; i++) {
			EditPart p1a = (EditPart) a1.get(i);
			EditPart p2a = (EditPart) a2.get(i);
			if (p1a == p2a) {
				if (p1a != null)
					continue; // same ancester
				else {
					// both are null. just compare the offset.
					return offset1 < offset2 ? -1
							: (offset1 == offset2 ? 0 : 1);
				}
			}
			// p1a != p2a. now we can just compare p1a and p2a to decide the
			// order.
			if (p1a != null)
				offset1 = p1a.getParent().getChildren().indexOf(p1a);
			if (p2a != null)
				offset2 = p2a.getParent().getChildren().indexOf(p2a);
			if ((p1a == null && p2a == null) || (p1a != null && p2a != null)) {
				return offset1 < offset2 ? -1 : (offset1 == offset2 ? 0 : 1);
			} else if (p1a == null) {
				return offset1 <= offset2 ? -1 : 1;
			} else {
				return offset1 >= offset2 ? 1 : -1;
			}
		}
	}

	/**
	 * Get a list of ancester nodes starting from the DocumentEditPart till the
	 * node.
	 * 
	 * @param part
	 * @return
	 */
	private static List getAncesters(EditPart part) {
		List list = new ArrayList();
		while (part != null) {
			list.add(part);
			if (part instanceof DocumentEditPart)
				break;
			else
				part = part.getParent();
		}
		if (part == null) {
			// if part ==null, means we didn't find a DocumentEditPart,
			// something must be wrong.
			return null;
		}
		// reverse to make it starting from the docuemnteditpart node.
		Collections.reverse(list);
		list.add(null); // add an null terminator.
		return list;
	}

	/**
	 * find the smallest common ancester of two edit part.
	 * 
	 * @param part1
	 * @param part2
	 * @return
	 */
	public static EditPart findCommonAncester(EditPart part1, EditPart part2) {
		if (part1 == part2) {
			return part1;
		}
		List list1 = getAncesters(part1);
		if (list1 == null)
			return null;
		List list2 = getAncesters(part2);
		if (list2 == null)
			return null;
		if (list1.get(0) != list2.get(0))
			return null;
		EditPart common = (EditPart) list1.get(0);
		for (int i = 1;; i++) {
			EditPart p1 = (EditPart) list1.get(i);
			EditPart p2 = (EditPart) list2.get(i);
			if (p1 == null || p2 == null)
				return common;
			if (p1 != p2)
				return common;
			common = p1;
		}

	}

	public static EditPart findCommonAncestor(DesignRange range) {
		if (!range.isValid()) {
			return null;
		}
		DesignPosition startPosition = range.getStartPosition();
		DesignPosition endPosition = range.getEndPosition();
		return findCommonAncester(startPosition.getContainerPart(), endPosition
				.getContainerPart());
	}
}
