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 = {
        'Osso Zigomático': {'label': 'Osso Zigomático', 'children': ['Faces', 'Apófises'], 'color': 'white', 'shape': 'circle', 'fontsize': '20', 'labeled': True},
        'Faces': {'label': 'Faces', 'children': ['Face lateral', 'Face Temporal', 'Face Orbitrária'], 'color': 'deepskyblue', 'labeled': True},
        'Apófises': {'label': 'Apófises', 'children': ['Apófise Frontal', 'Apófise Temporal'], 'color': 'yellowgreen', 'labeled': True},
        'Face lateral': {'label': 'Face Lateral', 'children': ['Oríficio zigomático-facial'], 'labeled': True},
        'Face Temporal': {'label': 'Face Temporal', 'children': ['Orifício zigomático-temporal'], 'labeled': True},
        'Oríficio zigomático-facial': {'label': 'Oríficio zigomático-facial', 'children': [], 'labeled': False},
        'Orifício zigomático-temporal': {'label': 'Orifício zigomático-temporal', 'children': [], 'labeled': False},
        'Face Orbitrária': {'label': 'Face Orbitrária', 'children': ['Porção ântero-lateral da cavidade orbitária', 'Orifícios zigomático-orbitários'], 
                            'labeled': True},
        'Porção ântero-lateral da cavidade orbitária': {'label': 'Porção ântero-lateral da cavidade orbitária', 'children': [], 'labeled': False},
        'Apófise Frontal': {'label': 'Apófise Frontal', 'children': [], 'labeled': True},
        'Orifícios zigomático-orbitários': {'label': 'Orifícios zigomático-orbitários', 'children': [], 'labeled': False},
        'Apófise Temporal': {'label': 'Apófise Temporal', 'children': ['Arco zigomático'], 'labeled': False},
        'Arco zigomático': {'label': 'Arco zigomático', '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, 'Faces', nodes['Faces']['label'], nodes['Faces']['color'], nodes)
    add_nodes(dot1, 'Faces', nodes['Faces']['children'], nodes['Faces']['color'])

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

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

if __name__ == "__main__":
    create_mind_map()
