import coral
import string

def getAllProperties(e):
    l=e.properties
    for x in e.superclasses:
        for p in getAllProperties(x):
            if p not in l:
                l.append(p)
    return l
        
def toStr(e):
    s=""
    #for p in  e.__meta__.properties:
    #    if str(p.name)=="name":
    #        s=str(e.name)
    #if not s:
    try:
        s=str(e.name)+"_"+str(e.__type__().getName())
    except:
        s=str(e)
    s=string.replace(s," ","_")
    return s

def addLine(l,s):
    if s not in l:
        l.append(s)
    return l

def todot_r(e,l,processed):
    if processed.has_key(e):
        return 
    processed[e]=1
    
    addLine(l,toStr(e)+" ;")
    
    for p in getAllProperties(e.__meta__):
        if p.element_kind.oclIsKindOf(coral.lang.SMD01.DatatypeDefinition):
            continue
        v=getattr(e,str(p.name))
        if p.multiplicity_upper!=1:
            for e2 in v:
                if e2:
                    addLine(l,toStr(e)+" -- "+toStr(e2)+";")
                    todot_r(e2,l,processed)
        else:
            if v:
                addLine(l,toStr(e)+" -- "+toStr(v)+";")
                todot_r(v,l,processed)
    return 

def toNeato(e):
    l=["graph G {","overlap=false","spline=true"]
    todot_r(e,l,{})
    l.append("}")
    s=""
    for line in l:
        s=s+line+"\n"
    return s


def SMDPackage2neato(p):
    s=""
    for c in p.elements:
        if c.oclIsKindOf(coral.lang.SMD01.ElementDefinition):
            s=s+SMDClass2neato(c)
    return s

def SMDClass2neato(c):
    attr=""
    for p in c.properties:
        if p.element_kind.oclIsKindOf(coral.lang.SMD01.DatatypeDefinition):
            attr=attr+str(p.name)+":"+str(p.element_kind.name)+"\\n "
            
    s=str(c.name)+' [shape=record, labeljust=l, label="{'+str(c.name)+' | '+attr+' }" ];'
    s=s+"\n"
    for p in c.properties:
        if not p.element_kind.oclIsKindOf(coral.lang.SMD01.DatatypeDefinition):
            s=s+str(c.name)+" -- "+str(p.element_kind.name)+' [label="'+str(p.name)+'"];\n'

    for super in c.superclasses:
        s=s+str(c.name)+ " -- "+ str(super.name)+" [arrowhead=empty];\n"
    return s

def SMD2neato(l):
    s="graph G { overlap=false;\n"

    s=s+SMDPackage2neato(l)
    
    s=s+"}\n"

    return s
