# Copyright (c) 2020, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
#

from pathlib import Path
from carb import windowing, log_warn
import omni.ext
import weakref

EXTEND_CURSOR_GRAB_OPEN = "Grab_open"
EXTEND_CURSOR_GRAB_CLOSE = "Grab_close"
EXTEND_CURSOR_PAN_FILE = "cursorPan.png"
EXTEND_CURSOR_PAN_CLOSE_FILE = "cursorPanClosed.png"

main_window_cursor = None


def get_main_window_cursor():
    return main_window_cursor


def get_icon_path(path: str):
    extension_path = omni.kit.app.get_app().get_extension_manager().get_extension_path_by_module(__name__)
    icon_path = Path(extension_path).joinpath("data").joinpath("icons").joinpath(path)
    return str(icon_path)


class WindowCursor(omni.ext.IExt):
    def __init__(self):
        self._imgui_renderer = None
        self._app_window = None
        super().__init__()

    def on_startup(self, ext_id):
        global main_window_cursor
        main_window_cursor = weakref.proxy(self)

        try:
            import omni.kit.imgui_renderer
            import omni.appwindow
            self._imgui_renderer = omni.kit.imgui_renderer.acquire_imgui_renderer_interface()
            self._app_window = omni.appwindow.get_default_app_window()
        except Exception:
            # Currently need both of these for further API usage, which can't happen now; so clear them both out
            self._imgui_renderer, self._app_window = None, None
            log_warn("omni.kit.window.cursor failed to initialize properly, changing cursor with it will not work")
            import traceback
            log_warn(f"{traceback.format_exc()}")

        self._app_ready_sub = omni.kit.app.get_app().get_startup_event_stream().create_subscription_to_pop_by_type(
            omni.kit.app.EVENT_APP_READY,
            self._on_app_ready,
        )

    def on_shutdown(self):
        if self._imgui_renderer:
            self._imgui_renderer.unregister_cursor_shape_extend(EXTEND_CURSOR_GRAB_OPEN)
            self._imgui_renderer.unregister_cursor_shape_extend(EXTEND_CURSOR_GRAB_CLOSE)

        global main_window_cursor
        main_window_cursor = None

        self._imgui_renderer = None
        self._app_window = None
        self._app_ready_sub = None

    def _on_app_ready(self, event):
        if self._imgui_renderer:
            self._imgui_renderer.register_cursor_shape_extend(EXTEND_CURSOR_GRAB_OPEN, get_icon_path(EXTEND_CURSOR_PAN_FILE))
            self._imgui_renderer.register_cursor_shape_extend(EXTEND_CURSOR_GRAB_CLOSE, get_icon_path(EXTEND_CURSOR_PAN_CLOSE_FILE))


    def override_cursor_shape_extend(self, shape_name: str):
        if self._app_window and self._imgui_renderer:
            self._imgui_renderer.set_cursor_shape_override_extend(self._app_window, shape_name)
            return True
        return False

    def override_cursor_shape(self, shape: windowing.CursorStandardShape):
        if self._app_window and self._imgui_renderer:
            self._imgui_renderer.set_cursor_shape_override(self._app_window, shape)
            return True
        return False

    def clear_overridden_cursor_shape(self):
        if self._app_window and self._imgui_renderer:
            self._imgui_renderer.clear_cursor_shape_override(self._app_window)
            return True
        return False

    def get_cursor_shape_override_extend(self):
        if self._app_window and self._imgui_renderer:
            return self._imgui_renderer.get_cursor_shape_override_extend(self._app_window)
        return None

    def get_cursor_shape_override(self):
        if self._app_window and self._imgui_renderer:
            return self._imgui_renderer.get_cursor_shape_override(self._app_window)
        return None
