/*******************************************************************************
 * 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.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
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;

	public final static int OUT_OF_LEFT = 1;

	public final static int LEFT_NAME = 2;

	public final static int IN_MIDDLE = 3;

	public final static int RIGHT_NAME = 4;

	public final static int OUT_OF_RIGHT = 5;

	public 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
	 */
	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;

	}

	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
	 */
	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 operation
	 * @param currentPosition
	 * @param forward
	 * @param validator
	 * @return
	 */
	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
	 */
	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
	 */
	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 forward
	 * @return
	 */
	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
	 */
	public static IDOMPosition ensureDOMPosition(IDOMPosition position) {
		if (position instanceof DOMRefPosition) {
			return new DOMPosition(position.getContainerNode(), position
					.getOffset());
		}
		return position;
	}

	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));
		}
	}

	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));
					}
				}
			}
		}
	}

	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());
//		}
//	}

	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;
	}

	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)) {
								((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;
	}

	/*
	 * 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;
	}

	public static EditPart getPart(Node node) {
		if (node instanceof INodeNotifier) {
			((INodeNotifier) node).getAdapterFor(EditPart.class);
		}
		return null;
	}
}
