/*******************************************************************************
 * 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.core.runtime.Assert;
import org.eclipse.gef.EditPart;
import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
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());
				}
                return DesignPosition.INVALID;
			}
            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()));
				}
                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);
			}
            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()));
				}
                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);
			}
            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);
			}
            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());
            }
            // we need to calculate it out.
            int index = displayOffsetToTextDataOffset(displayData,
            		nodeData, offset);
            return new DOMPosition(text, index);
		}
        // ok, it is not text.
        EditPart sibling = position.getSiblingEditPart(true);
        if (sibling instanceof NodeEditPart) {
        	return new DOMRefPosition(((NodeEditPart) sibling).getDOMNode(), false);
        }

        sibling = position.getSiblingEditPart(false);
        if (sibling instanceof NodeEditPart) {
        	return new DOMRefPosition(((NodeEditPart) sibling).getDOMNode(), true);
        }

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

	/**
	 * if "position" is inside a text node, then split the text node and return
	 * a new IDOMPosition semantically equal to the position in the two
	 * splitted text. If the "position" is not a text position, then no action
	 * will be taken and will return the original position.
	 * 
	 * @param position
	 * @return IDOMPosition
	 */
	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);
		}
        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;
			}
            // 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;
			}
            // 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 IDOMPosition
	 */
	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);
		}
        return new DOMRefPosition2(position.getContainerNode(), true);
	}
}
