# Copyright (c) 2023, 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.
#
__all__ = ["WelcomeWindowExtension"]

import asyncio
import carb
import omni.ext
import omni.ui as ui
from typing import Optional


class WelcomeWindowExtension(omni.ext.IExt):
    """The entry point for Welcome Window"""

    WINDOW_NAME = "Welcome Window"
    # MENU_PATH = f"Window/{WINDOW_NAME}"

    def on_startup(self):
        self.__window: Optional["WelcomeWindow"] = None
        self.__widget: Optional["WelcomeWidget"] = None
        self.__render_loading: Optional["ViewportReady"] = None

        self.show_welcome(True)

    def on_shutdown(self):
        self._menu = None
        if self.__window:
            self.__window.destroy()
            self.__window = None
        if self.__widget:
            self.__widget.destroy()
            self.__widget = None

    def show_welcome(self, visible: bool):
        in_viewport = carb.settings.get_settings().get("/exts/omni.kit.window.welcome/embedInViewport")
        if in_viewport and not self.__window:
            self.__show_widget(visible)
        else:
            self.__show_window(visible)

        if not visible and self.__render_loading:
            self.__render_loading = None

    def __get_buttons(self) -> dict:
        return {
            "Create Empty Scene": self.__create_empty_scene,
            "Open Last Saved Scene": None,
            "Browse Scenes": None
        }

    def __destroy_object(self, object):
        # Hide it immediately
        object.visible = False

        # And destroy it in the future
        async def destroy_object(object):
            await omni.kit.app.get_app().next_update_async()
            object.destroy()
        asyncio.ensure_future(destroy_object(object))

    def __show_window(self, visible: bool):
        if visible and self.__window is None:
            from .window import WelcomeWindow
            self.__window = WelcomeWindow(WelcomeWindowExtension.WINDOW_NAME, width=500, height=300, buttons=self.__get_buttons())
        elif self.__window and not visible:
            self.__destroy_object(self.__window)
            self.__window = None
        elif self.__window:
            self.__window.visible = True

    def __show_widget(self, visible: bool):
        if visible and self.__widget is None:
            async def add_to_viewport():
                try:
                    from omni.kit.viewport.utility import get_active_viewport_window
                    from .widget import WelcomeWidget

                    viewport_window = get_active_viewport_window()
                    with viewport_window.get_frame("omni.kit.window.welcome"):
                        self.__widget = WelcomeWidget(self.__get_buttons(), add_background=True)
                except (ImportError, AttributeError):
                    # Fallback to Welcome window
                    self.__show_window(visible)

            asyncio.ensure_future(add_to_viewport())
        elif self.__widget and not visible:
            self.__destroy_object(self.__widget)
            self.__widget = None
        elif self.__widget:
            self.__widget.visible = True

    def __button_clicked(self):
        self.show_welcome(False)

    def __create_empty_scene(self, renderer: Optional[str] = None):
        self.__button_clicked()

        settings = carb.settings.get_settings()
        ext_manager = omni.kit.app.get_app().get_extension_manager()
        if renderer is None:
            renderer = settings.get("/exts/omni.app.setup/backgroundRendererLoad/renderer")
            if not renderer:
                return

        ext_manager.set_extension_enabled_immediate("omni.kit.viewport.bundle", True)
        if renderer == "iray":
            ext_manager.set_extension_enabled_immediate(f"omni.hydra.rtx", True)
            ext_manager.set_extension_enabled_immediate(f"omni.hydra.{renderer}", True)
        else:
            ext_manager.set_extension_enabled_immediate(f"omni.kit.viewport.{renderer}", True)

        async def _new_stage_async():
            if settings.get("/exts/omni.kit.window.welcome/showRenderLoading"):
                from .render_loading import start_render_loading_ui
                self.__render_loading = start_render_loading_ui(ext_manager, renderer)

            await omni.kit.app.get_app().next_update_async()
            import omni.kit.stage_templates as stage_templates
            stage_templates.new_stage(template=None)

            await omni.kit.app.get_app().next_update_async()

            from omni.kit.viewport.utility import get_active_viewport
            get_active_viewport().set_hd_engine(renderer)

        asyncio.ensure_future(_new_stage_async())
