# This file is part of the Coral project.
# Please read the copyright notice in the LICENSE file.

import coral
import re

def getFQTypeName(ed, stop_at_ed = None):
    """Returns the FQN of an AbstractElementDefinition, optionally stopping
    at stop_at_ed."""
    if ed is None:
        return "<None>"
    s = []
    while ed:
        if ed == stop_at_ed:
            break
        if isinstance(ed, coral.Language):
            s.append(ed.getName() + "." + \
                     str(ed.getVersion()) + "." + \
                     str(ed.getRevision()))
        else:
            s.append(ed.getName())
        ed = ed.__package__()
    s.reverse()
    return '::'.join(s)

def getFQName(element, n = -1):
    """Returns the fully qualified name of the element, up
    to @n parts. If no name can be obtained, use a pointer.
    If the name is empty, returns '(noname)' for convenience. """
    if element is None:
        return "<None>"
    if not isinstance(element, coral.Element):
        return unicode(element)
    e = element
    s = []
    while 1:
        t = e.__type__()
        name = ""
        try:
            op = t.__bindOperation__("getName", e)
        except AttributeError:
            found = 0
            p = t.getPropertyByName("name")
            if p and p.isAtMostOne():
                name = e.name
                found = 1
            if not found:
                for p in t.__properties__():
                    ed = p.getTarget()
                    if (ed == coral.Name) and p.isAtMostOne():
                        name = getattr(e, p.getName())
                        found = 1
                        break
                if not found:
                    break
        else:
            name = op()
        name = unicode(name)
        if re.search("^\s*$", name):
            name = u"(noname)"
        s.append(name)
        e = e.__parent__()
        n -= 1
        if not e or n == 0:
            s.reverse()
            return "::".join(s)

    # id() can be negative
    return hex(abs(id(element)))
