#version 140

uniform sampler2D color;
uniform sampler2D position;
uniform sampler2D normal;
uniform vec2 winSize;

out vec4 fragColor;

const int MAX_LIGHTS = 8;
const int TYPE_POINT = 0;
const int TYPE_DIRECTIONAL = 1;
const int TYPE_SPOT = 2;

struct Light {
    int type;
    vec3 position;
    vec3 color;
    float intensity;
    vec3 direction;
    float constantAttenuation;
    float linearAttenuation;
    float quadraticAttenuation;
    float cutOffAngle;
};

uniform Light lights[MAX_LIGHTS];
uniform int lightCount;

void main()
{
    vec2 texCoord = gl_FragCoord.xy / winSize;
    vec4 col = texture(color, texCoord);
    vec3 pos = texture(position, texCoord).xyz;
    vec3 norm = texture(normal, texCoord).xyz;

    vec3 lightColor = vec3(0.0);
    vec3 s;

    for (int i = 0; i < lightCount; ++i) {
        float att = 1.0;
        if ( lights[i].type != TYPE_DIRECTIONAL ) {
            s = lights[i].position - pos;
            if (lights[i].constantAttenuation != 0.0
             || lights[i].linearAttenuation != 0.0
             || lights[i].quadraticAttenuation != 0.0) {
                float dist = length(s);
                att = 1.0 / (lights[i].constantAttenuation + lights[i].linearAttenuation * dist + lights[i].quadraticAttenuation * dist * dist);
            }
            s = normalize( s );
            if ( lights[i].type == TYPE_SPOT ) {
                if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle)
                    att = 0.0;
            }
        } else {
            s = normalize( -lights[i].direction );
        }

        float diffuse = max( dot( s, norm ), 0.0 );

        lightColor += att * lights[i].intensity * diffuse * lights[i].color;
    }
    fragColor = vec4(col.rgb * lightColor, col.a);
}
