// gpu_postfx_pipeline.hpp - Pipeline de postprocesado (fullscreen triangle)
// © 2026 JailDesigner
//
// Pase final del frame: muestrea la escena renderizada en offscreen y aplica
// bloom + flicker + background pulse en el fragment shader. El vertex shader
// emite un único triángulo que cubre toda la pantalla, así que el draw no
// necesita vertex buffer (DrawPrimitives con vertex_count=3).
//
// Recursos del shader (SDL_gpu set bindings):
//   fragment set=2, binding=0 → sampler2D (escena offscreen)
//   fragment set=3, binding=0 → uniform buffer (parámetros del postpro)

#pragma once

#include <SDL3/SDL_gpu.h>

namespace Rendering::GPU {

    class GpuDevice;

    // Uniform buffer del composite final. Ha de coincidir EXACTAMENT amb
    // shaders/postfx.frag.glsl (layout std140 amb vec4 alineades a 16 bytes).
    // El bloom es calcula en passades separades (veure GpuBloomPipeline) i aquí
    // només passem la intensitat per a la composició; el threshold/sigma viuen
    // al UBO del bloom.
    struct PostFxUniforms {
        float time;                  // Temps acumulat en segons
        float bloom_intensity;       // Mescla bloom (0..2)
        float flicker_amplitude;     // Profunditat del flicker (0..1)
        float flicker_frequency_hz;  // Hz

        float background_pulse_freq_hz;  // Hz
        float pad_a;
        float pad_b;
        float pad_c;

        float background_min_r;  // Color min RGB en [0..1], A=1
        float background_min_g;
        float background_min_b;
        float background_min_a;

        float background_max_r;
        float background_max_g;
        float background_max_b;
        float background_max_a;
    };

    class GpuPostFxPipeline {
       public:
        GpuPostFxPipeline() = default;
        ~GpuPostFxPipeline();

        GpuPostFxPipeline(const GpuPostFxPipeline&) = delete;
        auto operator=(const GpuPostFxPipeline&) -> GpuPostFxPipeline& = delete;
        GpuPostFxPipeline(GpuPostFxPipeline&&) = delete;
        auto operator=(GpuPostFxPipeline&&) -> GpuPostFxPipeline& = delete;

        // target_format: formato del color target del pase final (swapchain).
        [[nodiscard]] auto init(const GpuDevice& device,
            SDL_GPUTextureFormat target_format) -> bool;
        void destroy();

        [[nodiscard]] auto get() const -> SDL_GPUGraphicsPipeline* { return pipeline_; }

       private:
        SDL_GPUDevice* owner_{nullptr};
        SDL_GPUGraphicsPipeline* pipeline_{nullptr};
    };

}  // namespace Rendering::GPU
