#version 430 core

///////////////////////////////////////////////////////////////////////////////
// shader inputs/outputs
///////////////////////////////////////////////////////////////////////////////
uniform float iGlobalTime; // in seconds
uniform vec2 iResolution; // viewport resolution (in pixels) (1080p or 720p)

// all samplers have linear filtering applied, wraping set to repeat
//
uniform sampler1D iFFTTexture; // 1024
uniform float iFFT[8]; // latest fram
uniform float iFFTs[8]; // smoothed latest frame
uniform sampler2D iFFTsHistory; // smoothed fft history, 8x1024, x coord = bin, y coord n-frames earlier, y=0 is latest frame

// predefined textures
//
uniform sampler2D iTex1;
uniform sampler2D iTex2;
uniform sampler2D iTex3;
uniform sampler2D iTex4;
uniform sampler2D iNoise;
uniform sampler2D iChecker;

// out_color must be written in order to see anything
//
layout(location = 0) out vec4 out_color;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

float mapg( vec3 pt, float sp )
{
	pt.xz *= 3.7;
	return (sin( pt.x ) + cos( pt.y ) ) * sp;
}

float rmg( vec3 ro, vec3 rd, float h, float sp )
{
	float t = 0.0;
	for( int i = 0; i < 50; i++ )
	{
		vec3 pt = ro + rd * t;
		float h = abs( pt.y - mapg( pt, sp ) );
		if( h < 0.1 )
		{
			break;
		}

		t += h * 0.3;
	}
	return t;
}

vec3 colorize( vec3 ro, vec3 rd, vec2 uv )
{
	float sp = texture( iFFTTexture, 0.0 ).r * 2.0 + 0.25;
	float t = rmg( ro, rd, 10.0, sp );


	vec3 pt = ro + rd * t;
	vec3 light = vec3( 0.0, 1.0, 0.0 );

	vec3 ed = normalize( pt - ro );
	float eps = 0.1;

	vec3 norm =  normalize( vec3( mapg( pt + vec3( eps, 0.0, 0.0 ), sp ) - mapg( pt, sp ), 1.0, 
			          mapg( pt + vec3( 0.0, 0.0, eps ), sp ) - mapg( pt, sp ) ) );

	vec3 r = reflect( light, norm );

	vec3 color = pt * ( sp + 0.1) + vec3( 1.0 + sp * 5.0, 1.0 - sp * 5.0, 1.0 ) * max( 0.0, dot( pt, r ) );
	return color;
}


void main(void)
{
	vec2 uv = vec2( gl_FragCoord.xy ) / iResolution;
	uv = uv - vec2( 0.5, 0.5 );

	float sp = texture( iFFTTexture, 0.0 ).r * 4.0 + 0.25;

	vec3 ro = vec3( 0.0, 0.0, 0.0 );
	vec3 rd = normalize( vec3 ( uv.x, uv.y, 1.0 ) );

	float d = 0.5-length( uv ) * 0.75;


	vec3 color = colorize( ro, rd, uv ) * ( d - sp * 0.3 );
		 //+ colorize( ro + vec3( sp * 0.5, 0.0, 0.0 ), rd, uv ) * ( d - sp * 0.3 );

	out_color = vec4( color, 1.0 );
}