
layout(location = 0, index = 0) out vec4 outcol0;

uniform sampler2D tex0;

uniform vec4 time;
uniform vec4 tex0siz;
uniform vec4 distval;

in vec2 texcoord0_nm;

//note: more code stolen from IQ... there should be a group for us poor bastards.
float hash( float n )
{
	return fract(sin(n)*43758.5453);
}
float noise( in vec2 x )
{
	vec2 p = floor(x);
	vec2 f = fract(x);
	f = f*f*(3.0f-2.0f * f);
	float n = p.x + p.y*57.0f;
	float res = mix( mix( hash(n +  0.0f), hash(n +  1.0f),f.x),
					 mix( hash(n + 57.0f), hash(n + 58.0f),f.x),
					 f.y);
	return res;
}
float fbm( vec2 p )
{
	const mat2 m = mat2( 0.80,  0.60, -0.60,  0.80 );

	float f = 0.0;
	f += 0.50000 * noise( p ); p = m*p*2.02;
	f += 0.25000 * noise( p ); p = m*p*2.03;
	f += 0.12500 * noise( p ); p = m*p*2.01;
	f += 0.06250 * noise( p ); p = m*p*2.04;
	f += 0.03125 * noise( p );

	return f/0.984375;
}

////////////////////////////////
//from coloffset
float sat( float t ) {
	return clamp( t, 0.0f, 1.0f );
}

//remaps inteval [a;b] to [0;1]
float remap( float t, float a, float b ) {
	return sat( (t - a) / (b - a) );
}

//note: /\ t=[0;0.5;1], y=[0;1;0]
float linterp( float t ) {
	return sat( 1 - abs( 2*t - 1 ) );
}

vec3 spectrum_offset( float t ) {
	vec3 ret;
	float lo = step(t,0.5f);
	float hi = 1.0f-lo;
	float w = linterp( remap( t, 1.0f/6.0f, 5.0f/6.0f ) );
	float neg_w = 1.0f-w;
	ret = vec3(lo,1.0f,hi) * vec3(neg_w, w, neg_w);

	return ret;
}
////////////////////////////////

float atan2(float x, float y )
{
	return atan( x, y );
}

vec3 rgb2hsl( const vec3 in_rgb )
{
	float u = (2.0f*in_rgb.r - in_rgb.g - in_rgb.b)    / 3.0f;
	float v = ( -in_rgb.r + 2.0f* in_rgb.g - in_rgb.b) / 3.0f;

	vec3 out_hsl;
	out_hsl.x = (abs(u) > 0.0f) ? atan2(u,v) : 0.0f;
	out_hsl.y = sqrt(u*u + v*v);
	out_hsl.z = dot( vec3(0.3333f), in_rgb);

	return out_hsl;
}

vec3 hsl2rgb( vec3 in_hsl )
{
	float u = in_hsl.y * sin(in_hsl.x);
	float v = in_hsl.y * cos(in_hsl.x);

	vec3 out_rgb;
	out_rgb.r = in_hsl.z + u;
	out_rgb.g = in_hsl.z + v;
	out_rgb.b = sat( in_hsl.z - u - v );

	return out_rgb;
}

vec3 iLoveOrangeAndTeal( const vec3 in_col )
{
	vec3 hsl = rgb2hsl( in_col );

	const float tau = 2.0f * 3.141592653589f;
	const float tealHue = 175.0f / 255.0f * tau;
	const float orangeHue = 55.0f / 255.0f * tau;
	const vec2 vblue = vec2( cos(tealHue), sin(tealHue) );
	const vec2 vteal = vec2( cos(orangeHue), sin(orangeHue) );
	const vec2 vdiff = normalize(vblue - vteal); //( (1=blue, -1=teal)

	float t3 = hsl.x * tau;
	vec2 v = vec2(cos(t3), sin(t3));
	float t = dot( v, vdiff );
	t = clamp( t, -1.0f, 1.0f );
	hsl.x = mix( orangeHue, tealHue, t*0.5f + 0.5f );
	hsl.y = abs(t);

	return hsl2rgb( hsl );
}

//TODO: input mask
void main()
{
	vec2 noise_uv = gl_FragCoord.xy * distval.y;
	float t = 5.0 * time.x;
	float n0 = fbm( 0.0125f * noise_uv + vec2(-0.2,  -0.7) * t );
	float n1 = fbm( 0.005f * noise_uv + vec2(0.25, -0.3) * t );
	float n2 = fbm( 0.02f * noise_uv + vec2(-0.2, 0.5) * t );
	float m = 150 * distval.x; //TODO: input magnitude
	vec2 uvdist = m * n2 * clamp(vec2(n0,n1)*2-1,-1,1) * tex0siz.zw;
	uvdist *= vec2( 2, 0 );

	// outcol0 = vec4( vec3( distval.x ), 1 );
	// return;

	const int num_samples = 8;
	const float num_samples_f = float(num_samples);
	const float step = 1.0f / num_samples;
	float s = 0.1 * noise( gl_FragCoord.xy );
	vec4 sum = vec4(0.0f)  ;
	vec4 spec_sum = vec4(0);
	for( int i=0; i<num_samples; ++i )
	{
		vec4 spec = vec4(1.0f); //vec4(spectrum_offset( s ),1);
		spec_sum += spec;
		vec2 uv = texcoord0_nm + s * uvdist;
		sum += texture( tex0, uv ) * spec;
		s += step;
	}
	sum /= spec_sum;

	outcol0 = sum;

	//note: make teal... probably just change org spectrum instead of offsetting
	//const float tau = 2.0f * 3.141592653589f;
	//vec3 hsl = rgb2hsl( outcol0.rgb );
	//const float tealHue = 175.0f / 255.0f * tau;
	//hsl.x = mix( hsl.x, tealHue, distval.x );
	//vec3 rgb = hsl2rgb( hsl );
	//outcol0.rgb = rgb;
	//return;
	//outcol0.rgb = iLoveOrangeAndTeal( outcol0.rgb );
	//return;

	float q = fract( 0.25f * gl_FragCoord.y );
	float w = q > 0.5f ? 1 : 0; //wtf, step fails?
	outcol0.rgb *= mix( 1.0f, w, 10.0f * length(uvdist));

	//outcol0.rgb = mix( outcol0.rgb, iLoveOrangeAndTeal( outcol0.rgb ), distval.x );

	//outcol0 = vec4(vec3(n),1);
}
