// GlitchDisplace — MSL, generated from https://github.com/gl-transitions/gl-transitions/blob/master/transitions/GlitchDisplace.glsl
// Author: Matt DesLauriers
// License: MIT
// Description: Blocks of the image are displaced in a glitch that flashes into the incoming image
// Bindings and uniform layout: see the gl-transitions package README

// language: metal1.0
#include <metal_stdlib>
#include <simd/simd.h>

using metal::uint;

struct Uniforms {
    float progress;
    float ratio;
};

float ease2(
    thread float& t
) {
    float local = {};
    float _e34 = t;
    if (_e34 == 1.0) {
        float _e36 = t;
        local = _e36;
    } else {
        float _e37 = t;
        local = 1.0 - metal::pow(2.0, -10.0 * _e37);
    }
    float _e41 = local;
    return _e41;
}

float random(
    thread metal::float2& co
) {
    float a = {};
    float b = {};
    float c = {};
    float dt = {};
    float sn = {};
    a = 12.9898;
    b = 78.233;
    c = 43758.547;
    metal::float2 _e38 = co;
    float _e39 = a;
    float _e40 = b;
    dt = metal::dot(_e38, metal::float2(_e39, _e40));
    float _e43 = dt;
    sn = _e43 - (metal::floor(_e43 / 3.14) * 3.14);
    float _e48 = sn;
    float _e50 = c;
    return metal::fract(metal::sin(_e48) * _e50);
}

float voronoi(
    thread metal::float2& x
) {
    metal::float2 p = {};
    metal::float2 f = {};
    float res = {};
    float j = {};
    float i = {};
    metal::float2 b_1 = {};
    metal::float2 r = {};
    metal::float2 param = {};
    float d = {};
    metal::float2 _e42 = x;
    p = metal::floor(_e42);
    metal::float2 _e44 = x;
    f = metal::fract(_e44);
    res = 8.0;
    j = -1.0;
    uint2 loop_bound = uint2(4294967295u);
    bool loop_init = true;
    while(true) {
        if (metal::all(loop_bound == uint2(0u))) { break; }
        loop_bound -= uint2(loop_bound.y == 0u, 1u);
        if (!loop_init) {
            float _e70 = j;
            j = _e70 + 1.0;
        }
        loop_init = false;
        float _e46 = j;
        if (_e46 <= 1.0) {
            i = -1.0;
            uint2 loop_bound_1 = uint2(4294967295u);
            bool loop_init_1 = true;
            while(true) {
                if (metal::all(loop_bound_1 == uint2(0u))) { break; }
                loop_bound_1 -= uint2(loop_bound_1.y == 0u, 1u);
                if (!loop_init_1) {
                    float _e68 = i;
                    i = _e68 + 1.0;
                }
                loop_init_1 = false;
                float _e48 = i;
                if (_e48 <= 1.0) {
                    float _e50 = i;
                    float _e51 = j;
                    b_1 = metal::float2(_e50, _e51);
                    metal::float2 _e53 = b_1;
                    metal::float2 _e54 = f;
                    metal::float2 _e56 = p;
                    metal::float2 _e57 = b_1;
                    param = _e56 + _e57;
                    float _e59 = random(param);
                    r = (_e53 - _e54) + metal::float2(_e59);
                    metal::float2 _e62 = r;
                    metal::float2 _e63 = r;
                    d = metal::dot(_e62, _e63);
                    float _e65 = res;
                    float _e66 = d;
                    res = metal::min(_e65, _e66);
                    continue;
                } else {
                    break;
                }
            }
            continue;
        } else {
            break;
        }
    }
    float _e72 = res;
    return metal::sqrt(_e72);
}

