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

import java.util.ArrayList;
import java.util.Comparator;

import javax.xml.namespace.QName;

import org.eclipse.jst.pagedesigner.IJMTConstants;
import org.eclipse.jst.pagedesigner.adapters.IBodyInfo;
import org.eclipse.jst.pagedesigner.adapters.internal.BodyInfo;
import org.eclipse.jst.pagedesigner.dom.DOMPosition;
import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
import org.eclipse.jst.pagedesigner.dom.DOMRefPosition2;
import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * This class helps location insertion position to inside correct body or doc
 * prefix. NOTE: this class only doing limited support on doc level position
 * validation. Element specific position validation will be done in other
 * places.
 * 
 * @author mengbo
 */
public class BodyHelper {
	// bit flags used for child skipping.
	public static final int EMPTY_TEXT = 1;

	public static final int COMMENT = 2;

	public static final int HEADER = 3;

	/**
	 * 
	 * @param child
	 * @return
	 */
	private static boolean isSkippableChild(Node parent, Node child, int flag) {
		if ((flag & COMMENT) != 0 && child.getNodeType() == Node.COMMENT_NODE)
			return true;
		if ((flag & EMPTY_TEXT) != 0 && child instanceof IDOMText
				&& ((IDOMText) child).isElementContentWhitespace())
			return true;

		if ((flag & HEADER) != 0 && child.getNodeType() == Node.ELEMENT_NODE) {
			String uri = CMUtil.getElementNamespaceURI((Element) child);
			IBodyInfo parentInfo = getBodyInfo((IDOMNode) parent);
			if (parentInfo != null
					&& parentInfo.isBodyHeader((IDOMNode) parent, uri,
							((Element) child).getLocalName()))
				return true;
		}
		return false;
	}

	/**
	 * check whether uri/tag should be header of any body container that is
	 * ancester of the start node.
	 * 
	 * @param start
	 * @param uri
	 * @param tag
	 * @return
	 */
	public static IDOMNode findHeaderContainer(IDOMNode start, String uri,
			String tag) {
		while (start != null) {
			IBodyInfo designInfo = getBodyInfo(start);
			if (designInfo != null && designInfo.isBodyContainer(start)) {
				if (designInfo.isBodyHeader(start, uri, tag))
					return start;
			}
			start = (IDOMNode) start.getParentNode();
		}
		return null;
	}

	/**
	 * find the closest body insertion point, to make it as deep as possible.
	 * (Move into as more body as possible)
	 * 
	 * @param parent
	 * @param start
	 */
	public static IDOMPosition findBodyInsertLocation(IDOMPosition position) {
		// forward first.
		Node reference = position.getNextSiblingNode();
		Node container = position.getContainerNode();
		while (reference != null) {
			IBodyInfo info = getBodyInfo((IDOMNode) reference);
			if (info != null && info.isBodyContainer((IDOMNode) reference)) {
				// good, we find a body!
				position = new DOMPosition(reference, 0);
				return findBodyInsertLocation(position);
			}
			if (isSkippableChild(container, reference, EMPTY_TEXT | COMMENT
					| HEADER)) {
				reference = reference.getNextSibling();
				continue;
			} else
				break;
		}

		// backward
		reference = position.getPreviousSiblingNode();
		while (reference != null) {
			IBodyInfo info = getBodyInfo((IDOMNode) reference);
			if (info != null && info.isBodyContainer((IDOMNode) reference)) {
				// good, we find a body!
				position = new DOMPosition(reference, reference.getChildNodes()
						.getLength());
				return findBodyInsertLocation(position);
			}
			// XXX: not skip header here. So if there is some header with wrong
			// location, we will respect user.
			if (isSkippableChild(container, reference, EMPTY_TEXT | COMMENT)) {
				reference = reference.getPreviousSibling();
				continue;
			} else
				break;
		}

		// not find any body at same level as the insertion point.
		return position;
	}

