/**
 * @file pipeline.hpp
 * @brief Render pipeline visualization state and interface
 */

#pragma once

#include "math3d.hpp"
#include <SDL3/SDL.h>

struct GameContext;

constexpr int NUM_CUBE_VERTS = 8;
constexpr int NUM_CUBE_EDGES = 12;
constexpr int NUM_TRI_VERTS = 3;
constexpr int NUM_TRI_EDGES = 3;

struct PipelineState {
    int current_stage = 0; // 0-5
    int prev_stage = 0;
    float transition_t = 1.0f;       // 0→1 animation progress (1 = complete)
    float fade_alpha = 1.0f;         // for 3D↔2D mode transitions

    // Interpolated vertices for rendering during transitions
    Vec3 display_verts[NUM_CUBE_VERTS];

    // Vertex selection
    int selected_vertex = -1;  // -1 = none, 0-7 = selected vertex index
    bool pending_click = false;
    float click_x = 0, click_y = 0;

    // Object transform parameters (user-adjustable)
    float obj_rot_y = 0.0f;
    float obj_pos_x = 2.0f;
    float obj_pos_y = 1.0f;
    float obj_pos_z = -3.0f;
    float obj_scale = 1.0f;
    bool auto_rotate = false;

    // Display camera (orbit around scene for visualization)
    float cam_orbit_pitch = 25.0f;  // degrees
    float cam_orbit_yaw = -30.0f;   // degrees
    float cam_distance = 10.0f;

    // Pipeline camera (the one being visualized in the pipeline)
    float pipe_cam_x = 0.0f;
    float pipe_cam_y = 2.0f;
    float pipe_cam_z = 5.0f;
    float pipe_cam_fov = 1.0f; // radians (~57 degrees)
    float pipe_cam_near = 0.1f;
    float pipe_cam_far = 100.0f;

    // Mouse drag state
    bool mouse_down = false;
    float mouse_start_x = 0, mouse_start_y = 0;
    float orbit_start_pitch = 0, orbit_start_yaw = 0;

    // Slider drag state
    int dragging_slider = -1;  // -1 = none, 0+ = slider index
    bool show_sliders = true;

    // First-person camera view (picture-in-picture)
    bool show_first_person = false;

    // Matrix color breakdown
    bool show_matrix_breakdown = false;

    // Vertex shader simulation
    bool shader_mode = false;
    float shader_amplitude = 0.3f;
    float shader_frequency = 2.0f;
    float shader_time = 0.0f;

    // Help overlay
    bool show_help = false;

    // Clipping visualizer
    bool show_clipping = false;
    struct ClippedFace {
        static constexpr int MAX_VERTS = 24;
        Vec4 verts[MAX_VERTS];
        int count = 0;
        bool was_clipped = false;
    };
    ClippedFace clipped_faces[6];

    // Depth buffer / Z-fighting demo
    bool show_depth_viz = false;
    bool show_zfight_plane = false;
    float zfight_plane_z = -3.0f;
    static constexpr int NUM_PLANE_VERTS = 4;
    Vec4 plane_world[4];
    Vec3 plane_screen[4];
    Vec3 plane_display[4];

    // Input flags (set per event, cleared after processing)
    bool key_left = false;
    bool key_right = false;
    bool key_space = false;
    bool key_r = false;
    bool key_num[6] = {};

    // Computed transforms
    Mat4 model_matrix;
    Mat4 view_matrix;
    Mat4 proj_matrix;

    // Transformed vertices at each pipeline stage (cube)
    Vec4 verts_object[NUM_CUBE_VERTS];
    Vec4 verts_world[NUM_CUBE_VERTS];
    Vec4 verts_view[NUM_CUBE_VERTS];
    Vec4 verts_clip[NUM_CUBE_VERTS];
    Vec3 verts_ndc[NUM_CUBE_VERTS];
    Vec3 verts_screen[NUM_CUBE_VERTS];

    // Second shape: triangle
    bool show_triangle = false;
    Vec4 tri_object[NUM_TRI_VERTS];
    Vec4 tri_world[NUM_TRI_VERTS];
    Vec4 tri_view[NUM_TRI_VERTS];
    Vec4 tri_clip[NUM_TRI_VERTS];
    Vec3 tri_ndc[NUM_TRI_VERTS];
    Vec3 tri_screen[NUM_TRI_VERTS];
    Vec3 tri_display[NUM_TRI_VERTS];
};

void pipeline_handle_event(PipelineState& ps, const SDL_Event& event);
void pipeline_update(PipelineState& ps, GameContext& ctx);
void pipeline_render(PipelineState& ps, GameContext& ctx);
