"""
adx2dot
see https://cg-twiki.arrc.csiro.au/twiki/bin/view/Compgeosci/PythonDeclarativeProgramming
and https://cg-twiki.arrc.csiro.au/twiki/bin/view/Compgeosci/XmlToDot

"""

import pydot
#import pydotNoParser as pydot  # Andy's hack so you don't need pyparsing installed
# import pdis.xpath  # not using at present, just using elementree xpath support
from elementtree import ElementTree as ET

# namespace shortcuts
# easy way to assemble '//{http://www.opengis.net/gml}definitionMember/{http://www.opengis.net/om}ProcedureSequence'
# using  ''.join( ('//', gml, 'definitionMember/', om, 'ProcedureSequence') )
# use these shortcuts throughout logic so we can reassign them, in case xmlns is different!!!
adx = "{http://www.seegrid.csiro.au/xml/adx/3}"
gml = "{http://www.opengis.net/gml}"
om = "{http://www.opengis.net/om}"
xlink = "{http://www.w3.org/1999/xlink}"


def buildActivitiesDict(tree):
    """
    builds dict of all 
    <gml:definitionMember><adx:SpecimenPreparationActivity>
    This is the sort of thing you'd use an xsl:key for in XSLT.
    """
    activities = tree.findall( ''.join(( '//', gml, 'definitionMember/', adx, 'SpecimenPreparationActivity' )) )
    d = {}
    for a in activities:
        d[ a.attrib['{http://www.opengis.net/gml}id'] ] = a  # index elements by their id
    return d


def graphSeqDefsCrossLinking(tree, actsD):
    """
    returns a graph you can dump with .to_string() or graph with write_png
    actsD should be a dict created with buildActivitiesDict

    The nodes are shown    
    """
    graph = pydot.Dot(size='5.5,7')
    seqsPath = ''.join( ('//', gml, 'definitionMember/', om, 'ProcedureSequence') )
    seqs = tree.findall( seqsPath)
    for seq in seqs:
        seqName = seq.find(gml+'name').text
        graph.add_node( pydot.Node(seqName) )
        edgeFrom = seqName
        for step in seq.findall(om+'step'):
            activityDesc = actsD[ step.attrib[xlink+'href'][1:] ]  # assume # in href[0:0], eg: #rec1
            edgeTo = activityDesc.find(gml+'name').text
            graph.add_edge( pydot.Edge(edgeFrom, edgeTo) )
    return graph


def graphSeqDefs(tree, actsD):
    """
    returns a graph you can dump with .to_string() or graph with write_png
    actsD should be a dict created with buildActivitiesDict
    """
    graph = pydot.Dot(size='5.5,7')
    seqsPath = ''.join( ('//', gml, 'definitionMember/', om, 'ProcedureSequence') )
    seqs = tree.findall( seqsPath)
    uniqueStepNumber = 0
    for seq in seqs:
        seqName = seq.find(gml+'name').text
        seqNode = pydot.Node(seqName)
        seqNode.shape = "box"
        graph.add_node( seqNode )
        edgeFrom = seqName
        for step in seq.findall(om+'step'):
            activityDesc = actsD[ step.attrib[xlink+'href'][1:] ]  # assume # in href[0:0], eg: #rec1
            edgeTo = 'step'+str(uniqueStepNumber)
            uniqueStepNumber += 1
            destNode = pydot.Node(edgeTo)
            destNode.label = activityDesc.find(gml+'name').text  # unique name, possibly similar label
            graph.add_node( destNode )
            graph.add_edge( pydot.Edge(edgeFrom, edgeTo) )
            edgeFrom = edgeTo
    return graph
            
            
            
    
    
