# 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__ = ["ScriptEditorWindow"]

import omni.ui as ui

from .._script_editor import ScriptEditorWidget
from .script_editor_menu import MenuOptions

from omni.kit.actions.core import get_action_registry
import omni.kit.hotkeys.core as hotkeys

_DEFAULT_HOTKEY_MAP = {
    "Open": "ALT+O",
    "Save": "ALT+S",
    "Save As": "SHIFT+ALT+S",
}


class ScriptEditorWindow(ui.Window):
    """The Script Editor window"""

    def __init__(self):
        self._title = "Script Editor"

        super().__init__(
            self._title,
            width=800,
            height=600,
            flags=ui.WINDOW_FLAGS_MENU_BAR,
            raster_policy=ui.RasterPolicy.NEVER
        )

        self._visiblity_changed_listener = None
        self.set_visibility_changed_fn(self._visibility_changed_fn)
        with self.frame:
            self._script_editor_widget = ScriptEditorWidget()

        with self.menu_bar:
            self._menu_option = MenuOptions(
                load_data=self.load_data,
                save_data=self.save_data,
                get_file_path=self.get_file_path,
            )
            with ui.Menu("File"):
                ui.MenuItem("Open", hotkey_text="Alt + O", triggered_fn=self._menu_option.menu_open)
                ui.MenuItem("Save", hotkey_text="Alt + S", triggered_fn=self._menu_option.menu_save)
                ui.MenuItem("Save As...", hotkey_text="Shift + Alt + S", triggered_fn=self._menu_option.menu_save_as)

    def register_actions(self, extension_id: str):
        action_registry = get_action_registry()
        actions_tag = "Script Editor File Actions"

        action_registry.register_action(
            extension_id,
            "Open",
            self._menu_option.menu_open,
            display_name="Open",
            description="Open a script",
            tag=actions_tag,
        )
        action_registry.register_action(
            extension_id,
            "Save",
            self._menu_option.menu_save,
            display_name="Save",
            description="Save the script from the current tab to a file",
            tag=actions_tag,
        )
        action_registry.register_action(
            extension_id,
            "Save As",
            self._menu_option.menu_save_as,
            display_name="Save As...",
            description="Save the script from the current tab as a file",
            tag=actions_tag,
        )

    def deregister_actions(self, extension_id):
        action_registry = get_action_registry()
        action_registry.deregister_all_actions_for_extension(extension_id)

    def register_hotkeys(self, extension_id: str):
        hotkey_registry = hotkeys.get_hotkey_registry()
        action_registry = get_action_registry()
        ext_actions = action_registry.get_all_actions_for_extension(extension_id)

        for action in ext_actions:
            key = _DEFAULT_HOTKEY_MAP.get(action.id, None)
            # Not all Actions will have default hotkeys
            if not key:
                continue

            hotkey_registry.register_hotkey(
                hotkey_ext_id=extension_id,
                key=key,
                action_ext_id=action.extension_id,
                action_id=action.id,
                filter=None,
            )

    def deregister_hotkeys(self, extension_id: str):
        hotkey_registry = hotkeys.get_hotkey_registry()
        hotkey_registry.deregister_all_hotkeys_for_extension(extension_id)

    def load_data(self, filename, data):
        self._script_editor_widget.load_script(filename, data)

    def save_data(self, filename):
        return self._script_editor_widget.save_script(filename)

    def clear_data(self):
        self._script_editor_widget.clear_script()

    def get_file_path(self):
        return self._script_editor_widget.get_script_path()

    def _visibility_changed_fn(self, visible):
        if self._visiblity_changed_listener:
            self._visiblity_changed_listener(visible)

    def set_visibility_changed_listener(self, listener):
        self._visiblity_changed_listener = listener

    def destroy(self):
        """
        Called by extension before destroying this object. It doesn't happen automatically.
        Without this hot reloading doesn't work.
        """
        if self._script_editor_widget:
            self._script_editor_widget.destroy()
            self._script_editor_widget = None
        self._visiblity_changed_listener = None
        super().destroy()
