# -*- coding: UTF-8 -*-


# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
#     Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


"""XML Nodes Module"""


import libxml2

import namespaces
import xpaths


class NodeWrapper(object):
    node = None

    def __init__(self, node):
        if node is not None:
            self.node = node

    def append(self, item):
        raise NotImplementedError

    def evaluateXpath(self, xpath, contextNode = None):
        if contextNode is None:
            contextNode = self.node
        return xpaths.evaluateXpath(xpath, contextNode)

    def evaluateBoolean(self, xpath, contextNode = None):
        nodes = self.evaluateXpath(xpath)
        if nodes:
            return nodes[0].content in ["1", "true"]
        else:
            return False

    def serialize(self):
        return self.node.serialize(format = 1)


def copyNodeWithoutXhtmlNamespace(node):
    """Copy recursively a node, but remove all references to XHTML namespace.

    This function is needed when inserting nodes with namespaces into a libxslt generated HTML
    document, because this document has no namespace.
    """

    newNode = node.copyNode(False)

    # Copy namespace when it is not XHTML namespace.
    try:
        namespace = node.ns()
    except libxml2.treeError:
        # The libxml2 Python binding raises this exception when xmlNs returns None.
        pass
    else:
        if namespace.content != namespaces.html.uri:
            newNode.setNs(namespace)

    # Copy namespace definitions which are not XHTML namespace definitions.
    try:
        namespace = node.nsDefs()
    except libxml2.treeError:
        # The libxml2 Python binding raises this exception when xmlNs returns None.
        namespace = None
    while namespace is not None:
        if namespace.content != namespaces.html.uri:
            newNode.newNs(namespace.name, namespace.content)
        namespace = namespace.next

    # Copy properties.
    propertyNode = node.properties
    while propertyNode is not None:
        try:
            namespace = propertyNode.ns()
        except libxml2.treeError:
            # The libxml2 Python binding raises this exception when xmlNs returns None.
            namespace = None
        else:
            if namespace.content == namespaces.html.uri:
                namespace = None
        newNode.newNsProp(namespace, propertyNode.name, propertyNode.content)
        propertyNode = propertyNode.next

    # Recursively copy children.
    childNode = node.children
    while childNode is not None:
        if childNode.type != "element":
            newNode.addChild(childNode.copyNode(True))
            childNode = childNode.next
            continue
        newNode.addChild(copyNodeWithoutXhtmlNamespace(childNode))
        childNode = childNode.next

    return newNode
