#version 330 core

in vec2 texCoord;
in vec4 vertexFragColor;
out vec4 fragColor;
uniform sampler2D texture0;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform sampler2D texture3;
uniform vec4 color = vec4(1);
uniform float time = 1.0;
uniform float textureBias = 0.0;
uniform float animSpeed = 1.0;
uniform vec3 iResolution;

uniform vec2 resolution = vec2(1280,720)*0.9;
uniform int usePlasma = 0;
uniform int useWave = 1;
uniform int useNoise = 0;
uniform int useFillCircle = 1;

#define M_PI 3.1415926535897932384626433832795

vec2 pixelate(vec2 coord)
{
    vec2 d = vec2(1.0,1.0)/resolution;
    coord.s = floor(coord.s/d.s)*d.s;
    coord.t = floor(coord.t/d.t)*d.t;
    return coord;    
}

float rand(vec2 coord)
{
    return fract(sin(dot(coord.st,vec2(12.9898,78.233)+time)) * 43758.5453);
}

uniform vec2 scale = vec2(4,3);

vec4 plasma()
{
    vec2 coord = texCoord * scale;
    float d = 0.0;
    d+=sin(coord.x+time)*0.3;
    d+=cos(coord.y+time)*0.8;
    d-=sin(coord.x+coord.y+time);
    coord += vec2(sin(coord.x+time*2), cos(coord.y+time*3));
    d += sin(sqrt(d*10+coord.x*coord.x+coord.y*coord.y)+time);
    d = (1+cos(M_PI*1.4*d))/2.;

    return vec4(vec3(d), 1);
}

mat2 rotateZ(float angleDeg){
    float angleRad = radians(angleDeg);
    mat2 rot = mat2(vec2(cos(angleRad), sin(angleRad)), vec2(-sin(angleRad), cos(angleRad)));
    return rot;
}

float circle(vec2 coord, vec2 pos, float size){
    return min(floor(distance(coord,pos)-size),0.);
}

float repeatCircle(vec2 p, vec2 c)
{
    vec2 q = mod(p,c)-0.5*c;
    return circle( q, vec2(0), 0.1);
}


float rect( vec2 p, vec2 b )
{
  vec2 d = abs(p) - b;
  return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}

float xcross( vec2 p, vec2 b )
{
  p *= rotateZ(45.0);
  vec2 d = abs(p) - b;
  float dist = min(max(d.x,d.y),0.0) + length(max(d,0.0));
    
  p *= rotateZ(90.0);
  d = abs(p) - b;
  dist = min(dist,min(max(d.x,d.y),0.0) + length(max(d,0.0)));

  return dist;
}
float triangle(vec2 p, vec2 h)
{
  const float steinerRatio2d = sqrt(3.0)/2.0;
  vec2 q = abs(p);
  return max(-h.y,max(q.x*steinerRatio2d+p.y*0.5,-p.y)-h.x*0.5);
}

float hexagon(vec2 p, vec2 h)
{
  float dist = triangle(abs(p), h);
    
  dist = max(dist, triangle(abs(p) * rotateZ(180.0), h));

  return dist;
}

float star(vec2 p, vec2 h)
{
  float dist = triangle(abs(p), h);
    
  dist = min(dist, triangle(abs(p) * rotateZ(180.0), h));

  return dist;
}

void main()
{
    float aspectCorrection = (iResolution.x/iResolution.y);
    vec2 rayCoord = (2.0 * texCoord - 1.0);
    float ray = circle(rayCoord, vec2(-0.04,0.055), 0.37);
    /*for(float i = 0.0; i < 20.0; i++) {
        vec2 dc = rayCoord * rotateZ(30.0*i * sin(time));
        float obu = max(-hexagon(dc, vec2(0.1+i*0.2)), hexagon(dc, vec2(0.3+i*0.2)));
        ray = min(-ray, obu);
    }*/

    vec2 coord=texCoord;
    if (useWave == 1) {
      coord.s += (sin(coord.t*89.0 + time*10.0)*0.012)*(coord.t-0.5);
      coord.t += (cos(coord.s*50.0 + time*14.0)*0.015)*(coord.t-0.5);
    }

    vec4 eclipse1 = texture2D(texture0, coord, textureBias);
    vec4 eclipse2 = texture2D(texture1, coord, textureBias);
    vec4 eclipse3 = texture2D(texture2, coord, textureBias);
    vec4 eclipse4 = texture2D(texture3, coord, textureBias);

    float timePos = mod(time * animSpeed, 4.0);
    if (timePos < 1.0) {
        fragColor = mix(eclipse1, eclipse2, timePos) * color;
    } else if (timePos < 2.0) {
        fragColor = mix(eclipse2, eclipse3, timePos-1.0) * color;
    } else if (timePos < 3.0) {
        fragColor = mix(eclipse3, eclipse4, timePos-2.0) * color;
    } else {
        fragColor = mix(eclipse4, eclipse1, timePos-3.0) * color;
    }

    if (useNoise == 1) {
        fragColor *= vec4(vec3(rand(pixelate(texCoord))),1);
    }

    if(ray<0.0  && useFillCircle == 1){
        fragColor = vec4(vec3(1.0,1.0,1.0),0);
        if (useNoise == 1) {
            fragColor = vec4(vec3(rand(pixelate(texCoord))),1) * color;
            if (usePlasma == 1) {
                fragColor *= plasma();
            }
        }

    }
}