	/**
	 * The element type identifiered by "uri" and "tag" is going to be inserted
	 * into the document. This method is used to adjust the insert position so
	 * it can be put into correct body or header section.
	 * 
	 * @param parent
	 * @param reference
	 */
	public static IDOMPosition adjustInsertPosition(String uri, String tag,
			IDOMPosition position) {
		IDOMNode parent = (IDOMNode) position.getContainerNode();
		IBodyInfo designInfo = getBodyInfo(parent);
		if (designInfo == null) {
			return position; // should not happen.
		}

		IDOMNode headerContainer = findHeaderContainer(parent, uri, tag);

		if (headerContainer == null) {
			// the new node is not header.
			if (shouldIgnoreAdjust(uri, tag)) {
				return position;
			}

			// new node is not body header. So should inside the inner most
			// body.
			if (!designInfo.isBodyContainer(parent)) {
				return position; // it's parent is not body, so we suggest
				// it's parent already correctly located, and respect user's
				// choice.
			}

			// ok, we are inside some body, but we don't know whether we are in
			// the inner most body.
			// try to find a body container at same level and see whether we can
			// move into that body.
			return findBodyInsertLocation(position);
		} else {
			// good, we find a body container and the new node should be header
			// of it.
			Node child = headerContainer.getFirstChild();
			Node refNode = position.getNextSiblingNode();
			// if parent is different from headerContainer, then
			// child!=referenceHolder[0] will always be true
			while (child != null) // && child != refNode)
			{
				Comparator comp = NodeLocationComparator.getInstance();
				// Currently the comparator deels with tags like taglib and
				// loadbundle particularly, comparasion result 0
				// means it didn't compare the tags.
				if (comp.compare(child, tag) < 0
						|| (comp.compare(child, tag) == 0 && isSkippableChild(
								headerContainer, child, COMMENT | EMPTY_TEXT
										| HEADER))) {
					child = child.getNextSibling();
				} else {
					break;
				}
			}
			if (child != null) {
				return new DOMRefPosition(child, false);
			} else {
				return new DOMPosition(parent, parent.getChildNodes()
						.getLength());
			}
			// parentHolder[0] = headerContainer;
			// referenceHolder[0] = child;
			// return;
		}
	}

	/**
	 * Find the position to insert a header element into the specified parent.
	 * 
	 * @param uri
	 * @param tag
	 * @param parent
	 */
	public static void findHeaderInsertPosition(String uri, String tag,
			Node parent, Node[] ref) {
		Node child = parent.getFirstChild();
		while (child != null) {
			Comparator comp = NodeLocationComparator.getInstance();
			if (comp.compare(child, tag) < 0
					|| (comp.compare(child, tag) == 0 && isSkippableChild(
							parent, child, COMMENT | EMPTY_TEXT | HEADER))) {
				child = child.getNextSibling();
			} else {
				break;
			}
		}
		ref[0] = child;
		return;
	}

	public static IDOMPosition insertBody(IDOMPosition position, QName body,
			String defaultPrefix) {
		IBodyInfo bodyInfo = getBodyInfo((IDOMNode) position.getContainerNode());

		Node node = position.getContainerNode();
		Node originalContainer = node;
		Node nextSibling = position.getNextSiblingNode();

		// create the body element first.
		Document ownerDoc;
		if (node instanceof Document) {
			ownerDoc = (Document) node;
		} else {
			ownerDoc = node.getOwnerDocument();
		}
		if (ownerDoc == null) {
			return null; // should not happen
		}

		String prefix = JSPUtil.getOrCreatePrefix(((IDOMNode) node).getModel(),
				body.getNamespaceURI(), defaultPrefix);
		Element ele = ownerDoc.createElement((prefix == null ? ""
				: (prefix + ":"))
				+ body.getLocalPart());

		// need to find out the insertion point
		while (node instanceof IDOMNode) {
			if (bodyInfo.isBodyContainer((IDOMNode) node)) {
				// ok, node is a body container.
				// we could create the new node as child of node and move all
				// node's none header children
				// as children of the new node.

				NodeList nl = node.getChildNodes();
				ArrayList list = new ArrayList();
				for (int i = 0; i < nl.getLength(); i++) {
					Node child = (Node) nl.item(i);
					if (isSkippableChild(node, child, HEADER | COMMENT
							| EMPTY_TEXT)) {
						continue;
					}
					list.add(nl.item(i));
				}
				for (int i = 0; i < list.size(); i++) {
					ele.appendChild((Node) list.get(i));
				}
				node.appendChild(ele);

				if (node == originalContainer) {
					if (nextSibling == null) {
						return new DOMRefPosition2(ele, true);
					} else if (nextSibling.getParentNode() == ele) {
						// next sibling is not in header part
						return new DOMRefPosition(nextSibling, false);
					} else {
						return new DOMPosition(ele, 0);
					}
				} else {
					return position;
				}
			}
			node = node.getParentNode();
		}
		// should not happen, because document and documentfragment node will
		// always be body node
		// so if reach here, means the position is not in document.
		return null;
	}

	/**
	 * For certain special tags, do not following the "header"/"body" separation
	 * and can't fit into the relocation process.
	 * 
	 * @param uri
	 * @param tag
	 * @return
	 */
	public static boolean shouldIgnoreAdjust(String uri, String tag) {
		// FIXME:
		return (IJMTConstants.URI_HTML.equals(uri) && "script"
				.equalsIgnoreCase(tag))
				|| (IJMTConstants.URI_JSP.equals(uri));
	}

	public static IBodyInfo getBodyInfo(IDOMNode node) {
		// TODO: in the future, when bodyinfo is no longer singleton, we'll use
		// adapter mechanism.
		return BodyInfo.getInstance();
	}
}
