
__all__ = ["get_property_enum_class", "PropertyType", "create_property_widget"]

from typing import Tuple, Union, Callable
import omni.ui as ui
import enum

from .widget_model import WidgetModel, WidgetComboItemModel
from .widget_builder import PropertyWidgetBuilder


def get_property_enum_class(property: str) -> Callable:
    if property == "direction":
        return ui.Direction
    elif property == "alignment":
        return ui.Alignment
    elif property == "fill_policy":
        return ui.FillPolicy
    elif property == "arc":
        return ui.Alignment
    elif property == "size_policy":
        return ui.CircleSizePolicy
    elif property == "drag_axis":
        return ui.Axis
    else:
        return ui.Direction


class PropertyType(enum.Enum):
    FLOAT = 0
    INT = 1
    COLOR3 = 2
    BOOL = 3
    STRING = 4
    DOUBLE3 = 5
    INT2 = 6
    DOUBLE2 = 7
    ENUM = 8


#  TODO: Section will be moved to some location like omni.ui.settings
#  #############################################################################################
def create_property_widget(
    widget: ui.Widget, property: str, property_type: PropertyType, range_from=0, range_to=0, speed=1, **kwargs
) -> Tuple[Union[ui.Widget, None], Union[ui.AbstractValueModel, None]]:
    """
    Create a UI widget connected with a setting. 

    If ``range_from`` >= ``range_to`` there is no limit. Undo/redo operations are also supported, because changing setting
    goes through the :mod:`omni.kit.commands` module, using :class:`.ChangeSettingCommand`.

    Args:
        setting_path: Path to the setting to show and edit.
        property_type: Type of the setting to expect.
        range_from: Limit setting value lower bound.
        range_to: Limit setting value upper bound.

    Returns:
        :class:`ui.Widget` connected with the setting on the path specified.
    """
    property_widget: Union[ui.Widget, None] = None
    model = None
    # Create widget to be used for particular type
    if property_type == PropertyType.INT:
        model = WidgetModel(widget, property)
        property_widget = PropertyWidgetBuilder.createIntWidget(model, range_from, range_to, **kwargs)
    elif property_type == PropertyType.FLOAT:
        model = WidgetModel(widget, property)
        property_widget = PropertyWidgetBuilder.createFloatWidget(model, range_from, range_to, **kwargs)
    elif property_type == PropertyType.BOOL:
        model = WidgetModel(widget, property)
        property_widget = PropertyWidgetBuilder.createBoolWidget(model, **kwargs)
    elif property_type == PropertyType.STRING:
        model = WidgetModel(widget, property)
        property_widget = ui.StringField(**kwargs)
    elif property_type == PropertyType.ENUM:
        enum_cls = get_property_enum_class(property)
        model = WidgetComboItemModel(widget, property, enum_cls)
        property_widget = ui.ComboBox(model, **kwargs)
    else:
        print("Couldnt find widget for ", property_type, property)  # Do we have any right now?
        return property_widget, None

    if property_widget:
        try:
            property_widget.model = model
        except:
            print(widget, "doesn't have model")

    return property_widget, model
