# theme_2.py
"""
Theming support for manual_slop GUI — imgui-bundle port.

Replaces theme.py (DearPyGui-specific) with imgui-bundle equivalents.
Palettes are applied via imgui.get_style().set_color_() calls.
Font loading uses hello_imgui.load_font().
Scale uses imgui.get_style().font_scale_main.
"""

from imgui_bundle import imgui, hello_imgui
from pathlib import Path

# ------------------------------------------------------------------ palettes

# Each palette maps imgui color enum values to (R, G, B, A) floats [0..1].
# Only keys that differ from the ImGui dark defaults need to be listed.

def _c(r, g, b, a=255):
    """Convert 0-255 RGBA to 0.0-1.0 floats."""
    return (r / 255.0, g / 255.0, b / 255.0, a / 255.0)


_PALETTES: dict[str, dict[int, tuple]] = {

    "ImGui Dark": {},  # empty = use imgui dark defaults

    "10x Dark": {
        imgui.Col_.window_bg:               _c( 34,  32,  28),
        imgui.Col_.child_bg:                _c( 30,  28,  24),
        imgui.Col_.popup_bg:                _c( 35,  30,  20),
        imgui.Col_.border:                  _c( 60,  55,  50),
        imgui.Col_.border_shadow:           _c(  0,   0,   0,   0),
        imgui.Col_.frame_bg:                _c( 45,  42,  38),
        imgui.Col_.frame_bg_hovered:        _c( 60,  56,  50),
        imgui.Col_.frame_bg_active:         _c( 75,  70,  62),
        imgui.Col_.title_bg:                _c( 40,  35,  25),
        imgui.Col_.title_bg_active:         _c( 60,  45,  15),
        imgui.Col_.title_bg_collapsed:      _c( 30,  27,  20),
        imgui.Col_.menu_bar_bg:             _c( 35,  30,  20),
        imgui.Col_.scrollbar_bg:            _c( 30,  28,  24),
        imgui.Col_.scrollbar_grab:          _c( 80,  78,  72),
        imgui.Col_.scrollbar_grab_hovered:  _c(100, 100,  92),
        imgui.Col_.scrollbar_grab_active:   _c(120, 118, 110),
        imgui.Col_.check_mark:              _c(194, 164,  74),
        imgui.Col_.slider_grab:             _c(126,  78,  14),
        imgui.Col_.slider_grab_active:      _c(194, 140,  30),
        imgui.Col_.button:                  _c( 83,  76,  60),
        imgui.Col_.button_hovered:          _c(126,  78,  14),
        imgui.Col_.button_active:           _c(115,  90,  70),
        imgui.Col_.header:                  _c( 83,  76,  60),
        imgui.Col_.header_hovered:          _c(126,  78,  14),
        imgui.Col_.header_active:           _c(115,  90,  70),
        imgui.Col_.separator:               _c( 70,  65,  55),
        imgui.Col_.separator_hovered:       _c(126,  78,  14),
        imgui.Col_.separator_active:        _c(194, 164,  74),
        imgui.Col_.resize_grip:             _c( 60,  55,  44),
        imgui.Col_.resize_grip_hovered:     _c(126,  78,  14),
        imgui.Col_.resize_grip_active:      _c(194, 164,  74),
        imgui.Col_.tab:                     _c( 83,  83,  70),
        imgui.Col_.tab_hovered:             _c(126,  77,  25),
        imgui.Col_.tab_selected:            _c(126,  77,  25),
        imgui.Col_.tab_dimmed:              _c( 60,  58,  50),
        imgui.Col_.tab_dimmed_selected:     _c( 90,  80,  55),
        imgui.Col_.docking_preview:         _c(126,  78,  14, 180),
        imgui.Col_.docking_empty_bg:        _c( 20,  20,  20),
        imgui.Col_.text:                    _c(200, 200, 200),
        imgui.Col_.text_disabled:           _c(130, 130, 120),
        imgui.Col_.text_selected_bg:        _c( 59,  86, 142, 180),
        imgui.Col_.table_header_bg:         _c( 55,  50,  38),
        imgui.Col_.table_border_strong:     _c( 70,  65,  55),
        imgui.Col_.table_border_light:      _c( 50,  47,  42),
        imgui.Col_.table_row_bg:            _c(  0,   0,   0,   0),
        imgui.Col_.table_row_bg_alt:        _c( 40,  38,  34,  40),
        imgui.Col_.nav_cursor:           _c(126,  78,  14),
        imgui.Col_.nav_windowing_highlight: _c(194, 164,  74, 180),
        imgui.Col_.nav_windowing_dim_bg:    _c( 20,  20,  20,  80),
        imgui.Col_.modal_window_dim_bg:     _c( 10,  10,  10, 100),
    },

    "Nord Dark": {
        imgui.Col_.window_bg:               _c( 36,  41,  49),
        imgui.Col_.child_bg:                _c( 30,  34,  42),
        imgui.Col_.popup_bg:                _c( 36,  41,  49),
        imgui.Col_.border:                  _c( 59,  66,  82),
        imgui.Col_.border_shadow:           _c(  0,   0,   0,   0),
        imgui.Col_.frame_bg:                _c( 46,  52,  64),
        imgui.Col_.frame_bg_hovered:        _c( 59,  66,  82),
        imgui.Col_.frame_bg_active:         _c( 67,  76,  94),
        imgui.Col_.title_bg:                _c( 36,  41,  49),
        imgui.Col_.title_bg_active:         _c( 59,  66,  82),
        imgui.Col_.title_bg_collapsed:      _c( 30,  34,  42),
        imgui.Col_.menu_bar_bg:             _c( 46,  52,  64),
        imgui.Col_.scrollbar_bg:            _c( 30,  34,  42),
        imgui.Col_.scrollbar_grab:          _c( 76,  86, 106),
        imgui.Col_.scrollbar_grab_hovered:  _c( 94, 129, 172),
        imgui.Col_.scrollbar_grab_active:   _c(129, 161, 193),
        imgui.Col_.check_mark:              _c(136, 192, 208),
        imgui.Col_.slider_grab:             _c( 94, 129, 172),
        imgui.Col_.slider_grab_active:      _c(129, 161, 193),
        imgui.Col_.button:                  _c( 59,  66,  82),
        imgui.Col_.button_hovered:          _c( 94, 129, 172),
        imgui.Col_.button_active:           _c(129, 161, 193),
        imgui.Col_.header:                  _c( 59,  66,  82),
        imgui.Col_.header_hovered:          _c( 94, 129, 172),
        imgui.Col_.header_active:           _c(129, 161, 193),
        imgui.Col_.separator:               _c( 59,  66,  82),
        imgui.Col_.separator_hovered:       _c( 94, 129, 172),
        imgui.Col_.separator_active:        _c(136, 192, 208),
        imgui.Col_.resize_grip:             _c( 59,  66,  82),
        imgui.Col_.resize_grip_hovered:     _c( 94, 129, 172),
        imgui.Col_.resize_grip_active:      _c(136, 192, 208),
        imgui.Col_.tab:                     _c( 46,  52,  64),
        imgui.Col_.tab_hovered:             _c( 94, 129, 172),
        imgui.Col_.tab_selected:            _c( 76,  86, 106),
        imgui.Col_.tab_dimmed:              _c( 36,  41,  49),
        imgui.Col_.tab_dimmed_selected:     _c( 59,  66,  82),
        imgui.Col_.docking_preview:         _c( 94, 129, 172, 180),
        imgui.Col_.docking_empty_bg:        _c( 20,  22,  28),
        imgui.Col_.text:                    _c(216, 222, 233),
        imgui.Col_.text_disabled:           _c(116, 128, 150),
        imgui.Col_.text_selected_bg:        _c( 94, 129, 172, 180),
        imgui.Col_.table_header_bg:         _c( 59,  66,  82),
        imgui.Col_.table_border_strong:     _c( 76,  86, 106),
        imgui.Col_.table_border_light:      _c( 59,  66,  82),
        imgui.Col_.table_row_bg:            _c(  0,   0,   0,   0),
        imgui.Col_.table_row_bg_alt:        _c( 46,  52,  64,  40),
        imgui.Col_.nav_cursor:           _c(136, 192, 208),
        imgui.Col_.modal_window_dim_bg:     _c( 10,  12,  16, 100),
    },

    "Monokai": {
        imgui.Col_.window_bg:               _c( 39,  40,  34),
        imgui.Col_.child_bg:                _c( 34,  35,  29),
        imgui.Col_.popup_bg:                _c( 39,  40,  34),
        imgui.Col_.border:                  _c( 60,  61,  52),
        imgui.Col_.border_shadow:           _c(  0,   0,   0,   0),
        imgui.Col_.frame_bg:                _c( 50,  51,  44),
        imgui.Col_.frame_bg_hovered:        _c( 65,  67,  56),
        imgui.Col_.frame_bg_active:         _c( 80,  82,  68),
        imgui.Col_.title_bg:                _c( 39,  40,  34),
        imgui.Col_.title_bg_active:         _c( 73,  72,  62),
        imgui.Col_.title_bg_collapsed:      _c( 30,  31,  26),
        imgui.Col_.menu_bar_bg:             _c( 50,  51,  44),
        imgui.Col_.scrollbar_bg:            _c( 34,  35,  29),
        imgui.Col_.scrollbar_grab:          _c( 80,  80,  72),
        imgui.Col_.scrollbar_grab_hovered:  _c(102, 217,  39),
        imgui.Col_.scrollbar_grab_active:   _c(166, 226,  46),
        imgui.Col_.check_mark:              _c(166, 226,  46),
        imgui.Col_.slider_grab:             _c(102, 217,  39),
        imgui.Col_.slider_grab_active:      _c(166, 226,  46),
        imgui.Col_.button:                  _c( 73,  72,  62),
        imgui.Col_.button_hovered:          _c(249,  38, 114),
        imgui.Col_.button_active:           _c(198,  30,  92),
        imgui.Col_.header:                  _c( 73,  72,  62),
        imgui.Col_.header_hovered:          _c(249,  38, 114),
        imgui.Col_.header_active:           _c(198,  30,  92),
        imgui.Col_.separator:               _c( 60,  61,  52),
        imgui.Col_.separator_hovered:       _c(249,  38, 114),
        imgui.Col_.separator_active:        _c(166, 226,  46),
        imgui.Col_.resize_grip:             _c( 73,  72,  62),
        imgui.Col_.resize_grip_hovered:     _c(249,  38, 114),
        imgui.Col_.resize_grip_active:      _c(166, 226,  46),
        imgui.Col_.tab:                     _c( 73,  72,  62),
        imgui.Col_.tab_hovered:             _c(249,  38, 114),
        imgui.Col_.tab_selected:            _c(249,  38, 114),
        imgui.Col_.tab_dimmed:              _c( 50,  51,  44),
        imgui.Col_.tab_dimmed_selected:     _c( 90,  88,  76),
        imgui.Col_.docking_preview:         _c(249,  38, 114, 180),
        imgui.Col_.docking_empty_bg:        _c( 20,  20,  18),
        imgui.Col_.text:                    _c(248, 248, 242),
        imgui.Col_.text_disabled:           _c(117, 113,  94),
        imgui.Col_.text_selected_bg:        _c(249,  38, 114, 150),
        imgui.Col_.table_header_bg:         _c( 60,  61,  52),
        imgui.Col_.table_border_strong:     _c( 73,  72,  62),
        imgui.Col_.table_border_light:      _c( 55,  56,  48),
        imgui.Col_.table_row_bg:            _c(  0,   0,   0,   0),
        imgui.Col_.table_row_bg_alt:        _c( 50,  51,  44,  40),
        imgui.Col_.nav_cursor:           _c(166, 226,  46),
        imgui.Col_.modal_window_dim_bg:     _c( 10,  10,   8, 100),
    },
}

