/*******************************************************************************
 * 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.jsf.common.ui.internal.logging.Logger;
import org.eclipse.jst.pagedesigner.PDPlugin;
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;
			}
            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;
	}
}
