# 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 or hello_imgui.apply_theme().
Font loading uses hello_imgui.load_font().
Scale uses imgui.get_style().font_scale_main.
"""

from imgui_bundle import imgui, hello_imgui
from typing import Any, Optional
import src.theme_nerv

# ------------------------------------------------------------------ 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: int, g: int, b: int, a: int = 255) -> tuple[float, float, float, float]:
 """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
 "NERV": {},
 "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),
 },
 "Binks": {
  imgui.Col_.text:                    _c(  0,   0,   0, 255),
  imgui.Col_.text_disabled:           _c(153, 153, 153, 255),
  imgui.Col_.window_bg:               _c(240, 240, 240, 240),
  imgui.Col_.child_bg:                _c(  0,   0,   0,   0),
  imgui.Col_.popup_bg:                _c(255, 255, 255, 240),
  imgui.Col_.border:                  _c(  0,   0,   0,  99),
  imgui.Col_.border_shadow:           _c(255, 255, 255,  25),
  imgui.Col_.frame_bg:                _c(255, 255, 255, 240),
  imgui.Col_.frame_bg_hovered:        _c( 66, 150, 250, 102),
  imgui.Col_.frame_bg_active:         _c( 66, 150, 250, 171),
  imgui.Col_.title_bg:                _c(245, 245, 245, 255),
  imgui.Col_.title_bg_collapsed:      _c(255, 255, 255, 130),
  imgui.Col_.title_bg_active:         _c(209, 209, 209, 255),
  imgui.Col_.menu_bar_bg:             _c(219, 219, 219, 255),
  imgui.Col_.scrollbar_bg:            _c(250, 250, 250, 135),
  imgui.Col_.scrollbar_grab:          _c(176, 176, 176, 255),
  imgui.Col_.scrollbar_grab_hovered:  _c(150, 150, 150, 255),
  imgui.Col_.scrollbar_grab_active:   _c(125, 125, 125, 255),
  imgui.Col_.check_mark:              _c( 66, 150, 250, 255),
  imgui.Col_.slider_grab:             _c( 61, 133, 224, 255),
  imgui.Col_.slider_grab_active:      _c( 66, 150, 250, 255),
  imgui.Col_.button:                  _c( 66, 150, 250, 102),
  imgui.Col_.button_hovered:          _c( 66, 150, 250, 255),
  imgui.Col_.button_active:           _c( 15, 135, 250, 255),
  imgui.Col_.header:                  _c( 66, 150, 250,  79),
  imgui.Col_.header_hovered:          _c( 66, 150, 250, 204),
  imgui.Col_.header_active:           _c( 66, 150, 250, 255),
  imgui.Col_.separator:               _c(100, 100, 100, 255),
  imgui.Col_.resize_grip:             _c(255, 255, 255, 127),
  imgui.Col_.resize_grip_hovered:     _c( 66, 150, 250, 171),
  imgui.Col_.resize_grip_active:      _c( 66, 150, 250, 242),
  imgui.Col_.plot_lines:              _c( 99,  99,  99, 255),
  imgui.Col_.plot_lines_hovered:      _c(255, 110,  89, 255),
  imgui.Col_.plot_histogram:          _c(230, 178,   0, 255),
  imgui.Col_.plot_histogram_hovered:  _c(255, 153,   0, 255),
  imgui.Col_.text_selected_bg:        _c( 66, 150, 250,  89),
  imgui.Col_.modal_window_dim_bg:     _c( 51,  51,  51,  89),
 },
}

def get_palette_names() -> list[str]:
 """Returns a list of all available palettes, including hello_imgui built-ins."""
 names = list(_PALETTES.keys())
 # Add hello_imgui themes
 hi_themes = [name for name in dir(hello_imgui.ImGuiTheme_) if not name.startswith('_') and name != 'count']
 # Filter out int methods that leaked into dir() if any
 hi_themes = [n for n in hi_themes if not hasattr(int, n)]
 names.extend(sorted(hi_themes))
 return names

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

_current_palette: str = "10x Dark"
_current_font_path: str = "fonts/Inter-Regular.ttf"
_current_font_size: float = 16.0
_current_scale: float = 1.0
_transparency: float = 1.0
_child_transparency: float = 1.0

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

def get_current_palette() -> str:
 return _current_palette

def is_nerv_active() -> bool:
 return _current_palette == "NERV"

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 get_transparency() -> float:
 return _transparency

def set_transparency(val: float) -> None:
 global _transparency
 _transparency = val
 apply(_current_palette)

def get_child_transparency() -> float:
 return _child_transparency

def set_child_transparency(val: float) -> None:
 global _child_transparency
 _child_transparency = val
 apply(_current_palette)

