# Copyright (c) 2021-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.
#
__all__ = ["ViewportMenuContainer"]

from ..viewport_menu_model import get_items, deregister
from ..viewport_menu_model import pop_from_scope
from ..viewport_menu_model import push_to_scope
from ..viewport_menu_model import ViewportMenuModel
from .viewport_menu_item import ViewportMenuItem
from typing import Dict
import omni.ui as ui


class ViewportMenuContainer(ViewportMenuItem):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # When visible and order changed, trigger UI updates
        self._visible_sub = self.visible_model.subscribe_value_changed_fn(lambda m: self._invalidate())
        self._order_sub = self.order_model.subscribe_value_changed_fn(lambda m: self._invalidate())

    def destroy(self):
        self._visible_sub = None
        self._order_sub = None

        # Clean children
        self._clean()

        super().destroy()

    def build_fn(self, factory: Dict):
        """Reimplement it to have own customized item"""
        children = self._children

        # TODO: Lazy menu
        with ui.Menu(self.name, delegate=self._delegate, style=self._style):
            for child in children:
                child.build_fn(factory)

    def __enter__(self):
        # Clean all existing child items
        # For multiple viewport window, menu contrainer may build multiple times
        # Make sure child items not duplicated
        self._clean()

        push_to_scope(self)

    def __exit__(self, exc_type, exc_value, traceback):
        pop_from_scope()

    @property
    def _children(self):
        # TODO: Sorting code
        return get_items(self.name)

    def _invalidate(self) -> None:
        ViewportMenuModel()._item_changed(None)

    def _clean(self):
        for child in self._children:
            child.destroy()