# Copyright (c) 2022, 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.
#

import omni.ext
import omni.kit.app
import carb


class ViewportReadyExtension(omni.ext.IExt):
    def on_startup(self, ext_id):
        self.__vp_ready = None
        self.__vp_extension_hooks = None
        # Create a default ready-delegate when exts/omni.kit.viewport.ready/startup/enabled is set
        if carb.settings.get_settings().get("exts/omni.kit.viewport.ready/startup/enabled"):
            manager = omni.kit.app.get_app().get_extension_manager()
            self.__vp_extension_hooks = (
                manager.subscribe_to_extension_enable(
                    self._create_viewport_ready,
                    self._remove_viewport_ready,
                    ext_name="omni.kit.window.viewport",
                    hook_name="omni.kit.viewport.ready.LoadListener-1",
                ),
                manager.subscribe_to_extension_enable(
                    self._create_viewport_ready,
                    self._remove_viewport_ready,
                    ext_name="omni.kit.viewport.window",
                    hook_name="omni.kit.viewport.ready.LoadListener-2",
                )
            )

    def on_shutdown(self):
        self._remove_viewport_ready()

    def _create_viewport_ready(self, *args):
        async def viewport_ready_ui():
            # Honor setting to force this message to only ever show once in a session if requested.
            # This needs to happen in the async loop as subscribe_to_extension_enable can call _create_viewport_ready
            # before it has returned and assigend hooks to self.__vp_extension_hooks
            settings = carb.settings.get_settings()
            show_once = bool(settings.get("exts/omni.kit.viewport.ready/startup/show_once"))
            if show_once:
                self.__vp_extension_hooks = None

            import omni.ui
            from .viewport_ready import ViewportReady, ViewportReadyDelegate
            max_wait = 100
            viewport_name = settings.get("exts/omni.kit.viewport.ready/startup/viewport") or "Viewport"
            viewport_window = omni.ui.Workspace.get_window(viewport_name)
            while viewport_window is None and max_wait:
                await omni.kit.app.get_app().next_update_async()
                viewport_window = omni.ui.Workspace.get_window(viewport_name)
                max_wait = max_wait - 1

            # Create a simple delegate that responds to on_complete and clears the objects created
            class DefaultDelegate(ViewportReadyDelegate):
                def on_complete(delegate_self):
                    # self is ViewportReadyExtension instance
                    self.__vp_ready = None
                    super().on_complete()

            self.__vp_ready = ViewportReady(DefaultDelegate())

        import asyncio
        asyncio.ensure_future(viewport_ready_ui())

    def _remove_viewport_ready(self, *args):
        self.__vp_ready = None
        self.__vp_extension_hooks = None
