/*******************************************************************************
 * 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.dom;

import java.util.List;

import org.eclipse.gef.EditPart;
import org.eclipse.jface.text.Assert;
import org.eclipse.jst.pagedesigner.parts.TextEditPart;
import org.eclipse.jst.pagedesigner.utils.HTMLUtil;
import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
import org.eclipse.jst.pagedesigner.viewer.DesignRefPosition;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

/**
 * @author mengbo
 */
public class DOMPositionHelper {
	public static DesignPosition toDesignRefPosition(DOMRefPosition position) {
		Node node = position.getReferenceNode();
		do {
			IDOMNode container = (IDOMNode) node.getParentNode();
			EditPart part = (EditPart) container.getAdapterFor(EditPart.class);
			if (part != null) {
				// XXX: what if the node has not corresponding part?
				EditPart child = DOMPositionHelper.findEditPart(part, node);
				if (child != null) {
					return new DesignRefPosition(child, position.isForward());
				} else {
					return DesignPosition.INVALID;
				}
			} else {
				node = node.getParentNode();
			}
		} while (true);
	}

	/**
	 * 
	 * @param position
	 *            if it is null, then will return null
	 * @return null if position is null or invalid.
	 */
	public static DesignPosition toDesignPosition(IDOMPosition position) {
		if (position == null) {
			return null;
		}
		if (position instanceof DOMRefPosition) {
			return toDesignRefPosition((DOMRefPosition) position);
		}
		do {
			IDOMNode container = (IDOMNode) position.getContainerNode();
			EditPart part = (EditPart) container.getAdapterFor(EditPart.class);
			if (part != null) {
				if (container instanceof Text) {
					String textData = ((Text) container).getData();
					String displayData = ((TextEditPart) part).getTextData();
					return new DesignPosition(part,
							textDataOffsetToDisplayOffset(textData,
									displayData, position.getOffset()));
				} else {
					Node pre = position.getPreviousSiblingNode();
					while (pre != null) {
						int index = findChildEditPartIndex(part, pre);
						if (index != -1) {
							return new DesignPosition(part, index + 1);
						}
						pre = pre.getPreviousSibling();
					}
					return new DesignPosition(part, 0);
				}
			} else {
				position = new DOMRefPosition(position.getContainerNode(),
						false);
			}
		} while (true);
	}

	/**
	 * Here is the position is not currect, currently it will returns invalid
	 * pos.
	 * 
	 * @param position
	 * @return
	 */
	public static DesignPosition toDesignPosition1(IDOMPosition position) {
		if (position instanceof DOMRefPosition) {
			return toDesignRefPosition((DOMRefPosition) position);
		}
		do {
			IDOMNode container = (IDOMNode) position.getContainerNode();
			EditPart part = (EditPart) container.getAdapterFor(EditPart.class);
			if (part != null) {
				if (container instanceof Text) {
					String textData = ((Text) container).getData();
					String displayData = ((TextEditPart) part).getTextData();
					return new DesignPosition(part,
							textDataOffsetToDisplayOffset(textData,
									displayData, position.getOffset()));
				} else {
					Node pre = position.getPreviousSiblingNode();
					while (pre != null) {
						int index = findChildEditPartIndex(part, pre);
						if (index != -1) {
							return new DesignPosition(part, index + 1);
						}
						pre = pre.getPreviousSibling();
					}
					return new DesignPosition(part, 0);
				}
			} else {
				return DesignPosition.INVALID;
			}
		} while (true);
	}

	static int findChildEditPartIndex(EditPart parent, Node node) {
		List children = parent.getChildren();
		for (int i = 0; i < children.size(); i++) {
			if (((EditPart) children.get(i)).getModel() == node) {
				return i;
			}
		}
		return -1;
	}

	static EditPart findEditPart(EditPart parent, Node node) {
		List children = parent.getChildren();
		EditPart part;
		for (int i = 0; i < children.size(); i++) {
			if ((part = (EditPart) children.get(i)).getModel() == node) {
				return part;
			}
		}
		return null;
	}

	/**
	 * convert a DesignPosition into DOMPosition.
	 * 
	 * @param position
	 * @return
	 */
	public static IDOMPosition toDOMRefPosition(DesignRefPosition position) {
		// ok, it is not text.
		EditPart sibling = position.getRefPart();
		if (sibling != null) {
			return new DOMRefPosition((Node) sibling.getModel(), position
					.caretIsAtRight());
		}
		// should never happens
		Assert.isTrue(false);
		return null;
	}

	/**
	 * convert a DesignPosition into DOMPosition.
	 * 
	 * @param position
	 * @return
	 */
	public static IDOMPosition toDOMPosition(DesignPosition position) {
		if (!EditValidateUtil.validPosition(position)) {
			return null;
		} else if (position instanceof DesignRefPosition) {
			return toDOMRefPosition((DesignRefPosition) position);
		}
		EditPart part = position.getContainerPart();
		if (part instanceof TextEditPart) {
			Text text = (Text) ((TextEditPart) part).getIDOMNode();
			int offset = position.getOffset();
			if (offset == 0) {
				return new DOMPosition(text, 0);
			} else {
				String displayData = ((TextEditPart) part).getTextData();
				String nodeData = text.getData();
				if (offset >= displayData.length()) {
					// point to end of the text node.
					return new DOMPosition(text, nodeData.length());
				} else {
					// we need to calculate it out.
					int index = displayOffsetToTextDataOffset(displayData,
							nodeData, offset);
					return new DOMPosition(text, index);
				}
			}
		} else {
			// ok, it is not text.
			EditPart sibling = position.getSiblingEditPart(true);
			if (sibling != null) {
				return new DOMRefPosition((Node) sibling.getModel(), false);
			}

			sibling = position.getSiblingEditPart(false);
			if (sibling != null) {
				return new DOMRefPosition((Node) sibling.getModel(), true);
			}

			// no previous sibling, no next sibling, the parent node must be
			// empty
			return new DOMPosition((Node) part.getModel(), 0);
		}
	}

