#include "inc/uniforms.glsl"
#include "inc/utils.glsl"

uniform mat4 shadowTransform;

#ifdef VERTEX
#include "inc/geometry_vert_io.glsl"

out vec4 ex_WorldPosition;	
out vec4 ex_ClipPosition;

void process() 
{
	ex_UV = in_UV;
	mat4 model_view = viewMatrix*modelMatrix;
	ex_Normal = mat3(model_view) * in_Normal;
	ex_WorldPosition = modelMatrix*in_Position;
	ex_Position = (model_view)*in_Position;
	ex_ClipPosition = (projectionMatrix*viewMatrix*modelMatrix)*in_Position;
	gl_Position = ex_ClipPosition;
}

#define PROCESSING_FUNCTION process
#include "inc/geometry_vert.glsl"

#endif


#ifdef FRAGMENT
#line 1 30
in vec4 ex_Color;
in vec3 ex_Normal;
in vec2 ex_UV;
in vec4 ex_Position;
in vec4 ex_WorldPosition;	
in vec4 ex_ClipPosition;

layout(location = 0) out vec4 out_Color;
//layout(location = 1) out vec3 out_Normal;
//layout(location = 2) out vec3 out_Position;
//layout(location = 3) out vec4 out_Material;

uniform float p_particle_alpha;

uniform sampler2D tex;
uniform sampler2D emitMap;
uniform sampler2D noisetex;

uniform sampler2D shadowbuffer;
uniform sampler2D depthbuffer;

#line 1 4
#include "inc/shadows.glsl"
#line 46 1

float convert_z(float log_z, float near, float far) {
	float z_n = 2.0 * log_z - 1.0;
    float z_e = 2.0 * near * far / (far + near - z_n * (far - near));
	return z_e;
}

void main()
{
	//float dist = length(ex_Position.xyz - vec3(0.0, 4.0, -10.0));
	vec2 calc_uv = ex_UV;
	calc_uv += vec2(p_time) * vec2(0.01, -0.02) + vec2(0.03 * sin(ex_WorldPosition.y*0.7), 0.05 * sin(ex_WorldPosition.z*0.5));
	vec4 sampld = texture(noisetex, calc_uv.xy);
	vec4 col = sampld.rgba;
	vec2 screen_uv = gl_FragCoord.xy / textureSize(depthbuffer, 0);
	
	float sceneDepth = texture(depthbuffer, screen_uv).r;
	
	float myDepth = gl_FragCoord.z;
	
	if (myDepth > sceneDepth) {
		discard;
	}

	/*
	vec3 lamppos = (viewMatrix*vec4(lights.spot[0].pos, 1.0)).xyz;
	vec4 worldpos = (inverseViewMatrix*vec4(viewpos, 1.0)).xyzw;
	vec4 lightview = shadowTransform * worldpos; // light position in lamp view space
	vec3 lightclip = lightViewToClip(lightview);
	
	vec3 point_to_lamp = normalize(worldpos.xyz - lights.spot[0].pos);

	vec3 lamplight = accumulate_light(scenecam, worldpos, lightclip, normal, specularExponent, specularMultiplier, 0.0);
	*/
	
	float density = sampld.r;
	density *= saturate(max(0.0, 0.5 - length(ex_UV - vec2(0.5, 0.5)))*8.0);	// blobl shape
	vec4 worldpos = ex_WorldPosition;
	//worldpos.xyz += noise(vec3(p_time, ex_UV.x, ex_UV.y)) * normalize(ex_Position.xyz) * 0.1;
	vec4 lightview = shadowTransform * worldpos; // light position in lamp view space
	vec3 lightclip = lightViewToClip(lightview);
	//vec3 lightclip = ex_Position.xyz * 0.0;
	//lightclip.xyz = lightclip.xyz * 0.5 + vec3(0.5); // map from [-1,1] range to [0,1]
	
	// vec3 lamplight = accumulate_light(scenecam, worldpos, lightclip, normal, specularExponent, specularMultiplier, 0.0);
	   vec3 lamplight = accumulate_light(scenecam, worldpos, lightclip, vec3(0.0), 100.0, 0.0, 1.0);
	
	col.a = density*2.0;
	
	float smoothnear=saturate(0.11 * (convert_z(sceneDepth, scenecam.near, scenecam.far) - convert_z(gl_FragCoord.z, scenecam.near, scenecam.far)));
	col.a *= smoothnear;
	
	col.a += saturate(-worldpos.y + 1.5)*0.2 * (smoothnear+0.5);
	col.a *= p_particle_alpha;
	//col.a *= saturate(200.0 * (convert_z(gl_FragCoord.z, scenecam.near, scenecam.far) - convert_z(sceneDepth, scenecam.near, scenecam.far)));
	col.a = saturate(col.a * min(1.0, length(ex_Position.xyz)));	// fade towards camera
	col.a *= abs(dot(normalize(ex_Normal), vec3(0.0, 0.0, -1.0)));	// do not show smoke from the side
	
	col.rgb = mix(sampld.rrr, sampld.ggg, compress(sin(ex_WorldPosition.z)));
	float ambient = 0.0;
	col.rgb *= vec3(ambient) + lamplight*1.0;	
	
	out_Color.rgba = col.rgba;
}

#endif