#include "core/slider.h"
#include "core/tokens.h"
#include <imgui.h>
#include <cstdio>

namespace fn_ui {

static void push_slider_style() {
    using namespace fn_tokens;
    ImGui::PushStyleColor(ImGuiCol_FrameBg,        colors::bg);
    ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, colors::surface_hover);
    ImGui::PushStyleColor(ImGuiCol_FrameBgActive,  colors::surface);
    ImGui::PushStyleColor(ImGuiCol_Border,         colors::border);
    ImGui::PushStyleColor(ImGuiCol_SliderGrab,       colors::primary);
    ImGui::PushStyleColor(ImGuiCol_SliderGrabActive, colors::primary_hover);
    ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding,   radius::sm);
    ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
    ImGui::PushStyleVar(ImGuiStyleVar_GrabRounding,    radius::sm);
}

static void pop_slider_style() {
    ImGui::PopStyleVar(3);
    ImGui::PopStyleColor(6);
}

static void label_muted(const char* label) {
    using namespace fn_tokens;
    ImGui::PushStyleColor(ImGuiCol_Text, colors::text_muted);
    ImGui::TextUnformatted(label);
    ImGui::PopStyleColor();
}

bool slider_float(const char* label, float* value,
                  float min_v, float max_v, const char* fmt) {
    label_muted(label);
    push_slider_style();
    char id[160];
    std::snprintf(id, sizeof(id), "##%s", label);
    ImGui::SetNextItemWidth(-FLT_MIN);
    bool changed = ImGui::SliderFloat(id, value, min_v, max_v, fmt);
    pop_slider_style();
    return changed;
}

bool slider_float_log(const char* label, float* value,
                      float min_v, float max_v, const char* fmt) {
    label_muted(label);
    push_slider_style();
    char id[160];
    std::snprintf(id, sizeof(id), "##%s", label);
    ImGui::SetNextItemWidth(-FLT_MIN);
    bool changed = ImGui::SliderFloat(id, value, min_v, max_v, fmt,
                                      ImGuiSliderFlags_Logarithmic);
    pop_slider_style();
    return changed;
}

bool slider_int(const char* label, int* value,
                int min_v, int max_v, const char* fmt) {
    label_muted(label);
    push_slider_style();
    char id[160];
    std::snprintf(id, sizeof(id), "##%s", label);
    ImGui::SetNextItemWidth(-FLT_MIN);
    bool changed = ImGui::SliderInt(id, value, min_v, max_v, fmt);
    pop_slider_style();
    return changed;
}

bool slider_double(const char* label, double* value,
                   double min_v, double max_v, const char* fmt) {
    float fv = static_cast<float>(*value);
    bool changed = slider_float(label, &fv,
                                static_cast<float>(min_v),
                                static_cast<float>(max_v), fmt);
    if (changed) *value = static_cast<double>(fv);
    return changed;
}

} // namespace fn_ui
