import graphviz
import colorsys
import matplotlib.colors as mcolors

labeled = True

def decrease_opacity(color, factor=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(0, 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='Corpo 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='Ramos mandibulares 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 Etmoide': {'label': 'Osso Etmoide', 'children': ['Lâmina Horizontal', 'Lâmina Vertical', 'Labirintos Laterais'], 'color': 'white', 
                         'shape': 'circle', 'fontsize': '20', 'labeled': True},
        'Lâmina Vertical': {'label': 'Lâmina Vertical', 'children': ['Septo nasal', 'Apófise Crista Galli'], 'color': 'mediumpurple', 'labeled': True},
        'Lâmina Horizontal': {'label': 'Lâmina Horizontal', 'children': ['Crista Galli', 'Filetes do nervo olfactivo'], 'color': 'orange', 'labeled': True},
        'Crista Galli': {'label': 'Crista Galli', 'children': [], 'labeled': True},
        'Filetes do nervo olfactivo': {'label': 'Filetes do nervo olfactivo', 'children': [], 'labeled': True},
        'Labirintos Laterais': {'label': 'Labirintos Laterais', 'children': ['Face Medial'], 'color': 'mediumturquoise', 'labeled': False},
        'Face Medial': {'label': 'Face Medial', 'children': ['Células etmoidais anteriores','Corneto superior', 'Infundíbulo', 'Corneto médio', 
                                                             'Apófise Unciforme',  'Face Superior', 'Face Lateral'], 'labeled': False},
        'Apófise Crista Galli': {'label': 'Apófise Crista Galli', 'children': [], 'labeled': True},
        'Septo nasal': {'label': 'Septo nasal', 'children': [], 'labeled': False},
        'Corneto superior': {'label': 'Corneto superior', 'children': [], 'labeled': False},
        'Corneto médio': {'label': 'Corneto médio', 'children': [], 'labeled': False},
        'Apófise Unciforme': {'label': 'Apófise Unciforme', 'children': [], 'labeled': False},
        'Infundíbulo': {'label': 'Infundíbulo', 'children': [], 'labeled': True},
        'Células etmoidais anteriores': {'label': 'Células etmoidais anteriores', 'children': [], 'labeled': False},
        'Face Superior': {'label': 'Face Superior', 'children': ['Canais etmoidal anterior', 'Canais etmoidal posterior'], 'labeled': False},
        'Canais etmoidal anterior': {'label': 'Canais etmoidal anterior', 'children': [], 'labeled': False},
        'Canais etmoidal posterior': {'label': 'Canais etmoidal posterior', 'children': [], 'labeled': False},
        'Face Lateral': {'label': 'Face Lateral', 'children': ['Lâmina orbitária'], 'labeled': False},
        'Lâmina orbitária': {'label': 'Lâmina orbitária', 'children': [], 'labeled': False},
     }

    # 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, 'Lâmina Horizontal', nodes['Lâmina Horizontal']['label'], nodes['Lâmina Horizontal']['color'], nodes)
    add_nodes(dot1, 'Lâmina Horizontal', nodes['Lâmina Horizontal']['children'], nodes['Lâmina Horizontal']['color'])
    add_node(dot1, 'Lâmina Vertical', nodes['Lâmina Vertical']['label'], nodes['Lâmina Vertical']['color'], nodes)
    add_nodes(dot1, 'Lâmina Vertical', nodes['Lâmina Vertical']['children'], nodes['Lâmina Vertical']['color'])

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

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

if __name__ == "__main__":
    create_mind_map()