def apply(palette_name: str) -> None:
 """
    Apply a named palette by setting all ImGui style colors and applying global professional styling.
    """
 global _current_palette
 _current_palette = palette_name
 if palette_name == 'NERV':
  src.theme_nerv.apply_nerv()
  return
 
 # 1. Apply base colors
 if palette_name in _PALETTES:
  colours = _PALETTES[palette_name]
  imgui.style_colors_dark()
  style = imgui.get_style()
  for col_enum, rgba in colours.items():
   style.set_color_(col_enum, imgui.ImVec4(*rgba))
 elif hasattr(hello_imgui.ImGuiTheme_, palette_name):
  theme_enum = getattr(hello_imgui.ImGuiTheme_, palette_name)
  hello_imgui.apply_theme(theme_enum)
 else:
  # Fallback to Nord Dark if requested but not found, otherwise ImGui Dark
  if palette_name == "Nord Dark":
   # This should not happen since it's in _PALETTES, but for safety
   imgui.style_colors_dark()
  else:
   imgui.style_colors_dark()

 # 2. Apply our "Subtle Rounding" professional tweaks on top of ANY theme
 style = imgui.get_style()
 style.window_rounding = 6.0
 style.child_rounding = 4.0
 style.frame_rounding = 4.0
 style.popup_rounding = 4.0
 style.scrollbar_rounding = 12.0
 style.grab_rounding = 4.0
 style.tab_rounding = 4.0
 style.window_border_size = 1.0
 style.frame_border_size = 1.0
 style.popup_border_size = 1.0
 
 # Apply transparency to WindowBg
 win_bg = style.color_(imgui.Col_.window_bg)
 win_bg.w = _transparency
 style.set_color_(imgui.Col_.window_bg, win_bg)
 
 # Apply child/frame transparency
 for col_idx in [imgui.Col_.child_bg, imgui.Col_.frame_bg, imgui.Col_.popup_bg]:
  c = style.color_(col_idx)
  c.w = _child_transparency
  style.set_color_(col_idx, c)
 
 # Spacing & Padding
 style.window_padding = imgui.ImVec2(8.0, 8.0)
 style.frame_padding = imgui.ImVec2(8.0, 4.0)
 style.item_spacing = imgui.ImVec2(8.0, 4.0)
 style.item_inner_spacing = imgui.ImVec2(4.0, 4.0)
 style.scrollbar_size = 14.0
 
 # Rendering anti-aliasing (Shaders/Quality)
 style.anti_aliased_lines = True
 style.anti_aliased_fill = True
 style.anti_aliased_lines_use_tex = True

def set_scale(factor: float) -> None:
 """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) -> None:
 """Persist theme settings into the config dict under [theme]."""
 import sys
 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
 config["theme"]["transparency"] = _transparency
 config["theme"]["child_transparency"] = _child_transparency
 sys.stderr.write(f"[DEBUG theme_2] save_to_config: palette={_current_palette}, transparency={_transparency}\n")
 sys.stderr.flush()

def load_from_config(config: dict) -> None:
 """Read [theme] from config. Font is handled separately at startup."""
 import sys
 global _current_font_path, _current_font_size, _current_scale, _current_palette, _transparency, _child_transparency
 t = config.get("theme", {})
 sys.stderr.write(f"[DEBUG theme_2] load_from_config raw: {t}\n")
 sys.stderr.flush()
 _current_palette = t.get("palette", "10x Dark")
 if _current_palette in ("", "DPG Default"):
  _current_palette = "10x Dark"
  
 _current_font_path = t.get("font_path", "fonts/Inter-Regular.ttf")
 _current_font_size = float(t.get("font_size", 16.0))
 _current_scale = float(t.get("scale", 1.0))
 _transparency = float(t.get("transparency", 1.0))
 _child_transparency = float(t.get("child_transparency", 1.0))
 sys.stderr.write(f"[DEBUG theme_2] load_from_config effective: palette={_current_palette}, transparency={_transparency}\n")
 sys.stderr.flush()

def apply_current() -> None:
 """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

def get_tweaked_theme() -> hello_imgui.ImGuiTweakedTheme:
 """Returns an ImGuiTweakedTheme object reflecting the current state."""
 tt = hello_imgui.ImGuiTweakedTheme()
 if hasattr(hello_imgui.ImGuiTheme_, _current_palette):
  tt.theme = getattr(hello_imgui.ImGuiTheme_, _current_palette)
 else:
  tt.theme = hello_imgui.ImGuiTheme_.imgui_colors_dark
 
 # Sync tweaks
 tt.tweaks.rounding = 6.0
 return tt

