// color_oscillator.cpp - Implementació d'oscil·lació de color
// © 2025 Port a C++20 amb SDL3

#include "core/rendering/color_oscillator.hpp"

#include <cmath>

#include "core/defaults.hpp"

namespace Rendering {

ColorOscillator::ColorOscillator()
    : accumulated_time_(0.0F) {
    // Inicialitzar amb el color mínim
    current_line_color_ = {.r = Defaults::Color::LINE_MIN_R,
        .g = Defaults::Color::LINE_MIN_G,
        .b = Defaults::Color::LINE_MIN_B,
        .a = 255};
    current_background_color_ = {.r = Defaults::Color::BACKGROUND_MIN_R,
        .g = Defaults::Color::BACKGROUND_MIN_G,
        .b = Defaults::Color::BACKGROUND_MIN_B,
        .a = 255};
}

void ColorOscillator::update(float delta_time) {
    accumulated_time_ += delta_time;

    float factor =
        calculateOscillationFactor(accumulated_time_, Defaults::Color::FREQUENCY);

    // Interpolar colors de línies
    SDL_Color line_min = {Defaults::Color::LINE_MIN_R,
        Defaults::Color::LINE_MIN_G,
        Defaults::Color::LINE_MIN_B,
        255};
    SDL_Color line_max = {Defaults::Color::LINE_MAX_R,
        Defaults::Color::LINE_MAX_G,
        Defaults::Color::LINE_MAX_B,
        255};
    current_line_color_ = interpolateColor(line_min, line_max, factor);

    // Interpolar colors de fons
    SDL_Color bg_min = {Defaults::Color::BACKGROUND_MIN_R,
        Defaults::Color::BACKGROUND_MIN_G,
        Defaults::Color::BACKGROUND_MIN_B,
        255};
    SDL_Color bg_max = {Defaults::Color::BACKGROUND_MAX_R,
        Defaults::Color::BACKGROUND_MAX_G,
        Defaults::Color::BACKGROUND_MAX_B,
        255};
    current_background_color_ = interpolateColor(bg_min, bg_max, factor);
}

float ColorOscillator::calculateOscillationFactor(float time, float frequency) {
    // Oscil·lació senoïdal: sin(t * freq * 2π)
    // Mapejar de [-1, 1] a [0, 1]
    float radians = time * frequency * 2.0F * Defaults::Math::PI;
    return (std::sin(radians) + 1.0F) / 2.0F;
}

SDL_Color ColorOscillator::interpolateColor(SDL_Color min, SDL_Color max, float factor) {
    return {static_cast<uint8_t>(min.r + ((max.r - min.r) * factor)),
        static_cast<uint8_t>(min.g + ((max.g - min.g) * factor)),
        static_cast<uint8_t>(min.b + ((max.b - min.b) * factor)),
        255};
}

}  // namespace Rendering
