
__all__ = ["StyleTreeDelegate"]

import omni.ui as ui
from typing import Union

from .style_model import StyleGroupItem, StyleModel, StyleItem, StylePropertyType
from .widget_styles import ClassStyles

from pathlib import Path

ICON_PATH = Path(__file__).parent.parent.parent.parent.parent.parent.joinpath("icons")

LINE_COLOR = 0x00555555

STYLE_NAME_DEFAULT = {
    "Colors": {
        "background_color": 0xFFAAAAAA,
        "color": 0xFFAAAAAA,
        "secondary_color": 0xFFAAAAAA,
        "selected_color": 0xFFAAAAAA,
        "secondary_selected_color": 0xFFAAAAAA,
        "debug_color": 0xAAAAFFAA,
    },
    "Border": {"border_radius": 2.0, "border_width": 1.0, "border_color": 0xFFAAFFAA, "corner_flag": ui.CornerFlag.ALL},
    "Text": {"alignment": ui.Alignment.LEFT, "font_size": 16.0},
    "Images": {"image_url": "", "fill_policy": ui.FillPolicy.STRETCH},
    "-Margin-": {"margin": 0, "margin_width": 0, "margin_height": 0},
    "-Padding-": {"padding": 0, "padding_width": 0, "padding_height": 0},
    "-Misc-": {"secondary_padding": 0, "scrollbar_size": 10, "draw_mode": ui.SliderDrawMode.DRAG},
}


class StyleTreeDelegate(ui.AbstractItemDelegate):
    def __init__(self, model: StyleModel):
        super().__init__()

        self._add_menu = None
        self._model = model
        self._delete_menu = None
        self._delete_group_menu = None

    def _show_group_menu(self, b, item: StyleGroupItem):

        if not b == 1:
            return

        if not self._delete_group_menu:
            self._delete_group_menu = ui.Menu("Delete")

        self._delete_group_menu.clear()

        def duplicate_item():
            self._model.duplicate_item(item)

        def delete_item():
            self._model.delete_item(item)

        with self._delete_group_menu:
            ui.MenuItem("Delete", triggered_fn=delete_item)
            ui.MenuItem("Duplicate", triggered_fn=duplicate_item)

        self._delete_group_menu.show()

    def _show_delete_menu(self, b, item: StyleItem):

        if not b == 1:
            return

        if not self._delete_menu:
            self._delete_menu = ui.Menu("Delete")

        self._delete_menu.clear()

        def delete_item():
            self._model.delete_item(item)

        with self._delete_menu:
            ui.MenuItem("Delete", triggered_fn=delete_item)

        self._delete_menu.show()

    def _show_add_menu(self, x, y, b, m, type: str, item: StyleGroupItem):

        if not self._add_menu:
            self._add_menu = ui.Menu("Add")

        # menu is dynamically built based on type
        self._add_menu.clear()

        def add_style(key, value):
            # this is capture by the closure
            item.style_dict[key] = value
            self._model._item_changed(item)
            self._model.update()

        # we extact the base type
        item_type = item.type_name.split(":")[0]
        if "." in item_type:
            item_type = item_type.split(".")[0]

        filtered_style = ClassStyles.get(item_type, None)

        def add_menu_item(name: str, default):
            if filtered_style and name not in filtered_style:
                return
            ui.MenuItem(name, triggered_fn=lambda key=name, value=default: add_style(key, value))

        with self._add_menu:
            for category, values in STYLE_NAME_DEFAULT.items():

                if category[0] == "-" or filtered_style:
                    ui.Separator()
                    for style, default in values.items():
                        add_menu_item(style, default)
                else:
                    with ui.Menu(category):
                        for style, default in values.items():
                            add_menu_item(style, default)

        self._add_menu.show()

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

            if isinstance(item, StyleGroupItem):
                with ui.VStack(height=0):
                    ui.Spacer(height=10)
                    with ui.ZStack(width=10 * (level + 1), height=0):
                        ui.Rectangle(height=25)
                        with ui.HStack(width=10 * (level + 1)):
                            ui.Spacer(height=10)
                            ui.Spacer()
                            if model.can_item_have_children(item):
                                with ui.VStack():
                                    ui.Spacer()
                                    image_name = "Minus" if expanded else "Plus"
                                    ui.Image(
                                        f"{ICON_PATH}/{image_name}.svg",
                                        width=10,
                                        height=10,
                                        style={"color": 0xFFCCCCCC},
                                    )
                                    ui.Spacer()
                                ui.Spacer(width=5)
            else:
                ui.Spacer(width=20)

    def build_widget(self, model, item: Union[StyleGroupItem, StyleItem], column_id: int, level, expanded):
        """Create a widget per column per item"""
        value_model: ui.AbstractValueModel = model.get_item_value_model(item, column_id)

        # some cells are empty
        if not value_model:
            ui.Spacer()
            return

        # Group Instance = Group Title and Add Button
        if isinstance(item, StyleGroupItem):
            with ui.VStack():
                # small Space before Group Title
                ui.Spacer(height=10)

                with ui.ZStack(
                    height=25, mouse_pressed_fn=lambda x, y, b, m, item=item: self._show_group_menu(b, item)
                ):
                    ui.Rectangle(style={"background_color": 0xFF222222})

                    with ui.HStack():
                        ui.Spacer(width=5)
                        with ui.VStack():
                            ui.Spacer()
                            ui.StringField(
                                value_model, height=20, style={"font_size": 16, "background_color": 0xFF222222}
                            )
                            ui.Spacer()
                        ui.Spacer(width=5)

                        group_type = model.get_item_value_model(item, 0).as_string
                        with ui.VStack(width=0):
                            ui.Spacer()
                            ui.Button(
                                image_url=f"{ICON_PATH}/Add.svg",
                                width=20,
                                height=20,
                                style={"background_color": 0xFF556655, "border_radius": 5},
                                mouse_pressed_fn=lambda x, y, b, m, type=group_type, item=item: self._show_add_menu(
                                    x, y, b, m, type, item
                                ),
                            )
                            ui.Spacer()
        # Style Property Row
        else:
            with ui.HStack(height=25, mouse_pressed_fn=lambda x, y, b, m, item=item: self._show_delete_menu(b, item)):
                ui.Spacer(width=5)

                with ui.VStack():
                    ui.Spacer()
                    ui.Label(
                        value_model.as_string,
                        height=0,
                        style={"font_size": 14, "alignment": ui.Alignment.RIGHT_CENTER, "margin_width": 5},
                    )
                    ui.Spacer()

                # Value Model for the Second Columns
                value_model: ui.AbstractValueModel = model.get_item_value_model(item, 1)

                with ui.VStack():
                    ui.Spacer()
                    with ui.HStack(height=0):
                        # key: str = model.get_item_value_model(item, 0).as_string
                        if item.style_type == StylePropertyType.COLOR:
                            # color_model = StyleColorModel(value_model.as_int)
                            ui.ColorWidget(value_model, width=12, height=12)
                        elif item.style_type == StylePropertyType.FLOAT:
                            ui.FloatDrag(value_model).step = 1
                        elif item.style_type == StylePropertyType.STRING:
                            ui.StringField(value_model)
                        elif item.style_type == StylePropertyType.ENUM:
                            ui.ComboBox(value_model)
                        ui.Spacer(width=20)
                    ui.Spacer()
