#type vertex
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;

out VS_OUT {
  vec3 FragPos;
  vec3 Normal;
  vec2 TexCoords;
} vs_out;


uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main() {
	vs_out.FragPos = vec3(model * vec4(aPos, 1.0));
	vs_out.Normal = aNormal;
	vs_out.TexCoords = aTexCoords;
	
	gl_Position = projection * view * vec4(vs_out.FragPos, 1.0);
}

#type fragment
#version 330 core
layout (location = 0) out vec4 FragColor;

in VS_OUT {
    vec3 FragPos;
    vec3 Normal;
    vec2 TexCoords;
} fs_in;

// Object material Difusse color
uniform vec3  Mat_Kd;
uniform vec3  Mat_Ka;
uniform vec3  Mat_Ks;
uniform float Mat_KsStrenght;

uniform vec3 viewPos;

uniform vec3 light1Pos;
uniform vec3 light1Color;

uniform vec3 light2Pos;
uniform vec3 light2Color;

uniform float blinn_exponent_1;
uniform float blinn_exponent_2;

void main() {   
    vec3 ambient = vec3(0.);
    vec3 diffuse = vec3(1.);
    vec3 specular = vec3(0.);

    diffuse = Mat_Kd;

    // diffuse
    vec3 normal = normalize(fs_in.Normal);

    vec3 light1Dir = normalize(light1Pos - fs_in.FragPos);
    vec3 light2Dir = normalize(light2Pos - fs_in.FragPos);

    float diff1 = max(dot(light1Dir, normal), 0.0);
    float diff2 = max(dot(light2Dir, normal), 0.0);

    diffuse = (diff1 + diff2 ) * Mat_Kd;

    // specular
    vec3 viewDir = normalize(viewPos - fs_in.FragPos);

    vec3 reflectDir1 = reflect(-light1Dir, normal);
    vec3 reflectDir2 = reflect(-light2Dir, normal);    
    
    vec3 specular1 = light1Color * pow(max(dot(viewDir, reflectDir1), 0.0), blinn_exponent_1);
    vec3 specular2 = light2Color * pow(max(dot(viewDir, reflectDir2), 0.0), blinn_exponent_2);

    specular = specular1 + specular2; // Assuming white light        

    FragColor = vec4(ambient + diffuse + specular, 1.0);
}