#pragma once

#include <GL/glew.h>
#include <GL/gl.h>
#include "math.h"
#include "light.h"

enum Shader_Type : u32 {
  VERTEX = GL_VERTEX_SHADER,
  FRAGMENT = GL_FRAGMENT_SHADER
};

struct Shader {
  u32 id = 0;

  u32 projection = 0;
  u32 model = 0;
  u32 view = 0;
  u32 eye_position = 0;
  u32 shininess = 0;
  u32 specular_intensity = 0;
  u32 position = 0;  
  u32 constant = 0;
  u32 linear = 0;  
  u32 exponent = 0;
   
  struct {
    u32 color;
    u32 ambient_intensity;
    u32 diffuse_intensity;

    u32 direction;
  } directional_light;

  u32 point_light_count = 0;

  struct {
    u32 color;
    u32 ambient_intensity;
    u32 diffuse_intensity;

    u32 position;
    u32 constant;
    u32 linear;
    u32 exponent;
  } point_lights[MAX_POINT_LIGHTS];

  u32 spot_light_count = 0;

  struct {
    u32 color;
    u32 ambient_intensity;
    u32 diffuse_intensity;

    u32 position;
    u32 constant;
    u32 linear;
    u32 exponent;

    u32 direction;
    u32 edge;
  } spot_lights[MAX_SPOT_LIGHTS];

  ~Shader();
};

bool create_shader(Shader *shader, const char *vertex_shader_path, const char *fragment_shader_path);
bool add_shader(Shader *shader, const char *shader_code, Shader_Type type);
void clear_shader(Shader *shader);

void use_light(Shader *shader, Directional_Light *light);
void use_light(Shader *shader, Point_Light *light, u32 point_light_count);
void use_light(Shader *shader, Spot_Light *light, u32 point_light_count);
