#version 120
// It was expressed that some drivers required this next line to function properly
precision highp float;
#define MAX_LIGHTS 14
in vec3 alightVec[MAX_LIGHTS];
//in vec3 aeyeVec[MAX_LIGHTS];
in vec2 texCoord;

in vec3 v;
in vec3 N;
in vec3 T;
in vec3 B;

uniform vec4 flash;
uniform vec4 glColor;
uniform vec3 camPos;

uniform float lightsPosx[MAX_LIGHTS];
uniform float lightsPosy[MAX_LIGHTS];
uniform float lightsPosz[MAX_LIGHTS];

//in vec3 vNormal;

uniform float lightsEnabled[MAX_LIGHTS];
uniform float lightsinvRadius[MAX_LIGHTS];
uniform float lightMapSelect[MAX_LIGHTS];


uniform float lightsAmbientr[MAX_LIGHTS];
uniform float lightsAmbientg[MAX_LIGHTS];
uniform float lightsAmbientb[MAX_LIGHTS];

uniform float lightsDiffuser[MAX_LIGHTS];
uniform float lightsDiffuseg[MAX_LIGHTS];
uniform float lightsDiffuseb[MAX_LIGHTS];

uniform float lightsSpecularr[MAX_LIGHTS];
uniform float lightsSpecularg[MAX_LIGHTS];
uniform float lightsSpecularb[MAX_LIGHTS];



uniform sampler2D colorMap;
uniform sampler2D normalMap;
uniform sampler2D lightMap;
uniform sampler2D specularMap;
//uniform float invRadius;
//out vec4 gl_FragColor;
vec3 CalcBumpedNormal()
{
    vec3 Normal = N;
    vec3 Tangent = T;
    Tangent = normalize(Tangent - dot(Tangent, Normal) * Normal);
    //vec3 Bitangent = cross(Tangent, Normal);
    vec3 Bitangent = B;
    vec3 BumpMapNormal = texture2D(normalMap, texCoord).xyz;
    BumpMapNormal = 2.0 * BumpMapNormal - vec3(1.0, 1.0, 1.0);
    vec3 NewNormal;
    mat3 TBN = mat3(Tangent, Bitangent, Normal);
    NewNormal = TBN * BumpMapNormal;
    NewNormal = normalize(NewNormal);
    return NewNormal;
}

