#include <bnb/glsl.frag>
#include <bnb/mediump.glsl>

#include <bnb/guided_filter.glsl>
#include <bnb/texture_bicubic.glsl>

precision highp float;
precision highp int;

BNB_IN(0)
vec2 var_uv;
BNB_IN(1)
vec2 var_bg_uv;

BNB_DECLARE_SAMPLER_2D(0, 1, s_bg_texture);
BNB_DECLARE_SAMPLER_2D(2, 3, s_src_texture);

void main()
{
    vec4 source_camera = textureLod(BNB_SAMPLER_2D(s_src_texture), var_uv, 0.f);
    vec4 source_texture = textureLod(BNB_SAMPLER_2D(s_bg_texture), var_bg_uv, 0.f);

    float fg_mask = 1.f;
    if (vbg_use_clear_color_and_guided.g == 1.f) {
        vec4 mean = bnb_guided_filter(BNB_PASS_SAMPLER_ARGUMENT(s_src_texture), var_uv, int(6), 0.01f);
        fg_mask = clamp(dot(mean.rgb, source_camera.rgb) + mean.a, 0.f, 1.f);
        fg_mask = cut_and_rescale(fg_mask, 0.18f, 2.5f);
    } else {
        fg_mask = source_camera.a;
    }

    float bg_mask = 1.f - fg_mask;
    float texture_alpha = source_texture.a;

    float is_custom_clear_color = vbg_use_clear_color_and_guided.r;

    vec2 uv_coeff = step(vec2(0.0, 0.0), var_bg_uv) - step(vec2(1., 1.), var_bg_uv);
    float texture_border = uv_coeff.x * uv_coeff.y;

    vec3 out_color;

    if (is_custom_clear_color > 0.5f) {
        // custom_clear_color was set
        out_color = mix(source_camera.rgb, vbg_clear_color.rgb, bg_mask);
        out_color = mix(out_color, source_texture.rgb * texture_border, bg_mask * texture_alpha * texture_border);
    } else {
        out_color = mix(source_camera.rgb, source_texture.rgb * texture_border, bg_mask * texture_alpha);
    }

    float complete_mask = clamp(bg_mask - (1.f - texture_alpha), 0.f, 1.f);
    float out_alpha = clamp(vbg_tex_size_a.w * texture_alpha, (1.f - complete_mask), 1.f);

    bnb_FragColor = vec4(out_color, out_alpha);
}
