import os
import functools
import carb.input
import omni.ext
import omni.kit.ui
import omni.kit.menu.utils
from functools import partial
from omni.kit.menu.utils import MenuItemDescription, MenuItemOrder
from .create_actions import register_actions, deregister_actions, get_action_name, get_geometry_standard_prim_list, get_audio_prim_list, get_light_prim_list


_extension_instance = None
_extension_path = None

PERSISTENT_SETTINGS_PREFIX = "/persistent"


class CreateMenuExtension(omni.ext.IExt):
    def __init__(self):
        super().__init__()
        omni.kit.menu.utils.set_default_menu_proirity("Create", -8)

    def on_startup(self, ext_id):
        global _extension_instance
        _extension_instance = self

        global _extension_path
        _extension_path = omni.kit.app.get_app_interface().get_extension_manager().get_extension_path(ext_id)

        self._settings = carb.settings.get_settings()
        self._settings.set_default_bool(PERSISTENT_SETTINGS_PREFIX + "/app/primCreation/highQuality", True)
        self._create_menu_list = None
        self._build_create_menu()

        self._ext_name = omni.ext.get_extension_name(ext_id)
        register_actions(self._ext_name, CreateMenuExtension, lambda: _extension_instance)

    def on_shutdown(self):
        global _extension_instance

        deregister_actions(self._ext_name)
        _extension_instance = None
        omni.kit.menu.utils.remove_menu_items(self._create_menu_list, "Create")

    def _rebuild_menus(self):
        omni.kit.menu.utils.remove_menu_items(self._create_menu_list, "Create")
        self._build_create_menu()

    def _high_quality_option_toggle(self):
        enabled = self._settings.get(PERSISTENT_SETTINGS_PREFIX + "/app/primCreation/highQuality")
        self._settings.set(PERSISTENT_SETTINGS_PREFIX + "/app/primCreation/highQuality", not enabled)

    def _build_create_menu(self):
        def is_create_type_enabled(type: str):
            settings = carb.settings.get_settings()
            if type == "Shape":
                if settings.get("/app/primCreation/hideShapes") == True or \
                   settings.get("/app/primCreation/enableMenuShape") == False:
                       return False
                return True
            enabled = settings.get(f"/app/primCreation/enableMenu{type}")
            if enabled == True or enabled == False:
                return enabled
            return True


        # setup menus
        self._create_menu_list = []

        # Shapes
        if is_create_type_enabled("Shape"):
            sub_menu = []
            for prim in get_geometry_standard_prim_list().keys():
                sub_menu.append(
                    MenuItemDescription(name=prim, onclick_action=("omni.kit.menu.create", f"create_prim_{prim.lower()}"))
                )

            def on_high_quality_option_select():
                enabled = self._settings.get(PERSISTENT_SETTINGS_PREFIX + "/app/primCreation/highQuality")
                self._settings.set(PERSISTENT_SETTINGS_PREFIX + "/app/primCreation/highQuality", not enabled)

            def on_high_quality_option_checked():
                enabled = self._settings.get(PERSISTENT_SETTINGS_PREFIX + "/app/primCreation/highQuality")
                return enabled

            sub_menu.append(MenuItemDescription())
            sub_menu.append(
                MenuItemDescription(
                    name="High Quality",
                    onclick_action=("omni.kit.menu.create", "high_quality_option_toggle"),
                    ticked_fn=lambda: on_high_quality_option_checked()
                )
            )

            self._create_menu_list.append(
                MenuItemDescription(name="Shape", glyph="menu_prim.svg", appear_after=["Mesh", MenuItemOrder.FIRST], sub_menu=sub_menu)
            )

        # Lights
        if is_create_type_enabled("Light"):
            sub_menu = []
            for name, prim, attrs in get_light_prim_list():
                sub_menu.append(
                    MenuItemDescription(name=name, onclick_action=("omni.kit.menu.create", f"create_prim_{get_action_name(name)}")
                    )
                )
            if is_create_type_enabled("Shape"):
                appear_after="Shape"
            else:
                appear_after="Mesh"
            self._create_menu_list.append(
                MenuItemDescription(name="Light", glyph="menu_light.svg", appear_after=appear_after, sub_menu=sub_menu)
            )

        # Audio
        if is_create_type_enabled("Audio"):
            sub_menu = []
            for name, prim, attrs in get_audio_prim_list():
                sub_menu.append(
                    MenuItemDescription(
                        name=name, onclick_action=("omni.kit.menu.create", f"create_prim_{get_action_name(name)}")
                    )
                )
            self._create_menu_list.append(
                MenuItemDescription(name="Audio", glyph="menu_audio.svg", appear_after="Light", sub_menu=sub_menu)
            )

        # Camera
        if is_create_type_enabled("Camera"):
            self._create_menu_list.append(
                MenuItemDescription(
                    name="Camera",
                    glyph="menu_camera.svg",
                    appear_after="Audio",
                    onclick_action=("omni.kit.menu.create", "create_prim_camera"),
                )
            )

        # Scope
        if is_create_type_enabled("Scope"):
            self._create_menu_list.append(
                MenuItemDescription(
                    name="Scope",
                    glyph="menu_scope.svg",
                    appear_after="Camera",
                    onclick_action=("omni.kit.menu.create", "create_prim_scope"),
                )
            )

        # Xform
        if is_create_type_enabled("Xform"):
            self._create_menu_list.append(
                MenuItemDescription(
                    name="Xform",
                    glyph="menu_xform.svg",
                    appear_after="Scope",
                    onclick_action=("omni.kit.menu.create", "create_prim_xform"),
                )
            )

        if self._create_menu_list:
            omni.kit.menu.utils.add_menu_items(self._create_menu_list, "Create", -8)

    def on_create_prim(prim_type, attributes, use_settings: bool = False):
        usd_context = omni.usd.get_context()
        with omni.kit.usd.layers.active_authoring_layer_context(usd_context):
            omni.kit.commands.execute("CreatePrimWithDefaultXform", prim_type=prim_type, attributes=attributes)

    def on_create_light(light_type, attributes):
        usd_context = omni.usd.get_context()
        with omni.kit.usd.layers.active_authoring_layer_context(usd_context):
            omni.kit.commands.execute("CreatePrim", prim_type=light_type, attributes=attributes)

    def on_create_prims():
        usd_context = omni.usd.get_context()
        with omni.kit.usd.layers.active_authoring_layer_context(usd_context):
            omni.kit.commands.execute("CreatePrims", prim_types=["Cone", "Cylinder", "Cone"])


def get_extension_path(sub_directory):
    global _extension_path
    path = _extension_path
    if sub_directory:
        path = os.path.normpath(os.path.join(path, sub_directory))
    return path

def rebuild_menus():
    if _extension_instance:
        _extension_instance._rebuild_menus()

