precision highp float;

varying highp vec2 vTextureCoord;
varying highp vec4 vNormal;
varying highp vec3 vPosition;
uniform sampler2D uSampler;
uniform float time;

vec2 cinv(in vec2 z)
{
	return (vec2(z.x, -z.y) / dot(z, z));
}

vec2 cmul(in vec2 z1, in vec2 z2)
{
	return(vec2(z1.x * z2.x - z1.y * z2.y, z1.x * z2.y + z1.y * z2.x));
}

vec2 cdiv(in vec2 z1, in vec2 z2)
{
	return (cmul(z1, cinv(z2)));
}

vec3 extremize(vec3 v, float n) {
	if (v.x > n / 2.)
		v.x = n;
	else
		v.x = 0.;
	if (v.y > n / 2.)
		v.y = n;
	else
		v.y = 0.;
	if (v.z > n / 2.)
		v.z = n;
	else
		v.z = 0.;
	return v;
}

void main() {
	float slowTime = time / 20.;
    vec2 a0 = vec2(sin(16. * slowTime) * 1.0 + 5., 0.);
    vec2 a1 = vec2(sin(17. * slowTime) * 2.0, 0.);
    vec2 a2 = vec2(sin(18. * slowTime) * 3.0, 0.);
    vec2 a3 = vec2(sin(19. * slowTime) * 4.0, 0.);
    vec2 a4 = vec2(sin(1.1 * slowTime) * 5.0, 0.);
    vec2 a5 = vec2(sin(1.2 * slowTime) * 6.0, 0.);
    vec2 a6 = vec2(sin(1.3 * slowTime) * 7.0, 0.);
    vec2 a7 = vec2(sin(1.4 * slowTime) * 8.0, 0.);
    vec2 a8 = vec2(sin(15. * slowTime) * 9.0, 0.);
    vec2 a9 = vec2(sin(16. * slowTime) * 10.0, sin(slowTime));
    vec2 a10 = vec2(sin(17. * slowTime) * 11.0, 1. +  sin(slowTime) * 0.2);

    vec2 a = vec2(1.0, 1. + sin(0.16 * slowTime) * 0.002);
    vec2 c = vec2(0.01, sin(slowTime) / 10.);
    // Normalized pixel coordinates (from 0 to 1)
    vec2 z = cmul((vTextureCoord/vec2(1., 1.) - 0.5), vec2(4., 0.));
	vec2 init_z = z;
    z.x = abs(z.x);
	z.y = abs(z.y);
	vec2		old_z = z;
	float		i_backup;
	for (float i = 0.0; i < 16.0; i += 1.)
	{
		z = z - cmul(a, cdiv(a0 + cmul(z, a1 + cmul(z, a2 + cmul(z, a3 + cmul(z, a4 + cmul(z, a5
                                + cmul(z, a6 + cmul(z, a7 + cmul(z, a8 + cmul(z, a9 + cmul(a10, z)))))))))),
						a1 + cmul(z, cmul(a2, vec2(2., 0.)) + cmul(z, cmul(a3, vec2(3., 0.))
                           + cmul(z, cmul(a4, vec2(4., 0.)) + cmul(z, cmul(a5, vec2(5., 0.))
                           + cmul(z, cmul(a6, vec2(6., 0.)) + cmul(z, cmul(a7, vec2(7., 0.))
                           + cmul(z, cmul(a8, vec2(8., 0.)) + cmul(z, cmul(a9, vec2(9., 0.))
                           + cmul(cmul(a10, vec2(10., 0.)), z))))))))))) + c;

		if (old_z.x * old_z.x + old_z.y * old_z.y < z.x * z.x + z.y * z.y + 0.001
		&&	old_z.x * old_z.x + old_z.y * old_z.y > z.x * z.x + z.y * z.y - 0.001)
		{
			i_backup = i / 16.0;
			break;
		}
		old_z = z;
	}
	vec3 n = normalize(vec3(-50., 100., 50.) - vPosition);
	float diffuse = max(dot(normalize(vNormal.xyz), n), 0.);
	float specular = pow(
		max(dot(
			reflect(n, normalize(vNormal.xyz)),
			normalize(vec3(0., 0., -50.) - vPosition)),
		0.), 10.);
    gl_FragColor = vec4(vec3(z.x, z.y, i_backup) * diffuse * 0.8 + vec3(z.x, z.y, i_backup) * 0.2 + vec3(specular), 1.0);
}

// void main() {
// 	vec3 n = normalize(vec3(-200., 200., -200.) - vPosition);
// 	float diffuse = max(dot(normalize(vNormal.xyz), n), 0.);
// 	vec3 tmp = extremize(mod(vPosition.xyz + vec3(1000.), vec3(100.)), 100.);
// 	float texture = (tmp.x + tmp.y + tmp.z) / 300.;
// 	gl_FragColor = vec4(vec3(texture * diffuse), 1.0);
// }