// Fragment Shader for experiments – file "texture_shadowmap.frag"
//

#version 330 core

#define SAMPLES_COUNT 4

uniform sampler2D in_texture;
uniform sampler2DShadow in_shadowmap;
uniform sampler2D mix_texture;

uniform int identity;


uniform vec3 light_position;
uniform vec2 other_offsets[4];
uniform int soft_shadows;

in vec4 ex_lightspace_position;
in vec3 ex_normal;
in vec3 ex_eye;
in vec2 fragment_texcoord;

out vec4 out_color;

const int offset_size = 8;
void main(void)
{
	float diffuse_intensity;
	float specular_intensity;
	vec4 texel_color;

	float shadow = 0;

	//soft shadow testing
	vec2 offsets[offset_size];
	offsets[0] = vec2(0,0);
	offsets[1] = vec2(1,0);
	offsets[2] = vec2(0,1);
	offsets[3] = vec2(1,1);
	offsets[4] = vec2(-1.0, 0.0);
	offsets[5] = vec2(0.0, -1.0);
	offsets[6] = vec2(-1.0, -1.0);
	offsets[7] = vec2(0.0, 0.0);
	
	//maximum distance of the neighbour samples
	float fsize = 0.1;
	//float fsize = ex_lightspace_position.w * 0.0025;

	vec4 smCoord = ex_lightspace_position;



	//for (int i = 0; i<offset_size; i++) {
//
		//smCoord.xy += other_offsets[i] * fsize;// + ex_lightspace_position;
//
		//shadow += textureProj(in_shadowmap, smCoord) * (1.0 / offset_size);
//
	//}
	//--------------
	// shadow calculation
	//--------------------
	if (soft_shadows > 0) {
		shadow = textureProj(in_shadowmap, ex_lightspace_position);
	}
	else {
		//--------------------------
		// accumulate shadow samples
		//--------------------------
		//float shadow = 1.0f;
		//do testing samples first
		for (int i=0; i< offset_size; i++) {
			//vec3 offset = texture(offset_map, vec2((i % offset_size), i / offset_size) ).xyz;
			vec4 offset = vec4(offsets[i], 0, 0);
			//vec3 offset = vec3((i % offset_size), (i / offset_size), 0 );
			// read depth val from shadowmap
			smCoord = offset * fsize + ex_lightspace_position;
			shadow += textureProj(in_shadowmap, smCoord) * (1.0 / offset_size);
		}


		//if we are in penumbra, take more samples
		//if ((shadow < 0.99) && (shadow > 0.0001) ) {
		if (false) {

		float weight = 0.03;
		shadow = 0.0;
		int offset_size_square = offset_size * offset_size;
		for (int i=0; i< offset_size_square; i++) {
			//vec3 offset = texture(offset_map, vec2((i % offset_size), i / offset_size) ).xyz;
			//vec3 offset = vec3(offsets[i % offset_size], 0);
			vec4 offset = vec4((i % offset_size), (i / offset_size), 0, 0 );
			// read depth val from shadowmap
			smCoord = offset * weight + ex_lightspace_position;
			shadow += textureProj(in_shadowmap, smCoord) * (1.0 / offset_size);
		}

		}
		//--------------------------------
		// accumulate shadow samples done
		//--------------------------------
	}

	vec3 light = normalize(light_position - ex_eye);
	vec3 normal = normalize(ex_normal);

	diffuse_intensity = clamp(max( dot(normal, light), 0.0), 0.0, 1.0);

	if (shadow > 0) {
		vec3 reflection = normalize(reflect(-light, normal));
		specular_intensity = pow(clamp(max(dot(reflection, ex_eye), 0.0), 0.0, 1.0), 30.0 );
	}
	else {
		specular_intensity = 0.0;
	}

	

	if(identity == 2)
	{
		//mix the textures
		vec4 texel = texture(in_texture, fragment_texcoord);
		vec4 texel2 = texture(mix_texture, fragment_texcoord*10.0);
		texel_color = mix(texel, texel2, 0.17);

		//cfur05    0.10
		//cskb06    0.16
		//ground15	0.07
		//misc02		0.17
	}
	else
	{
		//normal texture operation
		texel_color = texture(in_texture, fragment_texcoord);
	}

	//vec4 texel_color2 = texture(in_texture, fragment_texcoord*10.0);
	//texel_color = mix(texel_color, texel_color2, 0.25);

	out_color = texel_color * 0.05 + //ambient
				texel_color * diffuse_intensity *  clamp(shadow, 0.1, 1.0) +
				texel_color * specular_intensity *  clamp(shadow, 0.1, 1.0);

}