void main (void)
{

    vec3 lightVec;
    vec3 eyeVec;
    vec4 accvDiffuse = vec4(0.0);
    vec4 accvSpecular = vec4(0.0);
    float distSqr;
    vec3 lVec;
    vec3 vVec;
    float att;
    vec4 base;
    vec4 vAmbient;
    vec3 bump;
    float diffuse;
    vec4 vDiffuse;
    vec4 vSpecular;
    float specular;
    vec3 nrmltexture;

    base = texture2D(colorMap, texCoord);
    //vAmbient = gl_LightSource[0].ambient * gl_FrontMaterial.ambient;
    vAmbient = vec4(1.0f,1.0f,1.0f,1.0f)
               * vec4(lightsAmbientr[0],lightsAmbientg[0],lightsAmbientb[0],1.0f);
    ///vAmbient = vec4(0.0f,0.0f,0.0f,1.0f);

    vec3 viewDir = normalize(camPos-v);

    for (int i=0; i<MAX_LIGHTS; i++)
    {
        if (lightsEnabled[i]>0.0)
        {
            vec3 L = normalize(vec3(lightsPosx[i],lightsPosy[i],lightsPosz[i]) - v);
            vec3 E = normalize(-v); // we are in Eye Coordinates, so EyePos is (0,0,0)
            vec3 R = normalize(-reflect(L,N));
            vec3 lightDir = L;//normalize(lightPos - FragPos);

            lightVec=alightVec[i];
            //eyeVec=aeyeVec[i];
            //lightVec=L; eyeVec=E;

            distSqr = dot(lightVec, lightVec);
            att = clamp(1.0 - lightsinvRadius[i] * sqrt(distSqr), 0.0, 1.0);
            //att = 1.0 - lightsinvRadius[i] * sqrt(distSqr);
            lVec = lightVec * inversesqrt(distSqr);
            //vVec = normalize(eyeVec);

            //bump = normalize( texture2D(normalMap, texCoord).xyz * 2.0f - 1.0);
            //bump = normalize(N);
            bump=CalcBumpedNormal();

            //diffuse = max( dot(lVec, bump), 0.0 );
            diffuse = clamp( dot(lVec, bump), 0.0, 1.0 );
            //	vDiffuse = gl_LightSource[i].diffuse * gl_FrontMaterial.diffuse * diffuse *
            vDiffuse = vec4(lightsDiffuser[i],lightsDiffuseg[i],lightsDiffuseb[i],1.0f) * diffuse *
                       texture2D(lightMap, vec2(diffuse/1.02f,lightMapSelect[i]));

            //diffuse = clamp( dot(lVec, bump), 0.0, 1.0 );
            //diffuse = max(dot(N,L), 0.0);
            diffuse = max(dot(bump,L), 0.0);
            vec4 Idiff = vec4 (lightsDiffuser[i],lightsDiffuseg[i],lightsDiffuseb[i],1.0f)* diffuse*
                        texture2D(lightMap, vec2(diffuse/1.02f,lightMapSelect[i]));
            Idiff = clamp(Idiff, 0.0, 1.0);

            accvDiffuse = accvDiffuse + Idiff *att;
            //accvDiffuse = accvDiffuse + vDiffuse * att;

            //vDiffuse = gl_LightSource[i].diffuse * diffuse *
            //         texture2D(lightMap, vec2(diffuse-0.01,lightMapSelect[i]));
            //accvDiffuse = accvDiffuse + vDiffuse;

            //specular = pow(clamp(dot(reflect(-lVec, bump), vVec), 0.0, 1.0),
            //gl_FrontMaterial.shininess );


            vec3 reflectDir=reflect(-lightDir,bump);
            const float shininess=1.5f;
            //specular = pow(clamp(dot(reflect(-lVec, bump), vVec), 0.0f, 1.0f), 32.0f );// * texture2D(specularMap, texCoord).r; //here shiness is replaced with 1.0, should introduce material functionality in obj loader //16.0
            specular = pow(clamp(dot(viewDir,reflectDir)*shininess,0.0f,1.0f),1.2f); //32.0f
            //specular = pow(clamp(dot(reflect(-lVec, bump), vVec), 0.0f, 1.0f), 32.0f );// * texture2D(specularMap, texCoord).r; //here shiness is replaced with 1.0, should introduce material functionality in obj loader //16.0
            //specular= clamp( dot(lVec, bump), 0.0, 1.0 ) * texture2D(specularMap, texCoord).r;
            // * pow(max(dot(R,E),0.0),0.3*shininess);

            //vec4 vSpecular = gl_LightSource[0].specular * gl_FrontMaterial.specular * specular;
//	vSpecular = gl_LightSource[i].specular * gl_FrontMaterial.specular * specular *
            vSpecular = vec4(lightsSpecularr[i],lightsSpecularg[i],lightsSpecularb[i],1.0f)* specular *
                        texture2D(lightMap, vec2(specular-0.01,lightMapSelect[i]));


            //const float shininess=1.0f;
            //specular=pow(max(dot(normalize(reflect(-L, bump)), E), 0.0f), 32.0f );// * texture2D(specularMap, texCoord).r; //here shiness is replaced with 1.0, should introduce material functionality in obj loader //16.0
            //specular=pow(max(dot(normalize(reflect(-L, bump)), E), 0.0f), 32.0f );// * texture2D(specularMap, texCoord).r; //here shiness is replaced with 1.0, should introduce material functionality in obj loader //16.0
            //specular=max(dot(normalize(L+normalize(E)),bump),0.0f);
            //specular=pow(max(dot(R,E),0.0),0.3*shininess);
            vec4 Ispec = vec4(lightsSpecularr[i],lightsSpecularg[i],lightsSpecularb[i],1.0f) * specular *
                        texture2D(lightMap, vec2(specular/1.02f,lightMapSelect[i]));
            // * pow(max(dot(R,E),0.0),0.3*shininess);
            // * pow(max(dot(N,L),0.0),0.3*shininess);
            // * pow(max(dot(R,E),0.0),0.3*shininess);
            Ispec = clamp(Ispec, 0.0, 1.0);

            //accvSpecular = accvSpecular + vSpecular * att;
            accvSpecular = accvSpecular + Ispec * att;

            //vSpecular = gl_LightSource[i].specular * specular * texture2D(lightMap, vec2(specular-0.01,lightMapSelect[i]));
            //accvSpecular = accvSpecular + vSpecular;
        }
    }
    //gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular) * att;
    //gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular)*glColor;
    gl_FragColor = ( vAmbient*base + accvDiffuse*base + accvSpecular)*glColor;
    gl_FragColor += flash;

    //gl_FragColor = gl_FragColor * glColor;

    //gl_FragColor = vec4(vNormal.x,vNormal.y,vNormal.z,1.0);
    //gl_FragColor = ( vAmbient*base + vDiffuse*base + vSpecular) * att;
    //gl_FragColor = ( vAmbient*base + vDiffuse*base + texture2D(lightMap, vec2(1.0-specular,0))) * att;
}


/*
uniform sampler2D color_texture;
uniform sampler2D normal_texture;

void main() {

// Extract the normal from the normal map
vec3 normal = normalize(texture2D(normal_texture, gl_TexCoord[0].st).rgb * 2.0 - 1.0);

// Determine where the light is positioned (this can be set however you like)
vec3 light_pos = normalize(vec3(1.0, 1.0, 1.5));

// Calculate the lighting diffuse value
float diffuse = max(dot(normal, light_pos), 0.0);

vec3 color = diffuse * texture2D(color_texture, gl_TexCoord[0].st).rgb;

// Set the output color of our current pixel
gl_FragColor = vec4(color, 1.0);
}
*/

/*
in  vec3 ex_Color;
out vec4 gl_FragColor;

uniform sampler2D colorMap;
in vec2 fragtextureCoord;

void main(void) {
vec4 base;

    // Pass through our original color with full opacity.
    //gl_FragColor = vec4(ex_Color,1.0);

	base = texture2D(colorMap, fragtextureCoord);
	gl_FragColor = base;
}
*/
