#version 400 core
uniform sampler2D texCol;
uniform sampler2D texNormal;

uniform vec3 lDirection;
uniform bool isSky;
uniform bool isPhong;
uniform float skyMult;
uniform bool drawTextures;
uniform bool isLightSource;
uniform bool isPickingMode;
uniform vec3 pointLight[3];
uniform vec4 pointLightCol[3];
uniform mat3 normalMatrix;
uniform bool useNormalMap;

in vec3 fNormal;
in vec3 fPosition;
in vec4 ifColor;
in vec2 texCoords;

out vec4 fColor;


vec4 calcDirLight(vec4 tex, vec3 fPos, vec3 fNorm) {
	// Get lighting vectors
        vec3 LightDirection = normalize(lDirection);
        vec3 nviewDirection = normalize(fPos);
        vec3 nfNormal;

        if(useNormalMap) {
            vec3 vNorm = texture(texNormal, texCoords).rgb;
            nfNormal = normalize(normalMatrix * vNorm);
        } else {
            nfNormal = normalize(fNorm);
        }

	// Compute diffuse component
        float diff = 0.2*max(0.0, dot(nfNormal, -LightDirection));

	// Compute specular component
        vec3 Rl = reflect(LightDirection, nfNormal);
        float spec = 0.2*pow(max(0.0, dot(/*normalMatrix */ Rl, nviewDirection)), 64);

    // Compute ambient component
        float amb = 0.2;

        float mult = 1;//max(0.0, -LightDirection.y+1.5);

    //return vec4(0);
        return vec4(tex.xyz * (diff + amb + spec) * mult, tex.w);
}

vec4 calcPointLight(vec4 tex, vec3 fPos, vec3 fNorm, int i) {
    // Get lighting vectors
	vec3 LightDirection = normalize(pointLight[i] + fPos);
        // vec3 nfNormal = normalize(fNorm);
	vec3 nviewDirection = normalize(fPos);
        vec3 nfNormal;

        if(useNormalMap) {
            vec3 vNorm = texture(texNormal, texCoords).rgb;
            nfNormal = normalize(normalMatrix * vNorm);
        } else {
            nfNormal = normalize(fNorm);
        }

    // Attenuation
	float distance    = length(nviewDirection - pointLight[i] - fPos) / 3;
	float attenuation = 0.5 + 1 / max(0.25, distance * distance);

    // Compute diffuse component
	float diff = 0.3 * max(0.0, dot(nfNormal, LightDirection));

    // Compute specular component
        vec3 Rl = reflect(-LightDirection, /*normalMatrix */ nfNormal);
	float spec = 0.5 * pow(max(0.0, dot(Rl, nviewDirection)), 32);

    // Compute ambient component
	float amb = 0.2;

        return vec4(pointLightCol[i].xyz * attenuation * (amb + diff + spec) * tex.xyz, pointLightCol[i].w);
}

void
main()
{
    vec4 texColor;


	if(isPickingMode){
		fColor = ifColor;
	}else{
		if(drawTextures) {
                        texColor = texture(texCol, texCoords);
		} else {
                        texColor = ifColor;
		}

                if(isLightSource) {
		   fColor = texColor;
		} else if(isSky) {
			fColor = skyMult * normalize(texColor*texColor*texColor*2/1.41)*2;
		} else if(isPhong) {
			// Get lighting vectors
			vec3 LightDirection = normalize(lDirection);
			vec3 nfNormal = normalize(fNormal);
			vec3 nviewDirection = normalize(fPosition);

                        fColor = calcDirLight(texColor, fPosition, fNormal)
                        + calcPointLight(texColor, fPosition, fNormal, 0)/4
                        + calcPointLight(texColor, fPosition, fNormal, 1)/4
                        + calcPointLight(texColor, fPosition, fNormal, 2)/4;
		} else {
			fColor = texColor + ifColor;
		}
	}
}
