/*******************************************************************************
 * 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 java.util.Stack;

import org.eclipse.core.runtime.Assert;
import org.eclipse.gef.EditPart;
import org.eclipse.jst.pagedesigner.IHTMLConstants;
import org.eclipse.jst.pagedesigner.commands.range.WorkNode;
import org.eclipse.jst.pagedesigner.parts.TextEditPart;
import org.eclipse.jst.pagedesigner.utils.HTMLUtil;
import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
import org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator;
import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingNavigationMediator;
import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
import org.eclipse.jst.pagedesigner.viewer.DesignRefPosition;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * @author mengbo
 */
public class EditHelper {
//	public final static boolean INNER_DEBUG = false;

	private final static int OUT_OF_LEFT = 1;

	private final static int LEFT_NAME = 2;

	/**
	 * indicates a position in the middle
	 */
	public final static int IN_MIDDLE = 3;

	private final static int RIGHT_NAME = 4;

	private final static int OUT_OF_RIGHT = 5;

	private static final EditHelper _instance = new EditHelper();

	//private static Logger _log = PDPlugin.getLogger(EditHelper.class);

	private EditHelper() {
        //  no external instantiation
	}

	/**
	 * Move operation position infront of next non-blank and non-transparent
	 * char. The caller should ensure position's container node is not
	 * tranparent text node.
	 * 
	 * @param position
	 * @param forward
	 * @param forEmpty
	 * @return the offset
	 */
	public int getTextNextOffset(IDOMPosition position, boolean forward,
			boolean forEmpty) {
		EditValidateUtil.validPosition(position);
		Assert.isTrue(!EditModelQuery.isTransparentText(position
				.getContainerNode()));
		Text text = (Text) position.getContainerNode();
		int offset = position.getOffset();
		String data = text.getNodeValue();
		if (forward) {
			while (offset < data.length()
					&& HTMLUtil.isHTMLWhitespace(data.charAt(offset))) {
				offset++;
			}
		} else {
			while (offset > 0
					&& HTMLUtil.isHTMLWhitespace(data.charAt(offset - 1))) {
				offset--;
			}
		}
		return offset;

	}

	/**
	 * @return the singleton instance
	 */
	public static EditHelper getInstance() {
		return _instance;
	}

	/**
	 * This caret from current operation postion to next position, this method
	 * will convert DesignPosition in to DOMPosition, then call dom function to
	 * move dom position. Here we might insert some complex rules to see whether
	 * move is valid.
	 * 
	 * @param action
	 * @param currentPosition
	 * @param forward
	 * @return the dom position
	 */
	public static DesignPosition moveToNextEditPosition(int action,
			DesignPosition currentPosition, boolean forward) {
		IDOMPosition position;
		position = DOMPositionHelper.toDOMPosition(currentPosition);
		position = moveToNextEditPosition(position, forward,
				new InlineEditingNavigationMediator(
						new ActionData(action, null)));
		if (position == null) {
			return currentPosition;
		}

		EditValidateUtil.validPosition(position);
		return DOMPositionHelper.toDesignPosition(position);
	}

	/**
	 * Move operation position to next edit position. We may need rule to valid
	 * it based on operation ID and direction. We need to pack transparent
	 * string.
	 * 
	 * @param currentPosition
	 * @param forward
	 * @param validator
	 * @return the dom position
	 */
	public static IDOMPosition moveToNextEditPosition(
			IDOMPosition currentPosition, boolean forward,
			IMovementMediator validator) {
		IDOMPosition result = null;
		CaretMoveIterator moveIterator = new CaretMoveIterator(null, validator,
				currentPosition, forward);
		if ((result = moveIterator.moveToNextEditPosition(currentPosition,
				forward, validator)) == null) {
			result = currentPosition;
		}
		return result;
	}

	/**
	 * Delete a node, in case it is 'body' or 'html', it won't perform delete.
	 * 
	 * @param node
	 * @return the node
	 */
	public static Node deleteNode(Node node) {
		if (node == null || node.getNodeName() == null) {
			return null;
		}
		String name = node.getLocalName();

		if (name != null
				&& (name.equalsIgnoreCase(IHTMLConstants.TAG_BODY)
						|| name.equalsIgnoreCase(IHTMLConstants.TAG_HEAD) || name
						.equalsIgnoreCase(IHTMLConstants.TAG_HTML))) {
			return null;
		}
		Node parent = node.getParentNode();
		name = parent.getNodeName();
		if (parent != null
				&& name != null
				&& parent.getNodeName().equalsIgnoreCase(
						IHTMLConstants.TAG_HEAD)) {
			return null;
		}
		return parent.removeChild(node);
	}

	/**
	 * Order the IDOMPositions in a range in ascending order.
	 * 
	 * @param range
	 * @return the dom range
	 */
	public static DOMRange normal(DOMRange range) {
		EditValidateUtil.validRange(range);
		IDOMPosition p1 = range.getStartPosition();
		IDOMPosition p2 = range.getEndPosition();
		if (EditModelQuery.getIndexedRegionLocation(p1) > EditModelQuery
				.getIndexedRegionLocation(p2)) {
			return new DOMRange(p2, p1);
		}
        return range;
	}

