
import bpy


def get_collection_parents(col, root=None, cols=None):
    """Return all direct collection parents

    Args:
        col (bpy.types.Collection): collection to get parents from
        root (bpy.types.Collection, optional): collection to search in (recursive) instead of the scene collection.
            Defaults to None.
        cols (_type_, optional): for recursivity, store the parent collections.
            Defaults to None.

    Returns:
        list[bpy.types.Collection]: a list of direct parents
    """

    if cols is None:
        cols = []

    if root is None:
        root = bpy.context.scene.collection

    for sub in root.children:
        if sub == col:
            cols.append(root)

        if len(sub.children):
            cols = get_collection_parents(col, root=sub, cols=cols)
    return cols

def get_view_3d_override():
    windows = bpy.context.window_manager.windows
    areas = [a for w in windows for a in w.screen.areas if a.type == 'VIEW_3D']

    if not areas:
        print('No view 3d found')
        return

    view_3d = None
    for area in areas:
        if area.spaces.active.camera:
            view_3d = area
    
    if not view_3d:
        view_3d = max(areas, key=lambda x :x.width)

    return {'area': view_3d, 'region': view_3d.regions[-1]}

def get_mat(ob):
    for sl in ob.material_slots:
        if sl.material:
            return sl.material

def link_mat_to_object(ob):
    for sl in ob.material_slots:
        m = sl.material
        sl.link = 'OBJECT'
        sl.material = m

def eval_attr(ob, name):
    resolved = ob
    for o in name.split("."):
        resolved = getattr(resolved, o)
    return resolved

def flip_name(name):
    if not name:
        return

    if name.startswith('[') and name.endswith(']'): #It's a custom property
        flipped_name = bpy.utils.flip_name(name[:-2][2:])
        return f'["{flipped_name}"]'
    else:
        return bpy.utils.flip_name(name)

def split_path(path) :
    try :
        bone_name = path.split('["')[1].split('"]')[0]
    except Exception:
        bone_name = None

    try :
        prop_name = path.split('["')[2].split('"]')[0]
    except Exception:
        prop_name = None

    return bone_name, prop_name

def hide_layers(args):
    """ """
    ob = bpy.context.object

    layers = []
    for bone in [b for b in ob.pose.bones if b.bone.select]:
        for i,l in enumerate(bone.bone.layers):
            if l and i not in layers:
                layers.append(i)

    for i in layers:
        ob.data.layers[i] = not ob.data.layers[i]

def select_layer(args):
    ob = bpy.context.object

    layers =[]
    for bone in [b for b in ob.pose.bones if b.bone.select]:
        bone_layers = [i for i,l in enumerate(bone.bone.layers) if l]

        for l in bone_layers:
            if l not in layers:
                layers.append(l)

    for bone in ob.pose.bones:
        bone_layers = [i for i,l in enumerate(bone.bone.layers) if l]

        if len(set(bone_layers).intersection(layers)):
            bone.bone.select = True

def hide_bones(args):
    ob = bpy.context.object
    selected_bone = [b for b in ob.pose.bones if b.bone.select]

    hide = [b.bone.hide for b in selected_bone if not b.bone.hide]

    visibility = True if len(hide) else False

    for bone in selected_bone:
        bone.bone.hide = visibility

def select_all(args):
    ob = bpy.context.object
    shapes = ob.data.rig_picker['shapes']
    bones = [s['bone'] for s in shapes if s['shape_type']=='BONE']

    for bone_name in bones:
        bone = ob.pose.bones.get(bone_name)

        if bone:
            bone.bone.select = True
