

// Uniform variables for texturing
uniform sampler2D 	aaa_tex2d[4];


// Size of Texture for each texture unit
uniform vec2		aaa_tex_size[];

// 0 = time
// 1 = mouse X
// 2 = mouse Y
// 3 = mode (From 0.1 to 2.0)
uniform float		aaa_fu_float[8];

// 0 = iterations
uniform int			aaa_fu_int[4];


// balance between texture and effect
uniform float		aaa_fu_src;
uniform float		aaa_fu_out;


// Colors factors
// 0 = src colors
// 1 = out color
uniform vec4		aaa_fu_vec4[8];


float iMode = 2.0; // From 0.1 to 2.0
vec3 iColor = vec3(1.0, 1.0, 1.0);


float hash1( float n )
{
	return fract(sin(n)*43758.5453);
}

vec2  hash2( vec2  p )
{
	p = vec2( dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)) ); return fract(sin(p)*43758.5453);
}



vec4 voronoi( in vec2 x, float mode )
{
    vec2 n = floor( x );
    vec2 f = fract( x );

	vec3 m = vec3( 8.0 );
	float m2 = 8.0;

    for( int j=-2; j<=2; j++ )
    for( int i=-2; i<=2; i++ )
    {
        vec2 g = vec2( float(i),float(j) );
        vec2 o = hash2( n + g );

		// animate
        o = 0.5 + 0.5*sin( aaa_fu_float[0] + 6.2831*o );

		vec2 r = g - f + o;

        // euclidean
		vec2 d0 = vec2( sqrt(dot(r,r)), 1.0 );
        // manhattam
		vec2 d1 = vec2( 0.71*(abs(r.x) + abs(r.y)), 1.0 );
        // triangular
		vec2 d2 = vec2( max(abs(r.x)*0.866025+r.y*0.5,-r.y),
				        step(0.0,0.5*abs(r.x)+0.866025*r.y)*(1.0+step(0.0,r.x)) );

		vec2 d = d0;
		if( mode<3.0 ) d = mix( d2, d0, fract(mode) );
		if( mode<2.0 ) d = mix( d1, d2, fract(mode) );
		if( mode<1.0 ) d = mix( d0, d1, fract(mode) );

        if( d.x<m.x )
        {
			m2 = m.x;
            m.x = d.x;
            m.y = hash1( dot(n+g,vec2(7.0,113.0) ) );
			m.z = d.y;
        }
		else if( d.x<m2 )
		{
			m2 = d.x;
		}

    }
    return vec4( m, m2-m.x );
}

void main( void )
{
	vec2 p = gl_FragCoord.xy/aaa_tex_size[0].xx * aaa_fu_float[1] * 10.;
    vec4 c = voronoi( 4.0*p, aaa_fu_float[3] + 2. );

    vec3 col = 0.5 + 0.5*sin( c.y*2.5 + iColor );
    col *= sqrt( clamp( 1.0 - c.x, 0.0, 1.0 ) );
	col *= clamp( 0.5 + (1.0-c.z/2.0)*0.5, 0.0, 1.0 );
	col *= 0.4 + 0.6*sqrt(clamp( 4.0*c.w, 0.0, 1.0 ));


	vec4 src = (texture2D(aaa_tex2d[0], gl_TexCoord[0].st) * aaa_fu_src) * aaa_fu_vec4[0];
	vec4 fx  = (vec4( col, 1.0 ) * aaa_fu_out) * aaa_fu_vec4[1];

	gl_FragColor = vec4( (src + fx) );
}