# 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.
#

import carb
import omni.ext
import omni.kit.app
import omni.usd
import weakref

from pathlib import Path
from pxr import Sdf, UsdGeom
from typing import List
from .layer_property_widgets import LayerPathWidget, LayerMetaWiget

ICON_PATH = ""


_instance = None


def get_instance():
    global _instance
    return _instance


class LayerPropertyWidgets(omni.ext.IExt):
    def __init__(self):
        self._registered = False
        self._examples = None
        self._selection_notifiers = []
        super().__init__()

    def on_startup(self, ext_id):
        global _instance
        _instance = self

        manager = omni.kit.app.get_app().get_extension_manager()
        extension_path = manager.get_extension_path(ext_id)
        global ICON_PATH
        ICON_PATH = Path(extension_path).joinpath("data").joinpath("icons")
        self._selection_notifiers.append(SelectionNotifier())  # default context
        self._hooks = manager.subscribe_to_extension_enable(
            lambda _: self._register_widget(),
            lambda _: self._unregister_widget(),
            ext_name="omni.kit.window.property",
            hook_name="omni.kit.property.layer listener",
        )

    def on_shutdown(self):
        global _instance
        if _instance:
            _instance = None

        for notifier in self._selection_notifiers:
            notifier.stop()
        self._selection_notifiers.clear()
        self._hooks = None

        if self._registered:
            self._unregister_widget()

    def _register_widget(self):
        try:
            import omni.kit.window.property as p
            from .layer_property_widgets import LayerPathWidget, LayerMetaWiget

            w = p.get_window()
            self._layer_path_widget = LayerPathWidget(ICON_PATH)
            self._meta_widget = LayerMetaWiget(ICON_PATH)
            if w:
                w.register_widget("layers", "path", self._layer_path_widget)
                w.register_widget("layers", "metadata", self._meta_widget)

                for notifier in self._selection_notifiers:
                    notifier.start()
                    # notifier._notify_layer_selection_changed(None)  # force a refresh
                self._registered = True
        except Exception as exc:
            carb.log_warn(f"error {exc}")

    def _unregister_widget(self):
        try:
            import omni.kit.window.property as p

            w = p.get_window()
            if w:
                for notifier in self._selection_notifiers:
                    notifier.stop()
                w.unregister_widget("layers", "metadata")
                w.unregister_widget("layers", "path")
                self._registered = False
            if self._layer_path_widget:
                self._layer_path_widget.destroy()
            self._layer_path_widget = None
            self._meta_widget = None
        except Exception as e:
            carb.log_warn(f"Unable to unregister omni.kit.property.layer.widgets: {e}")


class SelectionNotifier:
    def __init__(self, property_window_context_id=""):
        self._property_window_context_id = property_window_context_id

    def start(self):
        layers_widget = self.get_layers_widget()
        if layers_widget:
            layers_widget.add_layer_selection_changed_fn(self._notify_layer_selection_changed)

    def get_layers_widget(self):
        return omni.kit.widget.layers.get_instance()

    def stop(self):
        layers_widget = self.get_layers_widget()
        if layers_widget:
            layers_widget.remove_layer_selection_changed_fn(self._notify_layer_selection_changed)

    def _notify_layer_selection_changed(self, item):
        import omni.kit.window.property as p

        # TODO _property_window_context_id
        w = p.get_window()
        if w and self.get_layers_widget():
            layer_item = self.get_layers_widget().get_current_focused_layer_item()
            if layer_item:
                w.notify("layers", weakref.ref(layer_item))
            else:
                w.notify("layers", None)