metal::float2 displace(
    thread metal::float4& tex,
    thread metal::float2& texCoord,
    thread float& dotDepth,
    thread float& textureDepth,
    thread float& strength
) {
    float b_2 = {};
    metal::float2 param_1 = {};
    float g = {};
    metal::float2 param_2 = {};
    float r_1 = {};
    metal::float2 param_3 = {};
    metal::float4 dt_1 = {};
    metal::float4 dis = {};
    metal::float2 res_uv = {};
    metal::float2 _e46 = texCoord;
    param_1 = (_e46 * 0.003) + metal::float2(2.0);
    float _e50 = voronoi(param_1);
    b_2 = _e50;
    metal::float2 _e51 = texCoord;
    param_2 = _e51 * 0.2;
    float _e53 = voronoi(param_2);
    g = _e53;
    metal::float2 _e54 = texCoord;
    param_3 = _e54 - metal::float2(1.0);
    float _e57 = voronoi(param_3);
    r_1 = _e57;
    metal::float4 _e58 = tex;
    dt_1 = _e58 * 1.0;
    metal::float4 _e60 = dt_1;
    float _e61 = dotDepth;
    metal::float4 _e65 = tex;
    float _e66 = textureDepth;
    dis = ((_e60 * _e61) + metal::float4(1.0)) - (_e65 * _e66);
    float _e70 = dis[0u];
    float _e72 = textureDepth;
    float _e73 = dotDepth;
    dis[0u] = (_e70 - 1.0) + (_e72 * _e73);
    float _e78 = dis[1u];
    float _e80 = textureDepth;
    float _e81 = dotDepth;
    dis[1u] = (_e78 - 1.0) + (_e80 * _e81);
    float _e85 = strength;
    float _e87 = dis[0u];
    dis[0u] = _e87 * _e85;
    float _e90 = strength;
    float _e92 = dis[1u];
    dis[1u] = _e92 * _e90;
    metal::float2 _e95 = texCoord;
    res_uv = _e95;
    float _e97 = res_uv[0u];
    float _e99 = dis[0u];
    res_uv[0u] = (_e97 + _e99) - 0.0;
    float _e104 = res_uv[1u];
    float _e106 = dis[1u];
    res_uv[1u] = _e104 + _e106;
    metal::float2 _e109 = res_uv;
    return _e109;
}

float ease1(
    thread float& t_1
) {
    float local_1 = {};
    float local_2 = {};
    float _e35 = t_1;
    float _e37 = t_1;
    if ((_e35 == 0.0) || (_e37 == 1.0)) {
        float _e40 = t_1;
        local_1 = _e40;
    } else {
        float _e41 = t_1;
        if (_e41 < 0.5) {
            float _e43 = t_1;
            local_2 = 0.5 * metal::pow(2.0, (20.0 * _e43) - 10.0);
        } else {
            float _e48 = t_1;
            local_2 = (-0.5 * metal::pow(2.0, 10.0 - (_e48 * 20.0))) + 1.0;
        }
        float _e54 = local_2;
        local_1 = _e54;
    }
    float _e55 = local_1;
    return _e55;
}

metal::float4 getToColor(
    thread metal::float2& uv,
    metal::sampler _sampler,
    metal::texture2d<float, metal::access::sample> _to
) {
    float _e34 = uv[0u];
    float _e36 = uv[1u];
    metal::float4 _e39 = _to.sample(_sampler, metal::float2(_e34, 1.0 - _e36), metal::level(0.0));
    return _e39;
}

metal::float4 getFromColor(
    thread metal::float2& uv_1,
    metal::texture2d<float, metal::access::sample> _from,
    metal::sampler _sampler
) {
    float _e34 = uv_1[0u];
    float _e36 = uv_1[1u];
    metal::float4 _e39 = _from.sample(_sampler, metal::float2(_e34, 1.0 - _e36), metal::level(0.0));
    return _e39;
}

