import omni.ui as ui
import omni.kit.app


class ComboBoxListItem(ui.AbstractItem):
    """Single item of the model"""

    def __init__(self, text):
        super().__init__()
        self.name_model = ui.SimpleStringModel(text)
        # True when the item is visible
        self.filtered = True

    def prefilter(self, filter_name_text: str):
        if not filter_name_text:
            self.filtered = True
        else:
            self.filtered = filter_name_text in self.name_model.as_string.lower()

    def __repr__(self):
        return f'"{self.name_model.as_string}"'


class ComboBoxListModel(ui.AbstractItemModel):

    _instance = None

    def __init__(self, item_list):
        super().__init__()
        self._children = [ComboBoxListItem(item) for item in item_list]
        global _instance
        _instance = self

    def clean(self):
        global _instance
        _instance = None

    def get_item_children(self, item):
        """Returns all the children when the widget asks it."""
        if item is not None:
            return []
        return [c for c in self._children if c.filtered]

    def get_item_value_model_count(self, item):
        """The number of columns"""
        return 1

    def get_drag_mime_data(self, item):
        """Returns Multipurpose Internet Mail Extensions (MIME) data for be able to drop this item somewhere"""
        # As we don't do Drag and Drop to the operating system, we return the string.
        return item.name_model.as_string

    def get_item_value_model(self, item, column_id):
        return item.name_model

    def filter_by_text(self, filter_name_text: str):
        """Specify the filter string that is used to reduce the model"""
        for c in self._children:
            c.prefilter(filter_name_text.lower())
        self._item_changed(None)

    def get_index_for_item(self, item_text: str):
        for index, item in enumerate(self._children):
            if item.name_model.get_value_as_string() == item_text:
                return index
        return -1


class ComboBoxListDelegate(ui.AbstractItemDelegate):
    """
    Delegate is the representation layer. TreeView calls the methods
    of the delegate to create custom widgets for each item.
    """

    def __init__(self, flat=False):
        super().__init__()

    def clean(self):
        pass

    def build_branch(self, model, item, column_id, level, expanded):
        """Create a branch widget that opens or closes subtree"""
        pass

    def build_widget(self, model, item, column_id, level, expanded):
        ui.Label(
            model.get_item_value_model(item, column_id).as_string,
            skip_draw_when_clipped=True,
            elided_text=True,
            height=18,
        )
