#ifndef NUM_LIGHTS
    #define NUM_LIGHTS 4
#endif

uniform mat4 g_ViewMatrix;
uniform vec4 g_LightPosition[NUM_LIGHTS];
uniform vec4 g_g_LightColor[NUM_LIGHTS];
uniform float m_Shininess;

float Lighting_Diffuse(vec3 norm, vec3 lightdir){
    return max(0.0, dot(norm, lightdir));
}

float Lighting_Specular(vec3 norm, vec3 viewdir, vec3 lightdir, float shiny){
    vec3 refdir = reflect(-lightdir, norm);
    return pow(max(dot(refdir, viewdir), 0.0), shiny);
}

void Lighting_Direction(vec3 worldPos, vec4 color, vec4 position, out vec4 lightDir){
    float posLight = step(0.5, color.w);
    vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
    float dist = length(tempVec);

    lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
    lightDir.xyz = tempVec / dist;
}

void Lighting_ComputePS(vec3 tanNormal, mat3 tbnMat,
                     int lightCount, out vec3 outDiffuse, out vec3 outSpecular){
   // find tangent view dir & vert pos
   vec3 tanViewDir = viewDir * tbnMat;

   for (int i = 0; i < lightCount; i++){
       // find light dir in tangent space, works for point & directional lights
       vec4 wvLightPos = (g_ViewMatrix * vec4(g_LightPosition[i].xyz, g_LightColor[i].w));
       wvLightPos.w = g_LightPosition[i].w;

       vec4 tanLightDir;
       Lighting_Direction(wvPosition, g_LightColor[i], wvLightPos, tanLightDir);
       tanLightDir.xyz = tanLightDir.xyz * tbnMat;

       vec3 lightScale = g_LightColor[i].rgb * tanLightDir.w;
       float specular = Lighting_Specular(tanNormal, tanViewDir, tanLightDir.xyz, m_Shininess);
       float diffuse = Lighting_Diffuse(tanNormal, tanLightDir.xyz);
       outSpecular += specular * lightScale * step(0.01, diffuse) * g_LightColor[i].rgb;
       outDiffuse += diffuse * lightScale * g_LightColor[i].rgb;
   }
}
