
__all__ = ["WidgetModel", "WidgetComboValueModel", "WidgetComboNameValueItem", "WidgetComboItemModel"]

from typing import Callable
import omni.ui as ui


class WidgetModel(ui.AbstractValueModel):
    """
    Model for widget Properties
    """

    def __init__(self, widget: ui.Widget, property: str, dragable=True):
        """
        Args:
        """
        super().__init__()

        self._widget = widget
        self._property = property

        self.initialValue = None
        self._reset_button = None
        self._editing = False

    # def _on_change(owner, value, event_type) -> None:
    #     if event_type == carb.settings.ChangeEventType.CHANGED:
    #         owner._on_dirty()
    #         if owner._editing == False:
    #             owner._update_reset_button()

    # def begin_edit(self) -> None:
    #     self._editing = True
    #     ui.AbstractValueModel.begin_edit(self)
    #     self.initialValue = self._settings.get(self._path)

    # def end_edit(self) -> None:
    #     ui.AbstractValueModel.end_edit(self)
    #     omni.kit.commands.execute(
    #         "ChangeSettingCommand", path=self._path, value=self._settings.get(self._path), prev=self.initialValue
    #     )
    #     self._update_reset_button()
    #     self._editing = False

    def get_value_as_string(self) -> str:
        return str(self._widget.__getattribute__(self._property))

    def get_value_as_float(self) -> float:
        return self._widget.__getattribute__(self._property)

    def get_value_as_bool(self) -> bool:
        return self._widget.__getattribute__(self._property)

    def get_value_as_int(self) -> int:
        # print("here int ")
        return self._widget.__getattribute__(self._property)

    def set_value(self, value):
        print(type(self._widget.__getattribute__(self._property)))
        if type(self._widget.__getattribute__(self._property)) == ui.Length:
            print("Is Length")
            self._widget.__setattr__(self._property, ui.Pixel(value))
        else:
            self._widget.__setattr__(self._property, value)
        self._value_changed()

    def destroy(self):
        self._widget = None
        self._reset_button = None


class WidgetComboValueModel(ui.AbstractValueModel):
    """
    Model to store a pair (label, value of arbitrary type) for use in a ComboBox
    """

    def __init__(self, key, value):
        """
        Args:
            value: the instance of the Style value
        """
        ui.AbstractValueModel.__init__(self)
        self.key = key
        self.value = value

    def __repr__(self):
        return f'"WidgetComboValueModel name:{self.key} value:{int(self.value)}"'

    def get_value_as_string(self) -> str:
        """
        this is called to get the label of the combo box item
        """
        return self.key

    def get_style_value(self) -> int:
        """
        we call this to get the value of the combo box item
        """
        return int(self.value)


class WidgetComboNameValueItem(ui.AbstractItem):
    def __init__(self, key, value):
        super().__init__()
        self.model = WidgetComboValueModel(key, value)

    def __repr__(self):
        return f'"StyleComboNameValueItem {self.model}"'


class WidgetComboItemModel(ui.AbstractItemModel):
    """
    Model for a combo box - for each setting we have  a dictionary of key, values
    """

    def __init__(self, widget: ui.Widget, property: str, class_obj: Callable):
        super().__init__()
        self._widget = widget
        self._property = property
        self._class = class_obj
        self._items = []
        self._default_value = self._widget.__getattribute__(property)

        default_index = 0
        current_index = 0
        for key, value in class_obj.__members__.items():
            if self._default_value == value:
                default_index = current_index
            self._items.append(WidgetComboNameValueItem(key, value))
            current_index += 1

        self._current_index = ui.SimpleIntModel(default_index)
        self._current_index.add_value_changed_fn(self._current_index_changed)

    def get_current_value(self):
        return self._items[self._current_index.as_int].model.get_style_value()

    def _current_index_changed(self, model):
        self._item_changed(None)
        value = self.get_current_value()
        self._widget.__setattr__(self._property, self._class(value))

    def get_item_children(self, item):
        return self._items

    def get_item_value_model(self, item, column_id: int):
        if item is None:
            return self._current_index
        return item.model
