#version 410 core

layout (location = 0) out vec4 fragment_color;

in VS_OUT {
	vec3 fragment_pos;
	vec3 world_normal;
	vec2 fragment_UV;
	vec4 fragment_pos_lvp;
} fs_in;

struct Light {
	vec4 position;
	vec3 ambient;
	vec3 diffuse;
	vec3 specular;
    float cutOff;
    float outerCutOff;
	vec3 cone_direction;
};

struct Material{
	vec3 ambient;
	vec3 diffuse;
	vec3 specular;
	float shininess;
};

uniform sampler2DShadow shadow_map;

uniform sampler2D color_texture;
uniform vec3 view_pos;
uniform Light lights[2];

uniform Material material;
uniform bool texture_bool;
uniform bool transparent = false;


void main(){
	vec4 textures;
	vec3 linearColor = vec3(0);
	float shadow = textureProj(shadow_map, fs_in.fragment_pos_lvp);
	if(texture_bool){
		textures = texture(color_texture, fs_in.fragment_UV);
	} else{
		textures = vec4(1,1,1,1);
	}

	for(int i = 0; i < 2; i++)
	{	
		float attenuation = 1.0;
		float intensity = 1.0;
		vec3 light_dir = normalize(vec3(lights[i].position) - fs_in.fragment_pos);
		if(lights[i].position.w == 1)
		{
			float theta = dot(light_dir, normalize(-lights[i].cone_direction));
			float epsilon = (lights[i].cutOff - lights[i].outerCutOff);
			//intensity = clamp((theta - lights[i].outerCutOff)/epsilon, 0.0, 1.0);
			intensity = smoothstep(0.0, 1.0, (theta - lights[i].outerCutOff)/epsilon);
		
			float light_dist = length(vec3(lights[i].position) - fs_in.fragment_pos);
			attenuation = 1.0/(1.0 + 0.05f * pow(light_dist,2));
			//linearColor = vec3(0);

			
		}
		vec3 ambient = lights[i].ambient * intensity * material.ambient * textures.rgb;
    
		vec3 normal = normalize(fs_in.world_normal);
		float diffuse_cos = max(dot(normal, light_dir), 0.0);
		vec3 diffuse = material.diffuse * lights[i].diffuse * intensity * diffuse_cos * textures.rgb;

		vec3 view_dir = normalize(view_pos - fs_in.fragment_pos);
		vec3 reflect_dir = reflect(-light_dir, normal);
		vec3 halfway_dir = normalize(light_dir + view_dir);  
		float spec_val = pow(max(dot(view_dir, reflect_dir), 0.0), material.shininess);    
		vec3 specular = material.specular * lights[i].specular * intensity  *  spec_val * textures.rgb;

		linearColor += ambient + (shadow)*attenuation*(diffuse + specular);
    
	}


	vec3 gamma = vec3(1.0/2.2);
	
	fragment_color += vec4(pow(linearColor, gamma), 1.0f);
	if(transparent)
	{
		fragment_color.a = 0.3f;
	}
}