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


"""Modules Handling Module"""


import logs
import namespaces


_defaultElementClass = None
_elementClasses = {}
_elementFeatures = {}
_elementNamespaceUriAndNameCouples = {}
_holderClasses = {}
_holderNamespaceUriAndNameCouples = {}


def getElementClass(namespaceUri, elementName):
    if namespaceUri in _elementClasses:
        namespaceElementClasses = _elementClasses[namespaceUri]
        if elementName in namespaceElementClasses:
            return namespaceElementClasses[elementName]
    if _defaultElementClass is None:
        defaultElementClassName = "None"
    else:
        defaultElementClassName = _defaultElementClass.__name__
    logs.debug(
        """Using default class "%s" for element "%s" in namespace "%s".""" % (
            defaultElementClassName, elementName, namespaceUri))
    return _defaultElementClass


def getElementClassNamespaceUriAndName(elementClass):
    return _elementNamespaceUriAndNameCouples[elementClass]


def getHolderClass(namespaceUri, elementName, default = None):
    if namespaceUri in _holderClasses:
        namespaceHolderClasses = _holderClasses[namespaceUri]
        if elementName in namespaceHolderClasses:
            return namespaceHolderClasses[elementName]
    if default is None:
        defaultHolderClassName = "None"
    else:
        defaultHolderClassName = default.__name__
    logs.debug(
        """Using default class "%s" for holder "%s" in namespace "%s"."""
        % (defaultHolderClassName, elementName, namespaceUri))
    return default


def getHolderClassNamespaceUriAndName(holderClass):
    return _holderNamespaceUriAndNameCouples[holderClass]


def getElementFeature(namespaceUri, elementName):
    return _elementFeatures[namespaceUri][elementName]


def getHolderConstructorNamespaceAndElementNames():
    import elements
    namespaceNameAndNameCouples = []
    for namespaceUri, namespaceElementFeatures in _elementFeatures.items():
        namespaceName = namespaces.getName(namespaceUri)
        for elementName, elementFeature in namespaceElementFeatures.items():
            if elementFeature.elementClass is not None and issubclass(
                    elementFeature.elementClass, elements.RootElement):
                namespaceNameAndNameCouples.append((namespaceName, elementName))
    return namespaceNameAndNameCouples


def registerElementClass(namespaceUri, elementName, elementClass):
    assert namespaceUri
    if namespaceUri not in _elementClasses:
        _elementClasses[namespaceUri] = {}
    _elementClasses[namespaceUri][elementName] = elementClass
    _elementNamespaceUriAndNameCouples[elementClass] = (
        namespaceUri, elementName)


def registerElementFeature(namespaceUri, name, elementFeature):
    assert namespaceUri
    if namespaceUri not in _elementFeatures:
        _elementFeatures[namespaceUri] = {}
    _elementFeatures[namespaceUri][name] = elementFeature


def registerHolderClass(namespaceUri, elementName, holderClass):
    assert namespaceUri
    if namespaceUri not in _holderClasses:
        _holderClasses[namespaceUri] = {}
    _holderClasses[namespaceUri][elementName] = holderClass
    _holderNamespaceUriAndNameCouples[holderClass] = (
        namespaceUri, elementName)


def setDefaultElementClass(elementClass):
    global _defaultElementClass
    _defaultElementClass = elementClass
