#include "/lib/filters/gauss.glsl"

vec3 chromaFringe(in sampler2D tex, in vec2 coord, in vec2 dir, in vec3 distortion) {
      return vec3(texture(tex, coord + dir * distortion.r).r, 
	  texture(tex, coord + dir * distortion.g).g, 
	  texture(tex, coord + dir * distortion.b).b);
}

vec4 gauss25lens(sampler2D tex, vec2 coord, float sigma, float threshold) {
    vec4 col = vec4(0.0);

    for (int i = 0; i<25; i++) {
        vec2 bcoord = coord + gauss25o[i]*sigma;
        col += max(texture2D(tex, bcoord)-threshold, 0.0);
    }
    return col/25;
}

void chapmanLens() {
    const int ghosts = s_ChLensGhosts;
    const float ghostDispersal = 0.3;
    const float haloWidth = 0.5;

    const vec3 ghostColor[8] = vec3[8] (
        vec3(1.00,  0.15,   0.05)*0.3, 
        vec3(0.22,  0.96,   0.32)*0.4, 
        vec3(0.12,  0.35,   0.99)*0.5,
        vec3(0.70,  0.38,   0.5)*0.16,
        vec3(0.92,  0.47,   0.42)*0.30,
        vec3(0.64,  0.98,   0.73)*0.5,
        vec3(0.48,  0.84,   0.85),
        vec3(0.32,  0.96,   0.32)
        );

    vec3 lensResult     = vec3(0.0);

    vec2 lensCoord  = -coord+vec2(1.0);

    vec2 texelSize      = 1.0/vec2(textureSize(colortex0, 0));
    vec3 distortion     = vec3(-texelSize.x*35.0, 0.0, texelSize.x*35.0);

    #if s_ChLensGhosts>=1
    vec2 ghostVec       = (vec2(0.5)-lensCoord)*ghostDispersal;

    for (int i = 0; i<ghosts; i++) {
        vec2 offset     = fract(lensCoord + ghostVec * float(i));

        float weight    = length(vec2(0.5)-offset) / length(vec2(0.5));
            weight      = linStep(1.0-weight, 0.3, 1.0);
            weight      = pow10(weight);

        //vec3 tempResult = texture(colortex5, offset).rgb;
        vec3 tempResult = chromaFringe(colortex4, offset, ghostVec*float(i), distortion*3.0);

        lensResult     += max(tempResult*ghostColor[i]*weight*0.5, 0.0)*0.5;
    }
    #endif

    #ifdef s_ChLensHalo
    vec2 haloCoord   = coord*2.0-1.0;
        haloCoord.x *= 0.55+aspectRatio*0.45;
        haloCoord.y *= 0.55+(1.0/aspectRatio)*0.45;
        haloCoord   *= 0.90;
        haloCoord    = haloCoord*0.5+0.5;

    vec2 ghostVec2   = (vec2(0.5)-haloCoord)*ghostDispersal;

    vec2 haloVec    = normalize(ghostVec2)*haloWidth;
    float weight    = length(vec2(0.5) - fract(haloCoord+haloVec))/length(vec2(0.5));
        weight      = linStep(1.0-weight, 0.5, 1.0);
        weight      = pow10(weight);

    vec2 dir        = normalize(vec2(0.5)-haloCoord);

    const vec3 haloCol = vec3(1.0, 0.82, 0.75)*0.3;
    vec3 halo       = chromaFringe(colortex4, haloCoord+haloVec, dir, distortion);
        halo       *= haloCol*weight;

    lensResult     += max(halo, 0.0);
    #endif

    returnLens += lensResult*s_ChLensIntensity*0.15;
}