	/**
	 * Move position in to node from its outside, the node should be breakble.
	 * 
	 * @param node
	 * @param validator 
	 * @param forward
	 * @return the dom position
	 */
	public static IDOMPosition moveInto(Node node, IMovementMediator validator,
			boolean forward) {
		CaretMoveIterator moveIterator = new CaretMoveIterator(null, validator,
				new DOMRefPosition(node, !forward), forward);
		return moveIterator.moveIn(node);
	}

	/**
	 * Convert a DomRefPosition into DOMPosition.
	 * 
	 * @param position
	 * @return the dom position
	 */
	public static IDOMPosition ensureDOMPosition(IDOMPosition position) {
		if (position instanceof DOMRefPosition) {
			return new DOMPosition(position.getContainerNode(), position
					.getOffset());
		}
		return position;
	}

	/**
	 * @param currentNode
	 * @param pos1
	 * @param pos2
	 * @param top
	 * @param workNode
	 */
	public void processText(Text currentNode, final int pos1, final int pos2,
			Node top, Stack workNode) {
		// the text could be tranparent, or 0 length.
		Assert.isTrue(pos1 <= pos2);
		if (pos1 == pos2) {
			return;
		}
		// int left = EditModelQuery.getNodeStartIndex(currentNode);
		// int right = EditModelQuery.getNodeEndIndex(currentNode);
		int location1 = getLocation(currentNode, pos1, false);
		int location2 = getLocation(currentNode, pos2, false);
		if (location1 <= IN_MIDDLE && location2 >= IN_MIDDLE) {
			workNode.push(new WorkNode(currentNode, pos1, pos2));
		}
	}

	/**
	 * @param currentNode
	 * @param pos1
	 * @param pos2
	 * @param top
	 * @param result
	 */
	public void collectNodes(Node currentNode, final int pos1, final int pos2,
			Node top, Stack result) {
		Assert.isTrue(pos1 <= pos2);
		if (pos1 == pos2) {
			return;
		}
		if (EditModelQuery.isText(currentNode)) {
			processText((Text) currentNode, pos1, pos2, top, result);
		} else {
			int location1 = getLocation(currentNode, pos1, false);
			int location2 = getLocation(currentNode, pos2, false);
			if (location1 < IN_MIDDLE && location2 > IN_MIDDLE) {
				// TODO: push the node into result.--
				result.push(new WorkNode(currentNode, pos1, pos2));
			} else if (location1 <= IN_MIDDLE && location2 >= IN_MIDDLE) {
				if (currentNode.hasChildNodes()) {
					Node child = currentNode.getFirstChild();
					Stack myResult = new Stack();
					while (child != null) {
						collectNodes(child, pos1, pos2, top, myResult);
						child = child.getNextSibling();
					}
					if (location1 < IN_MIDDLE && location2 >= IN_MIDDLE
							|| location1 <= IN_MIDDLE && location2 > IN_MIDDLE) {
						WorkNode workNode = new WorkNode(currentNode, pos1,
								pos2);
						while (myResult.size() > 0) {
							WorkNode w = (WorkNode) myResult.remove(0);
							if (w.getNode().getParentNode() == workNode
									.getNode()) {
								w.setParent(workNode);
							}
							result.push(w);
						}
						// TODO: push parent into result.--
						result.push(workNode);
					}
				} else {
					if (!(location1 == IN_MIDDLE && location2 == IN_MIDDLE)) {
						// TODO: push this node into result.
						result.push(new WorkNode(currentNode, pos1, pos2));
					}
				}
			}
		}
	}

	/**
	 * @param currentNode
	 * @param pos
	 * @param isOffset
	 * @return the location
	 */
	public int getLocation(Node currentNode, int pos, boolean isOffset) {
		if (EditModelQuery.getInstance().isSingleRegionNode(currentNode)) {
			// if (EditModelQuery.isText(currentNode))
			{

				int left = EditModelQuery.getNodeStartIndex(currentNode);
				int right = EditModelQuery.getNodeEndIndex(currentNode);
				if (isOffset) {
					pos += left;
				}
				if (pos <= left) {
					return OUT_OF_LEFT;
				} else if (left < pos && pos < right) {
					return IN_MIDDLE;
				} else {
					return OUT_OF_RIGHT;
				}
			}
		}
        int left = EditModelQuery.getNodeStartIndex(currentNode);
        int left1 = EditModelQuery.getNodeStartNameEndIndex(currentNode);
        int right = EditModelQuery.getNodeEndNameStartIndex(currentNode);
        int right1 = EditModelQuery.getNodeEndIndex(currentNode);
        if (isOffset) {
        	pos += left;
        }
        if (pos <= left) {
        	return OUT_OF_LEFT;
        } else if (left < pos && pos < left1) {
        	return LEFT_NAME;
        } else if (left1 <= pos && pos <= right) {
        	return IN_MIDDLE;
        } else if (right < pos && pos < right1) {
        	return RIGHT_NAME;
        } else {
        	return OUT_OF_RIGHT;
        }

	}