	/**
	 * if "position" is inside a text node, then split the text node and return
	 * a new IDOMPosition semantically equals to the position in the two
	 * splitted text. If the "position" is not a text position, then no action
	 * will be done.
	 * 
	 * @param position
	 * @return
	 */
	public static IDOMPosition splitText(IDOMPosition position) {
		Node container = position.getContainerNode();
		if (container instanceof Text) {
			int offset = position.getOffset();
			if (offset <= 0) {
				// at beginning of text node. no need to split
				return new DOMRefPosition(container, false);
			}
			String textData = ((Text) container).getData();
			if (offset >= textData.length()) {
				// at end of text node. no need to split
				return new DOMRefPosition(container, true);
			}
			// ok, we need split
			((Text) container).splitText(offset);
			return new DOMRefPosition(container, true);
		} else
			return position;
	}

	/**
	 * Remove all the content in the range. And return the new position.
	 * 
	 * @param range
	 * @return
	 */
	public static IDOMPosition removeRange(DOMRange range) {
		boolean ordered = range.isOrdered();
		IDOMPosition start = ordered ? range.getStartPosition() : range
				.getEndPosition();
		IDOMPosition end = ordered ? range.getEndPosition() : range
				.getStartPosition();

		// FIXME: Not DONE:
		return end;
	}

	/**
	 * try to merge the position in adjacent text node (if it is not already in)
	 * 
	 * @param position
	 * @return
	 */
	public static IDOMPosition mergeIntoText(IDOMPosition position) {
		if (position.getContainerNode() instanceof Text)
			return position;
		Node pre = position.getPreviousSiblingNode();
		if (pre instanceof Text) {
			return new DOMPosition(pre, ((Text) pre).getData().length());
		}
		Node after = position.getNextSiblingNode();
		if (after instanceof Text) {
			return new DOMPosition(after, 0);
		}
		return position;
	}

	/**
	 * @param displayData
	 * @param nodeData
	 * @param offset
	 * @return
	 */
	// FIXME: this method is still buggy
	public static int displayOffsetToTextDataOffset(String displayData,
			String nodeData, int offset) {
		char[] display = displayData.toCharArray();
		if (offset >= display.length) {
			// offset is already at end
			return nodeData.length();
		}
		char[] node = nodeData.toCharArray();
		int nodeDataLength = node.length;
		int displayIndex = 0;
		int nodeIndex = 0;

		while (displayIndex < offset && nodeIndex < nodeDataLength) {
			if (display[displayIndex] == node[nodeIndex]) {
				displayIndex++;
				nodeIndex++;
				continue;
			}
			if (HTMLUtil.isHTMLWhitespace(node[nodeIndex])) {
				if (HTMLUtil.isHTMLWhitespace(display[displayIndex])) {
					displayIndex++;
					nodeIndex++;
				} else {
					nodeIndex++;
				}
				continue;
			} else {
				// should not happen!
				displayIndex++;
				nodeIndex++;
			}
		}

		if (nodeIndex >= nodeDataLength)
			return nodeDataLength;
		// else means displayIndex == offset
		// since we already checked that offset < displayLength, so we can get
		// the next char
		if (display[offset] != ' ') {
			// we may need to skip whitespaces after nodeIndex
			while (nodeIndex < nodeDataLength
					&& HTMLUtil.isHTMLWhitespace(node[nodeIndex])) {
				nodeIndex++;
			}
		}
		return nodeIndex;
	}

	/**
	 * @param textData
	 * @param displayData
	 * @param offset
	 * @return
	 */
	// FIXME: this method is still buggy
	public static int textDataOffsetToDisplayOffset(String nodeData,
			String displayData, int offset) {
		if (offset >= nodeData.length()) {
			return displayData.length();
		}
		char[] node = nodeData.toCharArray();
		char[] display = displayData.toCharArray();

		int displayIndex = 0;
		int nodeIndex = 0;
		int displayDataLength = display.length;

		while (nodeIndex < offset && displayIndex < displayDataLength) {
			if (display[displayIndex] == node[nodeIndex]) {
				displayIndex++;
				nodeIndex++;
				continue;
			}
			if (HTMLUtil.isHTMLWhitespace(node[nodeIndex])) {
				if (HTMLUtil.isHTMLWhitespace(display[displayIndex])) {
					displayIndex++;
					nodeIndex++;
				} else {
					nodeIndex++;
				}
				continue;
			} else {
				// should not happen!
				displayIndex++;
				nodeIndex++;
			}
		}
		return displayIndex;
	}

	/**
	 * Convert a IDOMPosition to IDOMRefPosition. If can't convert to
	 * IDOMRefPosition, will return the original one.
	 * 
	 * @param position
	 * @return
	 */
	public static IDOMPosition toDOMRefPosition(IDOMPosition position) {
		if (position.isText()) {
			return position; // can't convert Text node.
		}
		if (position instanceof IDOMRefPosition) {
			return position;
		}
		if (position.getNextSiblingNode() != null) {
			return new DOMRefPosition(position.getNextSiblingNode(), false);
		}
		if (position.getPreviousSiblingNode() != null) {
			return new DOMRefPosition(position.getPreviousSiblingNode(), true);
		} else {
			return new DOMRefPosition2(position.getContainerNode(), true);
		}
	}
}
