precision mediump float;

const vec4 black = vec4(0.0, 0.0, 0.0, 1.0);

varying vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

uniform vec2 iResolution;
uniform float iTime;

#define PI 3.14159265359

vec2 rotate(vec2 uv, vec2 centerP, float rotation, float ratio) {
    vec2 ori = vec2(uv.x - centerP.x, (uv.y - centerP.y) * ratio);
    return vec2(ori.x * cos(rotation) - ori.y * sin(rotation), (ori.x * sin(rotation) + ori.y * cos(rotation)) / ratio) + centerP;
}

int inside(vec2 uv, vec4 edge) {
    return (uv.x >= edge.x && uv.x <= (edge.x + edge.z) && uv.y >= edge.y && uv.y <= (edge.y + edge.w)) ? 1 : 0;
}

void main(void) {
    vec2 uv = textureCoordinate;
    vec2 st = uv;
    float rotation;
    float offset;
    vec4 color = black;
    float ratio = iResolution.y/iResolution.x;
    float u_Time = mod(iTime, 1.5);
    float period = 0.65;

    float curPeriod;
    if (u_Time < period * 11.0/65.0) {
        curPeriod = period * 11.0/65.0;
        rotation = mix(-PI/24.0, -PI/9.0, u_Time/curPeriod);
        offset = mix(-0.7 - sqrt(2.0)*sin(PI/24.0+PI/4.0)/2.0, -0.1, u_Time/curPeriod);
    } else if (u_Time < period * 15.0/65.0) {
        float time = u_Time - period * 11.0/65.0;
        curPeriod = period * 4.0/65.0;
        rotation = mix(-PI/9.0, PI/15.0, -(cos(PI*time/curPeriod)-1.0)/2.0);
        offset = mix(-0.1, 0.2, time/curPeriod);
    } else if (u_Time < period * 25.0/65.0){
        float time = u_Time - period * 15.0/65.0;
        curPeriod = period * 10.0/65.0;
        rotation = mix(PI/15.0, -PI/24.0, -(cos(PI*clamp((time)/curPeriod, 0.0, 1.0))-1.0)/2.0);
        offset = mix(0.2, 0.0, time/curPeriod);
    } else if (u_Time < period * 35.0/65.0) {
        float time = u_Time - period * 25.0/65.0;
        curPeriod = period * 10.0/65.0;
        rotation = mix(-PI/24.0, PI/45.0, -(cos(PI*clamp((time)/curPeriod, 0.0, 1.0))-1.0)/2.0);
        offset = 0.0;
    } else if (u_Time < period * 45.0/65.0) {
        float time = u_Time - period * 35.0/65.0;
        curPeriod = period * 10.0/65.0;
        rotation = mix(PI/45.0, -PI/72.0, -(cos(PI*clamp((time)/curPeriod, 0.0, 1.0))-1.0)/2.0);
        offset = 0.0;
    } else {
        float time = u_Time - period * 45.0/65.0;
        curPeriod = period * 20.0/65.0;
        rotation = mix(-PI/72.0, 0.0, -(cos(PI*clamp((time)/curPeriod, 0.0, 1.0))-1.0)/2.0);
        offset = 0.0;
    }

    st.y += offset;
    st = rotate(st, vec2(0.5), rotation, ratio);
    if (inside(st, vec4(0.0, 0.0, 1.0, 1.0)) == 1) {
        color = texture2D(inputImageTexture, st);
    }

    gl_FragColor = color;
}