# -*- 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.


"""XHTML2 Tags Module"""


import types

import libxml2

import dataholders
import elements
import html as xhtml
import locations
import namespaces
import stations
import widgets


class Element(elements.Element):
    def generateXmlContextAttributes(self, context, newElement):
        filled = False
        attribute = self.node.properties
        while attribute is not None:
            attributeName = attribute.name
            attributeContent = attribute.content
            if attributeName in ("href", "src") and attributeContent:
                attributeContent = context.specimen.constructUri(attributeContent)
            newElement.node.newProp(attributeName, attributeContent)
            filled = True
            attribute = attribute.next
        return filled


class WidgetElement(widgets.WidgetMixin, Element):
    quickMapNodeName = None

    def isInline(self):
        raise NotImplementedError

    def newContext(self, specimen, *attributes, **keywords):
        return WidgetElementContext(self, specimen, *attributes, **keywords)


class WidgetElementContext(xhtml.WidgetElementContext):
    def deleteSectionLevel(self):
        del self.getParent().sectionLevel

    def getSectionLevel(self):
        return self.getParent().sectionLevel

    def setSectionLevel(self, sectionLevel):
        self.getParent().sectionLevel = sectionLevel

    sectionLevel = property(
        getSectionLevel, setSectionLevel, deleteSectionLevel)


class BlockLevelElement(WidgetElement):
    def isInline(self):
        # FIXME TODO.
        return False


class InlineLevelElement(WidgetElement):
    def isInline(self):
        # FIXME TODO.
        return True


class Xhtml2Holder(dataholders.XmlHolder):
    defaultFileNameExtension = ".xml"
    mimeType = "text/html"


class a(InlineLevelElement):
    pass


class body(WidgetElement):
    pass


class code(InlineLevelElement):
    pass


class h(BlockLevelElement):
    def generateXmlContextElement(self, context, layout):
        namespacePrefix = self.getNamespacePrefix()
        namespaceUri = self.getNamespaceUri()
        name = "h%d" % context.sectionLevel
        newElementClass = modules.getElementClass(namespaceUri, name)
        newElement = newElementClass(node = (namespacePrefix, namespaceUri, name), owner = None)
        layout.append(newElement)
        return newElement


class head(WidgetElement):
    pass


class html(WidgetElement):
    def generateXmlDocument(self):
        htmlDocument = documents.newTemporaryHtmlDocument()
        self.generateXml(htmlDocument)
        return htmlDocument

    def newContext(self, specimen, *attributes, **keywords):
        return HtmlContext(self, specimen, *attributes, **keywords)


class HtmlContext(xhtml.HtmlContextMixin, WidgetElementContext):
    sectionLevel = 0


class li(BlockLevelElement):
    pass


class nl(BlockLevelElement):
    quickMapNodeName = "ul"


class p(BlockLevelElement):
    pass
    

class section(BlockLevelElement):
    def generateXmlContextElement(self, context, layout):
        namespacePrefix = self.getNamespacePrefix()
        namespaceUri = self.getNamespaceUri()
        name = "div"
        newElementClass = modules.getElementClass(namespaceUri, name)
        newElement = newElementClass(node = (namespacePrefix, namespaceUri, name), owner = None)
        newElement.node.newProp("class", "section-h%s" % context.sectionLevel)
        layout.append(newElement)
        return newElement

    def generateXmlContext(self, context, layout):
        context.sectionLevel += 1
        filled = super(section, self).generateXmlContext(context, layout)
        context.sectionLevel -= 1
        return filled


class title(WidgetElement):
    pass


def areInline(*items):
    for item in items:
        if not isInline(item):
            return False
    return True


def enclose(*items, **attributes):
    if areInline(*items):
        return span(*items, **attributes)
    else:
        return div(*items, **attributes)


def isInline(item):
    if item is None:
        return True
    elif isinstance(item, WidgetElement):
        return item.isInline()
    elif type(item) in (types.ListType, types.TupleType):
        for itemItem in item:
            if not isInline(itemItem):
                return False
        return True
    else:
        return True


elements.registerElement(namespaces.xhtml2.uri, "a", a)
elements.registerElement(namespaces.xhtml2.uri, "body", body)
elements.registerElement(namespaces.xhtml2.uri, "code", code)
elements.registerElement(namespaces.xhtml2.uri, "h", h)
elements.registerElement(namespaces.xhtml2.uri, "head", head)
elements.registerElement(
    namespaces.xhtml2.uri, "html", html, holderClass = Xhtml2Holder)
elements.registerElement(namespaces.xhtml2.uri, "li", li)
elements.registerElement(namespaces.xhtml2.uri, "nl", nl)
elements.registerElement(namespaces.xhtml2.uri, "p", p)
elements.registerElement(namespaces.xhtml2.uri, "section", section)
elements.registerElement(namespaces.xhtml2.uri, "title", title)
