#version 430

layout(binding=0) uniform sampler2D srcBg;
layout(location = 0) out vec4 frag;
layout(location = 1) out vec4 frag2;

uniform float g_time;

precision highp float;
in highp vec2 coordG;

uniform float g_blurStrength = 1.0;

uniform float g_windowWidth = 1280.0;
uniform float g_windowHeight = 720.0;

uniform float g_readSize = 1.0;
uniform float g_screenSize = 1.0;

// google glsl rand gave this, thanks and credit flies to
// http://stackoverflow.com/questions/4200224/random-noise-functions-for-glsl
float rand(vec2 co) {
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

vec2 rotateXY(vec2 p, float a) {
  vec2 r = p;
  r.x = cos(a)*p.x - sin(a)*p.y;
  r.y = sin(a)*p.x + cos(a)*p.y;
  return r;
}


vec3 spreadSpec3(vec3 c, float sp) {
    sp = fract(sp);
    c.r *= smoothstep(1.0, 0.0, (1.0-sp)*1.0);
    c.g *= smoothstep(1.0, 0.0, abs((sp-0.5)*2.0));
    c.b *= smoothstep(1.0, 0.0, sp*1.0);
    return c;
}

vec4 spreadSpec(vec4 c, float sp) {
    sp = fract(sp);
    c.r *= smoothstep(1.0, 0.0, (1.0-sp)*1.0);
    c.g *= smoothstep(1.0, 0.0, abs((sp-0.5)*2.0));
    c.b *= smoothstep(1.0, 0.0, sp*1.0);
    return c;
}

// from Iq: http://www.iquilezles.org/www/articles/texture/texture.htm
vec4 getTexel( sampler2D s, vec2 p ) {
    vec2 texRes = vec2(g_windowWidth, g_windowHeight);
    p = p*texRes+0.5;

    vec2 i = floor(p);
    vec2 f = p - i;
    f = f*f*f*(f*(f*6.0-15.0)+10.0);
    p = i + f;

    p = (p - 0.5)/texRes;
    return texture2D(s, p);
}

void sampleAndAdd(vec2 c, inout vec4 color, float mul) {
    c = clamp(c, 0.5-g_readSize*(0.5-1.50/(g_windowWidth*g_screenSize)), 0.5+g_readSize*(0.5-1.50/(g_windowHeight*g_screenSize)));
    //vec4 texBg = getTexel(srcBg, c);
    vec4 texBg = clamp(texture2D(srcBg, c), -10000.0, 10000.0)*mul;
   // texBg *= texBg;
    color += texBg.rgba;
}

uniform float kernel_wm = 4.0;
uniform float kernel_ws = 2.0;
uniform float kernel_wc = 1.0;

uniform float kernelSX = 1.0;
uniform float kernelSY = 1.0;

uniform float kernelRot = 0.0;
uniform float kernelRotX = 0.0;
uniform float kernelRotY = 0.0;

void main() {
    vec4 color = vec4(0.0);
    // vec2 coordCen = coordG-vec2(0.5, 0.5);

    vec4 texBg;

    vec2 c;

    /*
    vec3 co = vec3(kernelSX/g_windowWidth, kernelSY/g_windowHeight, 0.0)*g_blurStrength*g_readSize;

    vec2 cc = (coordG-vec2(0.5))*g_readSize+vec2(0.5);

    cc = clamp(cc, 0.5-g_readSize*(0.5-1.50/(g_windowWidth*g_screenSize)), 0.5+g_readSize*(0.5-1.50/(g_windowHeight*g_screenSize)));

    vec4 orig = texture2D(srcBg, cc);

    co.xy = rotateXY(co.xy, kernelRot+cc.x*kernelRotX+cc.y*kernelRotY);

    sampleAndAdd(cc, color, kernel_wm);
    sampleAndAdd(cc+co.xz, color, kernel_ws);
    sampleAndAdd(cc-co.xz, color, kernel_ws);
    sampleAndAdd(cc+co.zy, color, kernel_ws);
    sampleAndAdd(cc-co.zy, color, kernel_ws);
    sampleAndAdd(cc+co.xy, color, kernel_wc);
    sampleAndAdd(cc-co.xy, color, kernel_wc);
    sampleAndAdd(cc+vec2(-co.x, co.y), color, kernel_wc);
    sampleAndAdd(cc-vec2(-co.x, co.y), color, kernel_wc);
    color /= (kernel_wm+(kernel_ws+kernel_wc)*4.0);
*/


    vec3 coCor = vec3(kernelSX/g_windowWidth, kernelSY/g_windowHeight, 0.0)*g_blurStrength*g_readSize;
    vec3 coCor2 = vec3(kernelSX/g_windowWidth, -kernelSY/g_windowHeight, 0.0)*g_blurStrength*g_readSize;
    vec3 coSideX = vec3(kernelSX/g_windowWidth, 0.0, 0.0)*g_blurStrength*g_readSize;
    vec3 coSideY = vec3(0.0, kernelSY/g_windowHeight, 0.0)*g_blurStrength*g_readSize;


    vec2 cc = (coordG-vec2(0.5))*g_readSize+vec2(0.5);

    cc = clamp(cc, 0.5-g_readSize*(0.5-1.50/(g_windowWidth*g_screenSize)), 0.5+g_readSize*(0.5-1.50/(g_windowHeight*g_screenSize)));

    vec4 orig = texture2D(srcBg, cc);

    coCor.xy = rotateXY(coCor.xy, kernelRot+cc.x*kernelRotX+cc.y*kernelRotY);
    coCor2.xy = rotateXY(coCor2.xy, kernelRot+cc.x*kernelRotX+cc.y*kernelRotY);
    coSideX.xy = rotateXY(coSideX.xy, kernelRot+cc.x*kernelRotX+cc.y*kernelRotY);
    coSideY.xy = rotateXY(coSideY.xy, kernelRot+cc.x*kernelRotX+cc.y*kernelRotY);

    sampleAndAdd(cc, color, kernel_wm);
    sampleAndAdd(cc+coSideX.xy, color, kernel_ws);
    sampleAndAdd(cc-coSideX.xy, color, kernel_ws);
    sampleAndAdd(cc+coSideY.xy, color, kernel_ws);
    sampleAndAdd(cc-coSideY.xy, color, kernel_ws);
    sampleAndAdd(cc+coCor.xy, color, kernel_wc);
    sampleAndAdd(cc-coCor.xy, color, kernel_wc);
    sampleAndAdd(cc+(coCor2.xy), color, kernel_wc);
    sampleAndAdd(cc-(coCor2.xy), color, kernel_wc);
    color /= (kernel_wm+(kernel_ws+kernel_wc)*4.0);


//    sampleAndAdd(cc+co.xz, color, 1.0);
//    sampleAndAdd(cc-co.xz, color, 1.0);
//    sampleAndAdd(cc+co.zy, color, 1.0);
//    sampleAndAdd(cc-co.zy, color, 1.0);
//    color /= 4.0;

//    float specAm = 0.1;
//    color = color*(1.0-specAm)+specAm*spreadSpec3(color, color.r+color.g+color.b);

 //   color = pow(color, vec3(0.5));

    frag = vec4(color);
//    frag.r = 1.0;
    frag2 = vec4(0.0, 0.0, 0.0, 0.0);
}