metal::float4 transition(
    thread metal::float2& uv_2,
    metal::texture2d<float, metal::access::sample> _from,
    metal::sampler _sampler,
    metal::texture2d<float, metal::access::sample> _to,
    constant Uniforms& uniforms
) {
    metal::float2 p_1 = {};
    metal::float4 color1_ = {};
    metal::float2 param_4 = {};
    metal::float4 color2_ = {};
    metal::float2 param_5 = {};
    metal::float2 disp = {};
    float param_6 = {};
    metal::float4 param_7 = {};
    metal::float2 param_8 = {};
    float param_9 = {};
    float param_10 = {};
    float param_11 = {};
    metal::float2 disp2_ = {};
    float param_12 = {};
    metal::float4 param_13 = {};
    metal::float2 param_14 = {};
    float param_15 = {};
    float param_16 = {};
    float param_17 = {};
    metal::float4 dColor1_ = {};
    metal::float2 param_18 = {};
    metal::float4 dColor2_ = {};
    metal::float2 param_19 = {};
    float val = {};
    float param_20 = {};
    metal::float3 gray = {};
    metal::float2 _e59 = uv_2;
    p_1 = _e59 / metal::float2(1.0, 1.0);
    metal::float2 _e61 = p_1;
    param_4 = _e61;
    metal::float4 _e62 = getFromColor(param_4, _from, _sampler);
    color1_ = _e62;
    metal::float2 _e63 = p_1;
    param_5 = _e63;
    metal::float4 _e64 = getToColor(param_5, _sampler, _to);
    color2_ = _e64;
    float _e66 = uniforms.progress;
    param_6 = _e66;
    float _e67 = ease1(param_6);
    metal::float4 _e69 = color1_;
    param_7 = _e69;
    metal::float2 _e70 = p_1;
    param_8 = _e70;
    param_9 = 0.33;
    param_10 = 0.7;
    param_11 = 1.0 - _e67;
    metal::float2 _e71 = displace(param_7, param_8, param_9, param_10, param_11);
    disp = _e71;
    float _e73 = uniforms.progress;
    param_12 = _e73;
    float _e74 = ease2(param_12);
    metal::float4 _e75 = color2_;
    param_13 = _e75;
    metal::float2 _e76 = p_1;
    param_14 = _e76;
    param_15 = 0.33;
    param_16 = 0.5;
    param_17 = _e74;
    metal::float2 _e77 = displace(param_13, param_14, param_15, param_16, param_17);
    disp2_ = _e77;
    metal::float2 _e78 = disp;
    param_18 = _e78;
    metal::float4 _e79 = getToColor(param_18, _sampler, _to);
    dColor1_ = _e79;
    metal::float2 _e80 = disp2_;
    param_19 = _e80;
    metal::float4 _e81 = getFromColor(param_19, _from, _sampler);
    dColor2_ = _e81;
    float _e83 = uniforms.progress;
    param_20 = _e83;
    float _e84 = ease1(param_20);
    val = _e84;
    metal::float4 _e85 = dColor2_;
    metal::float4 _e86 = dColor1_;
    gray = metal::float3(metal::dot(metal::min(_e85, _e86).xyz, metal::float3(0.299, 0.587, 0.114)));
    metal::float3 _e91 = gray;
    dColor2_ = metal::float4(_e91.x, _e91.y, _e91.z, 1.0);
    metal::float4 _e96 = dColor2_;
    dColor2_ = _e96 * 2.0;
    metal::float4 _e98 = color1_;
    metal::float4 _e99 = dColor2_;
    float _e101 = uniforms.progress;
    color1_ = metal::mix(_e98, _e99, metal::float4(metal::smoothstep(0.0, 0.5, _e101)));
    metal::float4 _e105 = color2_;
    metal::float4 _e106 = dColor1_;
    float _e108 = uniforms.progress;
    color2_ = metal::mix(_e105, _e106, metal::float4(metal::smoothstep(1.0, 0.5, _e108)));
    metal::float4 _e112 = color1_;
    metal::float4 _e113 = color2_;
    float _e114 = val;
    return metal::mix(_e112, _e113, metal::float4(_e114));
}

void main_1(
    metal::texture2d<float, metal::access::sample> _from,
    metal::sampler _sampler,
    metal::texture2d<float, metal::access::sample> _to,
    constant Uniforms& uniforms,
    thread metal::float4& _fragColor,
    thread metal::float2& _uv_1
) {
    metal::float2 param_21 = {};
    metal::float2 _e33 = _uv_1;
    param_21 = _e33;
    metal::float4 _e34 = transition(param_21, _from, _sampler, _to, uniforms);
    _fragColor = _e34;
    return;
}

struct main_Input {
    metal::float2 _uv [[user(loc0), center_perspective]];
};
struct main_Output {
    metal::float4 member [[color(0)]];
};
fragment main_Output main_(
  main_Input varyings [[stage_in]]
, metal::texture2d<float, metal::access::sample> _from [[texture(0)]]
, metal::sampler _sampler [[sampler(0)]]
, metal::texture2d<float, metal::access::sample> _to [[texture(1)]]
, constant Uniforms& uniforms [[buffer(0)]]
) {
    metal::float4 _fragColor = {};
    metal::float2 _uv_1 = {};
    const auto _uv = varyings._uv;
    _uv_1 = _uv;
    main_1(_from, _sampler, _to, uniforms, _fragColor, _uv_1);
    metal::float4 _e3 = _fragColor;
    return main_Output { _e3 };
}
