#version 330

uniform sampler2D tex0;
uniform sampler2D tex1;
uniform vec2 size;
uniform float zo;

in vec2 uv;
in vec2 uv1;
in vec4 color;

layout(location = 0) out vec4 output;

uint wang_hash(uint seed)
{
    seed = (seed ^ 61u) ^ (seed >> 16u);
    seed *= 9u;
    seed = seed ^ (seed >> 4u);
    seed *= 668265261u;
    seed = seed ^ (seed >> 15u);
    return seed;
}

float rand(uint value)
{
	return float(wang_hash(value)) * (1.0 / 4294967296.0);
}


void main()
{
  float _time = mod(zo, 200.0) / 100.0; //mod(time / 10000.0, 10000);
  
	vec2 uv = gl_FragCoord.xy / size.xy;
	vec2 block = floor(gl_FragCoord.xy / vec2(32));
	vec2 uv_noise = block / vec2(64);
	uv_noise += floor(vec2(_time * 35441.0) * vec2(1534.0, 3543.0)) / vec2(64);
  
  uv_noise = mod(uv_noise, vec2(1));
	
	float block_thresh = pow(fract(_time * 4341236.0453), 3.0) * 0.0;
	float line_thresh = pow(fract(_time * 3425236.0453), 13.0) * 0.8;
	              
	vec2 uv_r = uv, uv_g = uv, uv_b = uv;

  if (rand(uint(_time * 324.09)) < 0.77)
  {
    output = texture(tex0, uv);
    return;
  } 

  float blockSize = 32;
  if (texture(tex1, uv_noise).r < block_thresh)
  //if (rand(uint(block.x + block.y)) < 0.2)
  {
  vec2 zo2 = mod(gl_FragCoord.xy, blockSize) / blockSize;
  vec4 s0 = texture(tex0, (floor((gl_FragCoord.xy) / blockSize + vec2(0.0, 0.0)) * blockSize) / size.xy);
  vec4 s1 = texture(tex0, (floor((gl_FragCoord.xy) / blockSize + vec2(1.0, 0.0)) * blockSize) / size.xy);
  vec4 s2 = texture(tex0, (floor((gl_FragCoord.xy) / blockSize + vec2(1.0, 1.0)) * blockSize) / size.xy);
  vec4 s3 = texture(tex0, (floor((gl_FragCoord.xy) / blockSize + vec2(0.0, 1.0)) * blockSize) / size.xy);
  output = mix(mix(s0, s1, zo2.x), mix(s3, s2, zo2.x), zo2.y);
  }        

   
	// glitch some blocks and lines
	if (texture(tex1, uv_noise).r < block_thresh ||
		texture(tex1, vec2(uv_noise.y, 0.01)).g < line_thresh) {

		vec2 dist = (fract(uv_noise) - 0.5) * 0.3;
		uv_r += dist * 0.1;
		uv_g += dist * 0.2;
		uv_b += dist * 0.125;
	} 
  
  output.a = 1.0;
  
	output.r = texture(tex0, uv_r).r;
	output.g = texture(tex0, uv_g).g;
	output.b = texture(tex0, uv_b).b;

	// loose luma for some blocks
	if (texture(tex1, uv_noise).g < block_thresh)
		output.rgb = output.ggg;

	if (texture(tex1, uv_noise).g < block_thresh)
		output.rgb = texture(tex0, floor(uv / 0.1) * 0.1).rgb;

	// discolor block lines
	if (texture(tex1, vec2(uv_noise.y, 0.01)).b * 3.5 < line_thresh)
		output.rgb = vec3(0.0, dot(output.rgb, vec3(1.0)), 0.0);

	// interleave lines in some blocks
	if (texture(tex1, uv_noise).g * 1.5 < block_thresh ||
		texture(tex1, vec2(uv_noise.y, 0.01)).g * 2.5 < line_thresh) {
		float line = fract(gl_FragCoord.y / 3.0);
		vec3 mask = vec3(3.0, 0.0, 0.0);
		if (line > 0.333)
			mask = vec3(0.0, 3.0, 0.0);
		if (line > 0.666) 
			mask = vec3(0.0, 0.0, 3.0);
		
		output.xyz *= mask;
	}  
}