#define PI 3.141592653589793
#define TAU 6.283185307179586

float rand(vec2 p){
	return fract(sin(dot(p.xy, vec2(1.3295, 4.12))) * 493022.1);
}

float brightness_squared(vec3 color) {
    return 0.241*color.x*color.x + 0.691*color.y*color.y + 0.068*color.z*color.z;
}

vec2 window(float n, float b) {
	float l = b * (n - 1.0);
	float r = l + 1.0;
	return vec2(l, r);
}

vec3 get_color(float i) {
	if(i < 1.0) {
		return vec3(1.0, 0.0, 0.0);
	} else if(i < 2.0) {
		return vec3(1.0, 0.5, 0.0);
	} else if(i < 3.0) {
		return vec3(1.0, 1.0, 0.0);
	} else if(i < 4.0) {
		return vec3(0.0, 1.0, 0.0);
	} else if(i < 5.0) {
		return vec3(0.0, 1.0, 1.0);	
	} else if(i < 6.0) {
		return vec3(0.0, 0.0, 1.0);	
	} else if(i < 7.0) {
		return vec3(1.0, 0.0, 1.0);	
	} else {
		return vec3(1.0, 0.0, 0.0);	
	}
}

vec3 dither(float n, vec3 color, vec2 coord) {
	vec2 w = window(n, sqrt(brightness_squared(color)));
	float b = ceil(w.x) - w.x;
	float r = rand(vec2(coord.x, coord.y + iTime));
	return get_color(r < b ? w.y : w.x);
}

vec3 rgb2hsv(vec3 c)
{
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
    vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));

    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

vec3 hsv2rgb(vec3 c)
{
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

float scale(float l0, float r0, float l1, float r1, float x) {
	return (x - l0) / (r0 - l0) * (r1 - l1) + l1;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
	vec2 p = 2.0*(0.5 * iResolution.xy - fragCoord.xy) / iResolution.xx;
	float angle = atan(p.y, p.x);
	float turn = (angle + PI) / TAU;
	float radius = sqrt(p.x*p.x + p.y*p.y);
	
	float rotation = -0.02 * TAU * iTime;
	float turn_1 = turn + rotation;
	
	float n_sub = 3.0;
	
	float turn_sub = mod(float(n_sub) * turn_1, float(n_sub));
	
	float k_sine = 0.12 * sin(2.0 * iTime);
	float sine = k_sine * sin(50.0 * (pow(radius, 0.2) - 0.2 * iTime));
	float turn_sine = turn_sub + sine;

	int n_colors = 7;
	int i_turn = int(mod(float(n_colors) * turn_sine, float(n_colors)));
	
	float ir_numerator = 1.5;
	float ir_denominator = pow(radius*0.5, 0.6);
	float ir_dt = 5.0 * iTime;
	int i_radius = int(ir_numerator/ir_denominator + ir_dt);
		
	int i_color = int(mod(float(i_turn + i_radius), float(n_colors)));
	
	float c = 0.5/float(n_colors) + float(i_color) / float(n_colors - 0);
	
	vec3 color = vec3(c, c, c);
	
	//color *= pow(radius, 0.3)*1.0;
	
	color = dither(8.0, color, fragCoord);
	
	float ir_mod = fract(ir_numerator/ir_denominator + ir_dt);
	color *= scale(0.0, 1.0, 0.6, 1.0, pow(ir_mod, 0.5));	
	
	fragColor = vec4(color, 1.0);
}
