#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
layout (location = 3) in vec3 aTangent;
layout (location = 4) in vec4 aBitangent;

#define NR_POINT_LIGHTS 8

out vec3 FragPos;
out vec2 TexCoords;
out vec3 Normal;

// positions in tangent space for normal mapping
out vec3 TangentLightPos[NR_POINT_LIGHTS];
out vec3 TangentViewPos;
out vec3 TangentFragPos;

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


uniform vec3 lightPos[NR_POINT_LIGHTS];
uniform vec3 viewPos;

uniform bool useNormalMapping;

void main()
{
    FragPos = vec3(model * vec4(aPos, 1.0));
    Normal = aNormal; // used if no normal mapping is used
    TexCoords = aTexCoords;    

    if(useNormalMapping)
    {
        // Calculate TBN-Matrix
        mat3 normalMatrix = transpose(inverse(mat3(model)));
        vec3 T = normalize(normalMatrix * aTangent);
        vec3 N = normalize(normalMatrix * aNormal);
        T = normalize(T - dot(T, N) * N);
        vec3 B = cross(N, T);
        mat3 TBN = transpose(mat3(T, B, N));

        // move light, view ans fragpos into tangent space to save matrix mults in fragment shader
        
        for(int i =0; i < NR_POINT_LIGHTS; i++)
        {
            TangentLightPos[i] = TBN * lightPos[i];
        }

        TangentViewPos = TBN * viewPos;
        TangentFragPos = TBN * FragPos;
    }
    else
    {
        for(int i = 0; i < NR_POINT_LIGHTS; i++)
        {
            TangentLightPos[i] = lightPos[i];
        }

        TangentViewPos = viewPos;
        TangentFragPos = FragPos;
    }


    gl_Position = projection * view * model * vec4(aPos, 1.0);
}