from typing import List

import omni.ui as ui

from .option_item import OptionItem

class OptionsModel(ui.AbstractItemModel):
    """
    Model for options items.

    Args:
        name (str): Model name to display in menu header.
        items (List[OptionItem]): Items to show in menu.
    """
    def __init__(self, name: str, items: List[OptionItem]):
        self.name = name
        self._items = items
        self.__subs = {}
        for item in self._items:
            if item.name:
                self.__subs[item] = item.model.subscribe_value_changed_fn(lambda m, i=item: self.__on_value_changed(i, m))
        super().__init__()

    def destroy(self):
        self.__subs.clear()

    @property
    def dirty(self) -> bool:
        """
        Flag if any item not in default value.
        """
        for item in self._items:
            if item.dirty:
                return True
        return False
    
    def rebuild_items(self, items: List[OptionItem]) -> None:
        """
        Rebuild option items.

        Args:
            items (List[OptionItem]): Items to show in menu.
        """
        self.__subs.clear()
        self._items = items
        for item in self._items:
            if item.name:
                self.__subs[item] = item.model.subscribe_value_changed_fn(lambda m, i=item: self.__on_value_changed(i, m))

        self._item_changed(None)
    
    def reset(self) -> None:
        """
        Reset all items to default value.
        """
        for item in self._items:
            item.reset()

    def get_item_children(self) -> List[OptionItem]:
        """
        Get items in this model.
        """
        return self._items
    
    def __on_value_changed(self, item: OptionItem, model: ui.SimpleBoolModel):
        self._item_changed(item)
