#version 330 core

in vec2 UV;
uniform sampler2D colors;
uniform sampler2D normals;
uniform sampler2D ssao;
uniform sampler2D depth;
uniform mat4 projection;
uniform vec3 lightpos;
uniform float lightIntensity;
uniform vec3 eyepos;
uniform sampler2D fftDebug;
uniform int showSpectrum;
uniform float spectrumAlpha;

const float ambientCoeff = 1.0;
const float diffuCoeff = 0.1;
const float specuCoeff = 0.4;

// outputz
out vec4 color;


// Untested, http://stackoverflow.com/questions/22360810/reconstructing-world-coordinates-from-depth-buffer-and-arbitrary-view-projection
vec3 getPos(vec2 uv) {
  float z = 2.0 * texture(depth, uv).x - 1.0;
  vec4 clipSpace = vec4(UV, z, 1.0);
  vec4 homogLoc = inverse(projection) * clipSpace;
  return homogLoc.xyz / homogLoc.w;
}

void main() {
    // Ambient stuff
    vec4 cAmbient = vec4(texture(ssao, UV).rgb * texture(colors, UV).rgb, 1.0);
    vec4 normalData = texture(normals, UV);
    float hasLights = (normalData.a > 0.1) ? 1.0 : 0.0;

    // Lambertian light stuff
    vec3 normal = normalize(texture(normals, UV).xyz);
    vec3 pixpos = getPos(UV);
    vec3 lightdir = normalize(pixpos - lightpos);
    float lambertTerm = max(0.0, dot(normal, lightdir));
    vec4 cLambert = vec4(vec3(lambertTerm) * vec3(0.9, 1.0, 1.0), 1.0);

    // Specular term
    vec3 refl = normalize(reflect(lightdir, normal));
    float specularTerm = max(0.0, pow(dot(refl, normalize(pixpos - eyepos)), 5.0));
    vec4 cSpecular = vec4(vec3(specularTerm), 1.0);

    // Light fusion
    color = ambientCoeff * cAmbient + diffuCoeff * cLambert + specuCoeff * cSpecular;
    if (showSpectrum > 0) {
      color = 0.9*vec4(20.0*texture(fftDebug, vec2(UV.x)).rrr, 1.0);
    }
    color.rgb = smoothstep(0.1, 1.1 * (ambientCoeff +  hasLights * (diffuCoeff + specuCoeff) / (1.0001 + lightIntensity)), color.rgb);
    //color.a = dot(vec3(0.299, 0.587, 0.114), color.rgb);
}