PALETTE_NAMES: list[str] = list(_PALETTES.keys())

# ------------------------------------------------------------------ state

_current_palette: str = "ImGui Dark"
_current_font_path: str = ""
_current_font_size: float = 16.0
_current_scale: float = 1.0
_custom_font: imgui.ImFont = None  # type: ignore


# ------------------------------------------------------------------ public API

def get_palette_names() -> list[str]:
    return list(_PALETTES.keys())


def get_current_palette() -> str:
    return _current_palette


def get_current_font_path() -> str:
    return _current_font_path


def get_current_font_size() -> float:
    return _current_font_size


def get_current_scale() -> float:
    return _current_scale


def apply(palette_name: str):
    """
    Apply a named palette by setting all ImGui style colors.
    Call this once per frame if you want dynamic switching, or once at startup.
    In practice we call it once when the user picks a palette, and imgui retains the style.
    """
    global _current_palette
    _current_palette = palette_name

    colours = _PALETTES.get(palette_name, {})

    if not colours:
        # Reset to imgui dark defaults
        imgui.style_colors_dark()
        return

    style = imgui.get_style()
    # Start from dark defaults so unlisted keys have sensible values
    imgui.style_colors_dark()
    for col_enum, rgba in colours.items():
        style.set_color_(col_enum, imgui.ImVec4(*rgba))


