#pragma once

#include "shader.h"
#include "util.h"

namespace pp::panopainter {

struct LegacyVrColorUniforms {
    glm::vec4 color { 1.0f };
    glm::mat4 mvp { 1.0f };
};

struct LegacyVrStrokePreviewUniforms {
    int texture_slot = 0;
    float alpha = 1.0f;
    bool draw_outline = false;
    glm::vec4 color { 1.0f };
    glm::mat4 mvp { 1.0f };
};

inline void setup_legacy_vr_color_shader(const LegacyVrColorUniforms& uniforms) noexcept
{
    ShaderManager::use(kShader::Color);
    ShaderManager::u_vec4(kShaderUniform::Col, uniforms.color);
    ShaderManager::u_mat4(kShaderUniform::MVP, uniforms.mvp);
}

inline void setup_legacy_vr_stroke_preview_shader(const LegacyVrStrokePreviewUniforms& uniforms) noexcept
{
    ShaderManager::use(kShader::StrokePreview);
    ShaderManager::u_int(kShaderUniform::Tex, uniforms.texture_slot);
    ShaderManager::u_float(kShaderUniform::Alpha, uniforms.alpha);
    ShaderManager::u_int(kShaderUniform::DrawOutline, uniforms.draw_outline);
    ShaderManager::u_vec4(kShaderUniform::Col, uniforms.color);
    ShaderManager::u_mat4(kShaderUniform::MVP, uniforms.mvp);
}

template <
    typename SetupCompositeShader,
    typename BindCompositeSamplers,
    typename BindCompositeInputs,
    typename DrawPlane>
void execute_legacy_stroke_preview_final_composite(
    SetupCompositeShader&& setup_composite_shader,
    BindCompositeSamplers&& bind_composite_samplers,
    BindCompositeInputs&& bind_composite_inputs,
    DrawPlane&& draw_plane)
{
    setup_composite_shader();
    bind_composite_samplers();
    bind_composite_inputs();
    draw_plane();
}

template <
    typename ClearTarget,
    typename ComputeFrames,
    typename BeforeFrame,
    typename SetupSampleShader,
    typename DrawSample,
    typename CopyPreviewResult>
void execute_legacy_stroke_preview_live_pass(
    ClearTarget&& clear_target,
    ComputeFrames&& compute_frames,
    BeforeFrame&& before_frame,
    SetupSampleShader&& setup_sample_shader,
    DrawSample&& draw_sample,
    CopyPreviewResult&& copy_preview_result)
{
    auto frames = compute_frames();
    clear_target();
    for (auto& frame : frames) {
        before_frame(frame);
        setup_sample_shader(frame);
        draw_sample(frame);
    }
    copy_preview_result();
}

} // namespace pp::panopainter
