#ifndef SHADER_H
#define SHADER_H

#include "aliases.h"
#include "img.h"
#include "obj.h"
#include "vec.h"

typedef struct shader_id ShaderID;
struct shader_id {
  u64 id;
};

typedef struct vertex_data VertexData;
struct vertex_data {
  V3f position;
  V3f normal;
  V2f uv;
};

typedef struct fragment_result FragmentResult;
struct fragment_result {
  Colour colour;
  bool discard;
};

#define INVALID_SHADER ((ShaderID){0})
#define IS_INVALID_SHADER(ID) (ID.id == 0)
#define DISCARDED_FRAGMENT ((FragmentResult){.discard = true})
#define DISCARD_FRAGMENT(RESULT) (RESULT.discard)

typedef VertexData(VertexShader)(void *shader, const VertexData *vert, u8 index,
                                 const Model *model);
typedef FragmentResult(FragmentShader)(void *shader, const V3f *barycentric,
                                       const Colour *colour,
                                       const Model *model);

ShaderID register_shader(void *shader, VertexShader *vertex,
                         FragmentShader *fragment);
VertexData run_vertex_shader(ShaderID shader, const VertexData *vert, u8 index,
                             const Model *model);
FragmentResult run_fragment_shader(ShaderID shader, const V3f *barycentric,
                                   const Colour *colour, const Model *model);

#endif // SHADER_H