def set_scale(factor: float):
    """Set the global font/UI scale factor."""
    global _current_scale
    _current_scale = factor
    style = imgui.get_style()
    style.font_scale_main = factor


def save_to_config(config: dict):
    """Persist theme settings into the config dict under [theme]."""
    config.setdefault("theme", {})
    config["theme"]["palette"] = _current_palette
    config["theme"]["font_path"] = _current_font_path
    config["theme"]["font_size"] = _current_font_size
    config["theme"]["scale"] = _current_scale


def load_from_config(config: dict):
    """Read [theme] from config and apply palette + scale. Font is handled separately at startup."""
    global _current_font_path, _current_font_size, _current_scale, _current_palette
    t = config.get("theme", {})
    _current_palette = t.get("palette", "ImGui Dark")
    _current_font_path = t.get("font_path", "")
    _current_font_size = float(t.get("font_size", 16.0))
    _current_scale = float(t.get("scale", 1.0))

    # Don't apply here — imgui context may not exist yet.
    # Call apply_current() after imgui is initialised.


def apply_current():
    """Apply the loaded palette and scale. Call after imgui context exists."""
    apply(_current_palette)
    set_scale(_current_scale)


def get_font_loading_params() -> tuple[str, float]:
    """Return (font_path, font_size) for use during hello_imgui font loading callback."""
    return _current_font_path, _current_font_size
