#version 410 core

layout (location = 1) in vec3 position;
layout (location = 2) in vec3 normal;
layout (location = 3) in vec2 uv;

uniform mat4 MVP;
uniform mat4 M;
uniform mat4 V;

uniform int numLights;

struct Light {
	vec3 worldLightPosition;
	vec3 lightColorAmbient;
	vec3 lightColorDiffuse;
	vec3 lightColorSpecular;
	float attenuationConstant;
	float attenuationLinear;
	float attenuationSpecular;
	float shininess;
};

uniform Light lights[8]; // TODO: are 8 light sources enough?!

out vec2 texCoord;
out vec3 cameraNormal;
out vec3 cameraEyeDir;
out vec3 cameraLightDir[8];
out float attenuation[8];
out vec3 normal_vec;

void main(){

	normal_vec = normal;
	
	// positions
	gl_Position = MVP * vec4(position, 1.0);
	vec3 worldPosition = (M * vec4(position, 1.0)).xyz;

	// uvs
	texCoord = uv;

	// normals
	cameraNormal = (V * M * vec4(normal, 0.0)).xyz;

	// eye/light direction
	vec3 cameraPosition = (V * M * vec4(position, 1.0)).xyz;
	cameraEyeDir = vec3(0, 0, 0) - cameraPosition;

	for(int i = 0; i < numLights; i++){
		vec3 cameraLightPosition = (V * vec4(lights[i].worldLightPosition, 1.0)).xyz;
		cameraLightDir[i] = cameraLightPosition + cameraEyeDir;

		// distance to the light source
		float lightDistance = distance(lights[i].worldLightPosition, worldPosition);
		lightDistance = lightDistance < 0.0001f ? 0.0001f : lightDistance;

		// calculate the light attenuation
		attenuation[i] = 1.0 / (lights[i].attenuationConstant + lights[i].attenuationLinear * lightDistance + lights[i].attenuationSpecular * pow(lightDistance, 2));
	}
}