# Copyright (c) 2018-2021, 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__ = ["ScriptEditorExtension"]

import asyncio
import omni.ext
import omni.kit.ui
import omni.ui as ui
from functools import partial

from .script_editor_window import ScriptEditorWindow


class ScriptEditorExtension(omni.ext.IExt):
    """The entry point for Script Editor Window"""

    WINDOW_NAME = "Script Editor"
    MENU_PATH = f"Window/{WINDOW_NAME}"

    def on_startup(self, ext_id):
        self._ext_name = omni.ext.get_extension_name(ext_id)
        ui.Workspace.set_show_window_fn(ScriptEditorExtension.WINDOW_NAME, partial(self.show_window, None))

        editor_menu = omni.kit.ui.get_editor_menu()
        if editor_menu:
            # off by default
            self._menu = editor_menu.add_item(ScriptEditorExtension.MENU_PATH, self.show_window, toggle=True, value=False)

        self._window = None

    def on_shutdown(self):
        self._menu = None
        asyncio.ensure_future(self._destroy_window_async())

        ui.Workspace.set_show_window_fn(ScriptEditorExtension.WINDOW_NAME, None)

    def _set_menu(self, value):
        """Set the menu to create this window on and off"""
        editor_menu = omni.kit.ui.get_editor_menu()
        if editor_menu:
            editor_menu.set_value(ScriptEditorExtension.MENU_PATH, value)

    async def _destroy_window_async(self):
        # wait one frame, this is due to the one frame defer
        # in Window::_moveToMainOSWindow()
        await omni.kit.app.get_app().next_update_async()
        if self._window:
            self._window.deregister_hotkeys(self._ext_name)
            self._window.deregister_actions(self._ext_name)
            self._window.destroy()
        self._window = None

    def _visibility_changed_fn(self, visible):
        self._set_menu(visible)

    def show_window(self, menu, value):
        if value:
            if self._window:
                # If we already have the window hidden, just show it, rather than creating a new one
                self._window.visible = True
            else:
                self._window = ScriptEditorWindow()
                self._window.set_visibility_changed_listener(self._visibility_changed_fn)

                self._window.register_actions(self._ext_name)
                self._window.register_hotkeys(self._ext_name)

        elif self._window:
            self._window.visible = False
