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='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 = {
        'Mandíbula': {'label': 'Mandíbula', 'children': ['Corpo', 'Ramos mandibulares'], 'color': 'white', 'shape': 'circle', 'fontsize': '20', 'labeled': True},
        'Corpo': {'label': 'Corpo', 'children': ['Face lateral C', 'Face medial C'], 'color': 'violet', 'labeled': True},
        'Ramos mandibulares': {'label': 'Ramos Mandibulares', 'children': ['Bordo superior', 'Face medial R', 'Bordo inferior'], 'color': 'mediumseagreen',
                                'labeled': True},
        'Face lateral C': {'label': 'Face Lateral', 'children': [ 'Linha oblíqua', 'Buracos Mentonianos', 'Protuberância Mental (Gnátio)'], 'labeled': True},
        'Face medial C': {'label': 'Face Medial', 'children': ['Fosseta sublingual', 'Linha Milo-Hióidea', 'Fosseta submandibular', 'Espinhas Mentonianas', 
                                                               'Fossas Digástricas'], 'labeled': True},
        'Protuberância Mental (Gnátio)': {'label': 'Protuberância Mental (Gnátio)', 'children': [], 'labeled': False},
        'Buracos Mentonianos': {'label': 'Buracos Mentonianos', 'children': [], 'labeled': False},
        'Linha oblíqua': {'label': 'Linha Oblíqua', 'children': [], 'labeled': False},
        'Espinhas Mentonianas': {'label': 'Espinhas Mentonianas', 'children': ['Superiores', 'Inferiores'], 'labeled': False},
        'Fossas Digástricas': {'label': 'Fossas Digástricas', 'children': [], 'labeled': False},
        'Linha Milo-Hióidea': {'label': 'Linha Milo-Hióidea', 'children': [], 'labeled': False},
        'Superiores': {'label': 'Superiores', 'children': [], 'labeled': False},
        'Inferiores': {'label': 'Inferiores', 'children': [], 'labeled': False},
        'Fosseta sublingual': {'label': 'Fosseta Sublingual', 'children': [], 'labeled': False},
        'Fosseta submandibular': {'label': 'Fosseta Submandibular', 'children': [], 'labeled': False},
        'Face medial R': {'label': 'Face Medial', 'children': ['Língula (Espinha de Spix)', 'Buraco mandibular'], 'labeled': True},
        'Bordo superior': {'label': 'Bordo Superior', 'children': ['Apófise condilar', 'Apófise coronoide', 'Incisura mandibular'], 'labeled': True},
        'Bordo inferior': {'label': 'Bordo Inferior', 'children': ['Gónion'], 'labeled': True},
        'Gónion': {'label': 'Gónion', 'children': [], 'labeled': False},
        'Buraco mandibular': {'label': 'Buraco mandibular', 'children': [], 'labeled': False},
        'Língula (Espinha de Spix)': {'label': 'Língula (Espinha de Spix)', 'children': [], 'labeled': False},
        'Apófise coronoide': {'label': 'Apófise Coronoide', 'children': ['Crista Temporal'], 'labeled': False},
        'Crista Temporal': {'label': 'Crista Temporal', 'children': [], 'labeled': False},
        'Apófise condilar': {'label': 'Apófise Condilar', 'children': ['Colo do côndilo da mandíbula', 'Côndilo da mandíbula'], 'labeled': False},
        'Incisura mandibular': {'label': 'Incisura Mandibular', 'children': [], 'labeled': False},
        'Fossa Pterigóide': {'label': 'Fossa Pterigóide', 'children': [], 'labeled': False},
        'Côndilo da mandíbula': {'label': 'Côndilo da mandíbula', 'children': [], 'labeled': False},
        'Colo do côndilo da mandíbula': {'label': 'Colo do côndilo da mandíbula', 'children': ['Fossa Pterigóide'], '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, 'Corpo', nodes['Corpo']['label'], nodes['Corpo']['color'], nodes)
    add_nodes(dot1, 'Corpo', nodes['Corpo']['children'], nodes['Corpo']['color'])

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

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

if __name__ == "__main__":
    create_mind_map()