    // TODO: dead?
//	private Node cutCurrentNode(int pos[], Node currentNode,
//			IDOMPosition position) {
//		// at right edge
//		int curpos = EditModelQuery.getIndexedRegionLocation(position);
//		if (pos[0] <= curpos) {
//			pos[1] = EditModelQuery.getNodeStartIndex(currentNode);
//			currentNode = deleteNode(currentNode);
//			if (INNER_DEBUG) {
//				_log.info("cut:" + currentNode);
//			}
//			return currentNode;
//		} else if (pos[1] >= curpos) {
//			pos[0] = EditModelQuery.getNodeEndIndex(currentNode);
//			currentNode = deleteNode(currentNode);
//			if (INNER_DEBUG) {
//				_log.info("cut:" + currentNode);
//			}
//			return currentNode;
//		}
//		return null;
//	}

    //TODO: dead?
//	private int getPos(DOMRange range, boolean forStart) {
//		if (forStart) {
//			return EditModelQuery.getIndexedRegionLocation(range
//					.getStartPosition());
//		} else {
//			return EditModelQuery.getIndexedRegionLocation(range
//					.getEndPosition());
//		}
//	}

	/**
	 * @param position
	 * @param forward
	 * @return the edit part for position
	 */
	public EditPart getEditPart(DesignPosition position, boolean forward) {
		if (position instanceof DesignRefPosition) {
			return ((DesignRefPosition) position).getRefPart();
		}
		EditPart container = position.getContainerPart();
		if (container instanceof TextEditPart) {
			return container;
		}
		if (container != null) {
			List children = container.getChildren();
			for (int i = 0, n = children.size(); i < n; i++) {
				if (i == position.getOffset()) {
					int index = (forward) ? i - 1 : i + 1;
					if (index < 0) {
						index = 0;
					}
					if (index >= children.size()) {
						index = children.size() - 1;
					}

					return (EditPart) children.get(index);
				}
			}
		}
		return null;
	}

	/**
	 * @param position
	 * @return the resulting dom position
	 */
	public static IDOMPosition splitNode(IDOMPosition position) {
		if (EditValidateUtil.validPosition(position)) {
			Node container = null;
			// Avoid to split tag at its edge
			if (position.getOffset() > 0) {
				if (position.isText()) {
					container = position.getContainerNode();
					if (position.getOffset() < ((Text) container).getLength()) {
						position = DOMPositionHelper.splitText(position);
					} else {
						// position = new
						// DOMRefPosition(position.getContainerNode(), true);
					}
				} else {
					if (position.getNextSiblingNode() != null) {
						container = position.getContainerNode();
						Node parent = container.getParentNode();

						Document document = EditModelQuery
								.getDocumentNode(container);
						Node newContainer = document.createElement(container
								.getNodeName());
						Node node = position.getPreviousSiblingNode();
						Node refNode = null;
						while (node != null) {
							Node prev = node.getPreviousSibling();
							node = node.getParentNode().removeChild(node);

							newContainer.insertBefore(node, refNode);
							refNode = node;
							node = prev;
						}
						parent.insertBefore(newContainer, container);
						// set the newContainer node align attribute to the
						// original align attribue
						// copy nodes under container node to container node's
						// parent node
						if (container.getNodeName().equalsIgnoreCase(
								IHTMLConstants.TAG_P)) {
							Element pNode = (Element) container;
							String align = pNode
									.getAttribute(IHTMLConstants.ATTR_ALIGN);
							if (align != null && !"".equalsIgnoreCase(align)) { //$NON-NLS-1$
								((Element) newContainer).setAttribute(
										IHTMLConstants.ATTR_ALIGN, align);
							}
							NodeList nodeList = pNode.getChildNodes();
							for (int i = 0, size = nodeList.getLength(); i < size; i++) {
								Node tempNode = nodeList.item(i);
								parent.insertBefore(tempNode, container);
							}
						}
						return new DOMRefPosition(newContainer, true);
					}
//                    position = new
//                    DOMRefPosition(position.getContainerNode(), true);
				}
			} else {
				// container = position.getContainerNode();
				// position = new DOMRefPosition(container, false);
			}
		}
		return position;
	}

	/**
	 * @param position 
	 * @return the position of this 'position' in relative to it's container.
	 */
	public static int getLocation(IDOMPosition position) {
		if (position.getOffset() == 0) {
			return -1;
		}
        if (position.isText()) {
        	if (position.getOffset() == ((Text) position.getContainerNode())
        			.getLength()) {
        		return 1;
        	}
            return 0;
        }
        if (position.getOffset() == position.getContainerNode()
        		.getChildNodes().getLength()) {
        	return 1;
        }
        return 0;
	}
}
