#version 330

smooth in vec2 v_uv;

out vec4 result;

uniform sampler2D source;
uniform sampler2D noise;

uniform float time;
uniform float param;

uniform vec4 bounds;
uniform vec2 focus;

#define M_PI 3.1415926535897932384626433832795

void main()
{
  // basic stats
  vec2 levelpos = bounds.xy + v_uv * bounds.zw;
  vec2 offset = levelpos - focus;
  float dist = length(offset);
  float theta = atan(offset.y, offset.x);

  // Circle fade
  float outer = mix(25.0, 0.0, param);
  float inner = mix(20.0, -10.0, param);
  float aoe = smoothstep(outer, inner, dist);

  float radius = mix(0.5, 1.5, param);
  vec2 mlp = mod(offset, radius);
  float circle = step(length(mlp - vec2(0.5 * radius)), sqrt(2) * radius * aoe);

  // Shockwave
  float wavefront = 100.0* param;
  float inwave = step(dist, wavefront);

  float shockwave = smoothstep(0.75, 0.25, abs(dist - wavefront));

  // Disco beams
  vec2 n_uv = vec2(theta / (2 * M_PI) + 0.5, 0.2 * param);
  float beams = step(texture(noise, n_uv).r, 0.5) * inwave;

  // Combine
  vec3 pixel = texture(source, v_uv).rgb;
  float luminosity = dot(vec3(0.21, 0.72, 0.07), pixel.rgb);
  pixel.rgb = mix(pixel.rgb, vec3(0.7, 0.3, 0.8) * (1.0 - luminosity), beams);
  pixel.rgb *= circle;
  pixel = mix(pixel, vec3(1.0), shockwave);

  result.rgb = pixel.rgb;
  result.a = 1.0;
}
