#ifndef OG_LIGHTING_GLSL
#define OG_LIGHTING_GLSL

void getPhongLighting(
in vec3 vertex,
in vec3 normal,
in vec3 cameraPos,
in vec3 lightPos,
in vec3 ambient,
in vec3 diffuse,
in vec4 specular,
in float specularMask,
in float ao,
out vec3 outSpecularWeighting,
out vec4 outLightWeighting
){

    vec3 lightDir = normalize(lightPos);
    vec3 viewDir = normalize(cameraPos - vertex);

    vec3 reflectionDir = reflect(-lightDir, normal);
    float reflection = max(dot(reflectionDir, viewDir), 0.0);
    float diffuseLightWeighting = max(dot(normal, lightDir), 0.0);
    outSpecularWeighting = specular.rgb * pow(reflection, specular.w) * specularMask;
    outLightWeighting = vec4(ambient * ao + diffuse * diffuseLightWeighting, 1.0);
}

void getPhongLighting(
in vec3 vertex,
in vec3 normal,
in vec3 cameraPos,
in vec3 lightPos,
in vec3 ambient,
in vec3 diffuse,
in vec4 specular,
in float specularMask,
in vec3 sunIlluminance,
in float ao,
out vec3 outSpecularWeighting,
out vec4 outLightWeighting
){

    vec3 lightDir = normalize(lightPos);
    vec3 viewDir = normalize(cameraPos - vertex);

    vec3 reflectionDir = reflect(-lightDir, normal);
    float reflection = max(dot(reflectionDir, viewDir), 0.0);
    float diffuseLightWeighting = max(dot(normal, lightDir), 0.0);
    outSpecularWeighting = sunIlluminance * specular.rgb * pow(reflection, specular.w) * specularMask;
    outLightWeighting = vec4(ambient * ao + sunIlluminance * diffuse * diffuseLightWeighting, 1.0);
}

const float EMISSION_PACK_RANGE = 8.0;

float packEmissionColor(in vec3 emissionColor)
{
    // Gamma encode before 8-bit packing to preserve low-intensity night emission.
    vec3 encoded = sqrt(clamp(emissionColor / EMISSION_PACK_RANGE, 0.0, 1.0));
    vec3 packed = floor(encoded * 255.0 + 0.5);
    return packed.r + packed.g * 256.0 + packed.b * 65536.0;
}

vec3 unpackEmissionColor(in float packedEmission)
{
    float r = mod(packedEmission, 256.0);
    float g = mod(floor(packedEmission / 256.0), 256.0);
    float b = mod(floor(packedEmission / 65536.0), 256.0);
    vec3 encoded = vec3(r, g, b) / 255.0;
    vec3 decoded = encoded * encoded;
    return decoded * EMISSION_PACK_RANGE;
}

#endif
