/*******************************************************************************
 * 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.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.common.logging.Logger;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * @author mengbo
 */
public class DOMUtil {
	private static Logger _logger = PDPlugin.getLogger(DOMUtil.class);

	/**
	 * Get a list of ancester nodes starting from the Document till the node.
	 * 
	 * @param node
	 * @return
	 */
	private static List getAncesters(Node node) {
		List list = new ArrayList();
		while (node != null) {
			list.add(node);
			if (node instanceof Document) {
				break;
			} else {
				node = node.getParentNode();
			}
		}
		if (node == null) {
			// if part ==null, means we didn't find a DocumentEditPart,
			// something must be wrong.
			return null;
		}
		// reverse to make it starting from the docuemnteditpart node.
		Collections.reverse(list);
		list.add(null); // add an null terminator.
		return list;
	}

	/**
	 * find the smallest common ancester of two edit part.
	 * 
	 * @param node1
	 * @param node2
	 * @return
	 */
	public static Node findCommonAncester(Node node1, Node node2) {
		List list1 = getAncesters(node1);
		if (list1 == null) {
			return null;
		}
		List list2 = getAncesters(node2);
		if (list2 == null) {
			return null;
		}
		if (list1.get(0) != list2.get(0)) {
			return null;
		}
		Node common = (Node) list1.get(0);
		for (int i = 1;; i++) {
			Node p1 = (Node) list1.get(i);
			Node p2 = (Node) list2.get(i);
			if (p1 == null || p2 == null) {
				return common;
			}
			if (p1 != p2) {
				return common;
			}
			common = p1;
		}

	}

	/**
	 * this method is almost same as <code>cloneNodeDeep()</code>. The
	 * difference is that this method will try to ignore all kinds of error.
	 * 
	 * In SSE, if the document model enforce some kinds of validation, then the
	 * clone may fail. During some cases, we want to ignore the validation
	 * errors.
	 * 
	 * @param destDoc
	 * @param sourceNode
	 * @return
	 */
	public static Node cloneNodeDeepIgnoreError(Document destDoc,
			Node sourceNode) {
		switch (sourceNode.getNodeType()) {
		case Node.ELEMENT_NODE:
			Element sourceEle = (Element) sourceNode;
			Element resultEle = destDoc.createElement(sourceEle.getTagName());
			NamedNodeMap attrs = sourceEle.getAttributes();
			for (int i = 0, size = attrs.getLength(); i < size; i++) {
				Attr a = (Attr) attrs.item(i);
				try {
					resultEle.setAttribute(a.getName(), a.getValue());
				} catch (Exception ex) {
					// ignore
					_logger.info("Exception", ex);
				}
			}
			NodeList children = sourceEle.getChildNodes();
			for (int i = 0, size = children.getLength(); i < size; i++) {
				Node n = children.item(i);
				Node d = cloneNodeDeepIgnoreError(destDoc, n);
				if (d != null) {
					try {
						resultEle.appendChild(d);
					} catch (Exception ex) {
						// ignore
						_logger.info("Exception", ex);
					}
				}
			}
			return resultEle;
		case Node.TEXT_NODE:
			Text txt = destDoc.createTextNode(sourceNode.getNodeValue());
			if (txt instanceof IDOMText && sourceNode instanceof IDOMText) {
				try {
					((IDOMText) txt).setSource(((IDOMText) sourceNode)
							.getSource());
				} catch (Exception ex) {
					// ignore
				}
			}
			return txt;
		case Node.CDATA_SECTION_NODE:
			return destDoc.createCDATASection(sourceNode.getNodeValue());
		default:
			return null; // not support.
		}
	}

	public static Node cloneNodeDeep(Document destDoc, Node sourceNode) {
		switch (sourceNode.getNodeType()) {
		case Node.ELEMENT_NODE:
			Element sourceEle = (Element) sourceNode;
			Element resultEle = destDoc.createElement(sourceEle.getTagName());
			NamedNodeMap attrs = sourceEle.getAttributes();
			for (int i = 0, size = attrs.getLength(); i < size; i++) {
				Attr a = (Attr) attrs.item(i);
				resultEle.setAttribute(a.getName(), a.getValue());
			}
			NodeList children = sourceEle.getChildNodes();
			for (int i = 0, size = children.getLength(); i < size; i++) {
				Node n = children.item(i);
				Node d = cloneNodeDeep(destDoc, n);
				if (d != null) {
					resultEle.appendChild(d);
				}
			}
			return resultEle;
		case Node.TEXT_NODE:
			Text txt = destDoc.createTextNode(sourceNode.getNodeValue());
			if (txt instanceof IDOMText && sourceNode instanceof IDOMText) {
				try {
					((IDOMText) txt).setSource(((IDOMText) sourceNode)
							.getSource());
				} catch (Exception ex) {
					// ignore
					_logger.info("Exception", ex);
				}
			}
			return txt;
		case Node.CDATA_SECTION_NODE:
			return destDoc.createCDATASection(sourceNode.getNodeValue());
		default:
			return null; // not support.
		}
	}

	/**
	 * check whether the ancester relationship exist for the two nodes.
	 * 
	 * @param ancester
	 * @param child
	 * @return
	 */
	public static boolean isAncester(Node ancester, Node child) {
		while (child != null) {
			if (child == ancester) {
				return true;
			}
			child = child.getParentNode();
		}
		return false;
	}

	/**
	 * insert the node at specified position.
	 * 
	 * @param insertPosition
	 * @param insert
	 * @return null if fail, otherwise return the inserted node.
	 */
	public static Node insertNode(IDOMPosition domPosition, Node node) {
		IDOMPosition position = DOMPositionHelper.splitText(domPosition);
		if (position == null || position.getContainerNode() == null) {
			return null;
		}
		if (position.getNextSiblingNode() == null) {
			position.getContainerNode().appendChild(node);
		} else {
			position.getContainerNode().insertBefore(node,
					position.getNextSiblingNode());
		}

		return node;
	}
}
