package tools.xml;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Created by IntelliJ IDEA.
 * User: Igor
 * Date: 18.12.2005
 * Time: 15:26:59
 * To change this template use File | Settings | File Templates.
 */
public class XMLTools
{
    public static Document parse(String xmlString) throws IOException, ParserConfigurationException, SAXException
    {
        return XMLIO.load(new ByteArrayInputStream(xmlString.getBytes()));
    }
    public static Document parse(InputStream xmlString) throws IOException, ParserConfigurationException, SAXException
    {
        return XMLIO.load(xmlString);
    }

    /**
     * Возвращает вложенный элемент "childName" элемента "parent" <br/>
     * &lt;element&gt;&lt;childName/&gt;&lt;/element&gt;
     * @param parent
     * @param childName
     * @return Дочерный элемент либо <code>null</code>, если элементов с таким именем нет
     */
    public static Element getChild(Element parent, String childName){
        NodeList nl = parent.getChildNodes();
        for (int i = 0; i <nl.getLength(); i++) {
            if (isElement(nl.item(i), childName)){
                return (Element)nl.item(i);
            }
        }
        return null;
    }

    /**
     * Проверяет, является ли <code>node</code> элементом (<code>instanceOf {@link Element}</code>)
     * и имеет ли имя "tagname"
     * @param node
     * @param tagname
     * @return
     */
    public static boolean isElement(Node node, String tagname){
        return node instanceof Element && node.getNodeName().equals(tagname);
    }

    //вернуть первый попавшийся узел среди дочерних
    public static Node getFirstNodeOnName(Node node,String nodename)
    {
        Node[] mas=new Node[50]; //depth
        int pos=0;
        mas[pos] = node.getFirstChild();
        while (mas[pos] != null)
        {
            if(mas[pos].getNodeName().equals(nodename))
            {
                return mas[pos];
            }
            if(mas[pos].getFirstChild()!=null)
            {
                pos++;
                mas[pos]=mas[pos-1].getFirstChild();
            }else
            {
                //если не идёт дальше пытаемся подняться в верх по дереву
                while (true)
                {
                    mas[pos] = mas[pos].getNextSibling();
                    if (mas[pos]==null)
                    {
                        if(pos>0){ pos--; }else{ break; }
                    }else
                    {
                        break;
                    }
                }
            }
        }
        return null;
    }

    /**
     * Return first from childs in first deep level on name
     * @param node Find in
     * @param nodename Name node
     * @return node
     */
    public static Node getNodeOnName(Node node,String nodename)
    {
		if(node==null) return null;
		Node nextNode = node.getFirstChild();
		while(nextNode != null)
		{
			if(nextNode.getNodeName().equals(nodename)) return nextNode;
			nextNode=nextNode.getNextSibling();
		}
		return null;
    }

    //Сериализовать узел в строку
    public static String getOuterXML(Node node)
    {
        DOMImplementationLS domImplementation = (DOMImplementationLS) node.getOwnerDocument().getImplementation();
        LSSerializer lsSerializer = domImplementation.createLSSerializer();
        if (!(node instanceof Document))
        {
            lsSerializer.getDomConfig().setParameter("xml-declaration", false);
        }
        return lsSerializer.writeToString(node);
    }

}
