from collections.abc import Set as AbstractSet

from bpy.types import Armature, Context, GizmoGroup

from ..extension import get_armature_extension


# https://gist.github.com/FujiSunflower/09fdabc7ca991f8292657abc4ef001b0
class Vrm0FirstPersonBoneOffsetGizmoGroup(GizmoGroup):
    bl_idname = "VRM_GGT_vrm0_first_person_bone_offset"
    bl_label = "First Person Bone Offset Gizmo"
    bl_space_type = "VIEW_3D"
    bl_region_type = "WINDOW"
    bl_options: AbstractSet[str] = {"3D", "PERSISTENT"}

    @classmethod
    def poll(cls, context: Context) -> bool:
        active_object = context.active_object
        if not active_object:
            return False
        return active_object.type == "ARMATURE"

    def setup(self, context: Context) -> None:
        active_object = context.active_object
        if not active_object:
            return
        armature_data = active_object.data
        if not isinstance(armature_data, Armature):
            return
        ext = get_armature_extension(armature_data)
        first_person = ext.vrm0.first_person
        first_person_bone = armature_data.bones[
            first_person.first_person_bone.bone_name
        ]
        gizmo = self.gizmos.new("GIZMO_GT_move_3d")
        gizmo.target_set_prop("offset", first_person, "first_person_bone_offset")
        gizmo.matrix_basis = first_person_bone.matrix_local
        gizmo.draw_style = "CROSS_2D"
        gizmo.draw_options = {"ALIGN_VIEW"}
        gizmo.color = 1.0, 0.5, 0.0
        gizmo.alpha = 0.5
        gizmo.color_highlight = 1.0, 0.5, 1.0
        gizmo.alpha_highlight = 0.5
        gizmo.scale_basis = 0.25

        self.first_person_gizmo = gizmo

    def refresh(self, context: Context) -> None:
        active_object = context.active_object
        if not active_object:
            return
        armature_data = active_object.data
        if not isinstance(armature_data, Armature):
            return
        ext = get_armature_extension(armature_data)
        gizmo = self.first_person_gizmo
        first_person = ext.vrm0.first_person
        first_person_bone = armature_data.bones[
            first_person.first_person_bone.bone_name
        ]
        gizmo.matrix_basis = first_person_bone.matrix_local
