#pragma once
#include "types.h"
#include "pipelines.h"
#include <SDL3/SDL_gpu.h>
#include <SDL3/SDL_video.h>
#include <SDL3/SDL_gamepad.h>

struct Renderer {
  SDL_GPUDevice* dev = nullptr;
  SDL_Window*    win = nullptr;
  SDL_Gamepad*   gamepad = nullptr;

  RayPipeline  ray;
  PostPipeline  post;

  SDL_GPUBuffer*  vert_buff      = nullptr;
  SDL_GPUTexture* post_tex       = nullptr;
  SDL_GPUTexture* sprite_tex      = nullptr;
  SDL_GPUTexture* atlas_tex      = nullptr;
  SDL_GPUSampler* render_sampler = nullptr;
  SDL_GPUSampler* sprite_sampler  = nullptr;
  SDL_GPUSampler* atlas_sampler  = nullptr;
  uint32_t        render_w = 0, render_h = 0;
  uint64_t        frame = 0;

  bool in_menu = 0;
  float fps = 0.0;

  /* imgui controlled */
  int post_mode = 0;
  float zoom = 1.0f;
  float radius = 0.1f;

  std::vector<Vertex> vertices;

  bool init(SDL_Window* win);
  void destroy();

  void draw(CameraUBO& ubo);

private:
  bool load_sprites();
  bool load_bsp();
  void setup_imgui();
  void draw_imgui(SDL_GPUCommandBuffer* cmd, SDL_GPUTexture* tex);
  void add_gol_layer();
  void resize_render_texture(uint32_t w, uint32_t h);
  void pass_ray(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo);
  void pass_post(SDL_GPUCommandBuffer* cmd, SDL_GPUTexture* swapchain, const CameraUBO& ubo);
};
