import graphviz
import colorsys
import matplotlib.colors as mcolors

labeled = True

def decrease_opacity(color, factor=0.1, min_opacity=0.1):
    """Decrease the opacity of a color by a given factor."""
    # Convert named color to RGBA if necessary
    if color.startswith('#'):
        rgba_color = mcolors.to_rgba(color)
    else:
        rgba_color = mcolors.to_rgba(mcolors.CSS4_COLORS[color])

    # Decrease opacity (alpha value)
    r, g, b, a = rgba_color
    a = max(min_opacity, a - factor)

    # Convert back to hex with adjusted opacity
    return f'#{int(r*255):02x}{int(g*255):02x}{int(b*255):02x}{int(a*255):02x}'

def add_node(dot, node_id, label, color, nodes, shape='box', fontsize='20', fontname='Helvetica', width=2.0, height=1.0):
    if labeled or nodes[node_id].get('labeled', True):
        dot.node(node_id, label, shape=shape, style='filled,rounded', color=color, fontname=fontname, fontsize=fontsize, width=str(width), height=str(height))
    else:
        dot.node(node_id, label, shape=shape, style='filled,rounded', color=color, fontname=fontname, fontsize=fontsize, width=str(width), height=str(height), fontcolor=decrease_opacity(color, factor=0.5))

def add_edge(dot, node_id, children):
    for child_id in children:
        dot.edge(node_id, child_id)

def create_mind_map():
    # Subgraph 1 with LR layout
    dot1 = graphviz.Graph(comment='Face Orbitrária Subgraph', engine='dot')
    dot1.attr(size='11.7,8.3!', ratio='compress', overlap='scale', splines='true', dpi='300', rankdir='LR', nodesep='2.0', ranksep='0.5')
    

    # Subgraph 2 with RL layout
    dot2 = graphviz.Graph(comment='Bordo Inferior Subgraph', engine='dot')
    dot2.attr(size='11.7,8.3!', ratio='compress', overlap='scale', splines='true', dpi='300', rankdir='RL', nodesep='2.0', ranksep='0.5')


    # Define the nodes and their relationships
    nodes = {
        'Osso Lacrimal': {'label': 'Osso Lacrimal', 'children': ['Face Orbitrária', 'Bordo Inferior'], 'color': 'white', 'shape': 'circle', 'fontsize': '20', 'labeled': True},
        'Face Orbitrária': {'label': 'Face Orbitrária', 'children': ['Crista Lacrimal', 'Sulco Lacrimal', 'Fossa do Saco Lacrimal'], 'color': 'steelblue', 'labeled': True},
        'Bordo Inferior': {'label': 'Bordo Inferior', 'children': ['Gancho Lacrimal'], 'color': 'tomato', 'labeled': True},
        'Crista Lacrimal': {'label': 'Crista Lacrimal', 'children': [], 'labeled': True},
        'Sulco Lacrimal': {'label': 'Sulco Lacrimal', 'children': [], 'labeled': True},
        'Fossa do Saco Lacrimal': {'label': 'Fossa do Saco Lacrimal', 'children': [], 'labeled': True},
        'Gancho Lacrimal': {'label': 'Gancho Lacrimal', 'children': [], 'labeled': True},
     }

    # Recursive function to add nodes and their children
    def add_nodes(dot, parent_id, children, color):
        for child_id in children:
            new_color = decrease_opacity(color, factor=0.3)
            if int(new_color[-2:], 16) < 50:  # If alpha is less than 0.2 (approx)                
                new_color = decrease_opacity(color, factor=0.2)
            add_node(dot, child_id, nodes[child_id]['label'], new_color, nodes)
            dot.edge(parent_id, child_id)
            add_nodes(dot, child_id, nodes[child_id]['children'], new_color)

    # Add nodes and edges to subgraph 1
    add_node(dot1, 'Face Orbitrária', nodes['Face Orbitrária']['label'], nodes['Face Orbitrária']['color'], nodes)
    add_nodes(dot1, 'Face Orbitrária', nodes['Face Orbitrária']['children'], nodes['Face Orbitrária']['color'])

    # Add nodes and edges to subgraph 2
    add_node(dot2, 'Bordo Inferior', nodes['Bordo Inferior']['label'], nodes['Bordo Inferior']['color'], nodes)
    add_nodes(dot2, 'Bordo Inferior', nodes['Bordo Inferior']['children'], nodes['Bordo Inferior']['color'])

    # Render each subgraph to separate files
    dot1.render('lacrimal1_subgraph', format='svg', view=True)
    dot2.render('lacrimal2_subgraph', format='svg', view=True)

if __name__ == "__main__":
    create_mind_map()
