#version 430

layout(binding=0) uniform sampler2D tex;
layout(binding=1) uniform sampler2D tex2;
layout(binding=2) uniform sampler2D tex3;
layout(binding=3) uniform sampler2D tex4;
layout(binding=4) uniform sampler2D texPrevBlurFrame;
layout(binding=5) uniform sampler2D texPrevNorm;



in vec4 posG;
in vec3 normalG;
in vec3 normalWSG;
in vec2 uvG;
in vec3 tangentG;
in vec3 colorG;
in vec4 posW;
in float brightG;

layout(location = 0) out vec4 frag;
layout(location = 1) out vec4 frag2;

layout(location = 2) out vec4 frag3; // emitBuf


#define PI 3.1415926

uniform float g_time;

uniform float g_uvOfsX = 0.0;
uniform float g_uvScale = 1.0;
uniform float g_uv2Scale = 1.0;

uniform float g_baseBright = 0.5;
uniform float g_fadeBright = 0.5;

uniform float g_uvScaleY = 1.0;
uniform float g_uvOfsY = 0.0;

uniform float g_texBrightness = 1.0;
uniform float g_texAmbient = 0.0;
uniform float g_prevAmount = 0.0;
uniform float g_prevBlurAmount = 0.0;
uniform float g_bump = 0.0;

uniform vec4 g_color = vec4(1.0);
uniform vec4 g_ambColor = vec4(0.0);
uniform vec4 g_fadeColor = vec4(0.0);


uniform mat4 modelViewMatrix;
uniform mat4 modelViewInvMatrix;
uniform mat4 viewInvMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 projectionInvMatrix;

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

vec4 rotateXY(vec4 p, float a) {
  vec4 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 rotateXY3(vec3 p, float a) {
  return rotateXY(vec4(p, 0.0), a).xyz;
}

// 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);
}

const float zFar = 1.0;
const float zNear = 0.0;

float getPointDist(float z) {
    float clipA = zFar / (zFar - zNear);
    float clipB = zFar*zNear / (zNear - zFar);
    return clipB/(z-clipA);
}
float getPointZ(float d) {
    float clipA = zFar / (zFar - zNear);
    float clipB = zFar*zNear / (zNear - zFar);
    return (clipB + d*clipA)/d;
}

vec4 CalcEyeFromWindow(in vec3 windowSpace) {
    vec3 ndcPos;
    vec4 viewport = vec4(0.0, 0.0, g_windowWidth, g_windowHeight);
    ndcPos.xy = ((2.0 * windowSpace.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1;
//    ndcPos.z = (2.0 * windowSpace.z - zNear - zFar) / (zFar - zNear);
    ndcPos.z = (2.0 * windowSpace.z - zNear - zFar) / (zFar - zNear);
    vec4 clipPos;
    clipPos.w = projectionMatrix[3][2]/(ndcPos.z-(projectionMatrix[2][2]/projectionMatrix[2][3]));
    clipPos.xyz = ndcPos * clipPos.w;
    return projectionInvMatrix * clipPos;
}

vec2 getBump(vec2 uv) {
    vec2 d = vec2(0.01, 0.0);
    return vec2(texture2D(tex, uv+d.xy).g-texture2D(tex, uv-d.xy).g,
                texture2D(tex, uv+d.yx).g-texture2D(tex, uv-d.yx).g);
}


float atanSafe(float y, float x) {
    float ret=0.0;
    if (x!=0.0) {
        if (x>0.0) {
            ret=atan(y/x);
        } else	{
            ret=atan(y/x)+3.141592;
        }
    } else {
        if (y>=0.0) {
            ret=0.5*3.141592;
        } else {
            ret=-0.5*3.141592;
        }
    }
    return ret;
}

uniform float g_fadeEnds = 0.1;


layout(binding=6) uniform sampler2D texFFT;

uniform float g_swipePos = 0.0;
uniform float g_swipeAmp = 0.0;
uniform float g_swipeWidth = 0.0;
uniform float g_swipePow = 1.0;

uniform float g_swipeFFT = 0.0;
uniform float g_swipeFFTSpeed = 0.0;
uniform float g_swipeFFTFreq = 0.0;
uniform float g_swipeFFTThr = 0.0;

uniform float g_swipeBlend = 0.0;
uniform float g_swipeAmbient = 0.0;


vec4 getCol(float freq, vec2 ofs) {
    vec4 d;
    vec4 diffuse;
    float kalkutta, kalkuttas, kf;
    float pi = 3.141592;
    vec2 uv;


    float overlaps = g_uvScale;
    float dots = dot(vec3(0.0, 1.0, 0.0),normalize(posW.xyz));
    float dotter = (0.50+0.45*dots)*g_uvScaleY*g_uvScale+g_uvOfsY*freq;
    kalkutta = (atanSafe(posW.x, posW.z)+0.5*pi)/(2.0*pi)*overlaps*2.0;
    overlaps = fract((overlaps-0.01)*2.0)*0.5;
    kf = fract(kalkutta);
    uv = vec2(kalkutta, dotter)*1.0;
    d = texture2D(tex, uv*freq+ofs);
    d *= d;
    diffuse = d*(g_baseBright+g_fadeBright*((smoothstep(0.0, overlaps, kf))*(1.0-smoothstep(overlaps, overlaps*2.0, kf))));

    overlaps = g_uvScale*g_uv2Scale;
    kalkutta = ((atanSafe(posW.z, posW.x)+0.50*pi)/(2.0*pi)+0.0)*overlaps*2.0;
    overlaps = fract((overlaps-0.01)*2.0)*0.5;
    kf = fract(kalkutta);
    uv = vec2(kalkutta, dotter)*1.0;
    d = texture2D(tex, uv*freq+ofs);
    d *= d;
    diffuse += d*(g_baseBright+g_fadeBright*(smoothstep(0.0, overlaps, kf))*(1.0-smoothstep(overlaps, overlaps*2.0, kf)));


    dots = abs(dots);
    float fadeDo = 1.0;
    if (dots > 1.0-g_fadeEnds) {
        float fadeDots = (dots-(1.0-g_fadeEnds))*1.01;
        fadeDots = 1.0-fadeDots/(g_fadeEnds+0.0001);
        fadeDo = pow(clamp(fadeDots, 0.0, 1.0), 0.50);
    }
    diffuse *= fadeDo;
    diffuse.rgb += (1.0-fadeDo)*(g_fadeColor.rgb*g_fadeColor.a);


    return diffuse*brightG;
}

void main() {

  vec3 normal = normalG;
  vec2 uv = uvG;
  vec3 tangent = tangentG;
  vec3 color = colorG;
  float sk = 0.2;


  vec4 diffuse = getCol(1.0, vec2(0.0, 0.0));
  diffuse *= (getCol(1.5, vec2(0.07, 0.069))+vec4(0.450));
  diffuse *= (getCol(0.50, vec2(0.02, -0.069))+vec4(0.450));
  diffuse *= g_texBrightness*1.0;




//  uniform float g_swipePos = 0.0;
//  uniform float g_swipeAmp = 0.0;
//  uniform float g_swipeWidth = 0.0;

//  uniform float g_swipeFFT = 0.0;
//  uniform float g_swipeFFTFreq = 0.0;
//  uniform float g_swipeFFTSpeed = 0.0;


//  diffuse *= smoothstep(0.0, 0.05, dotter);


 diffuse.rgb *=diffuse.rgb*g_texBrightness;
 diffuse.rgb += vec3(g_texAmbient);
 diffuse.rgb *= g_color.rgb;
 diffuse.rgb += g_ambColor.rgb;

 if (g_swipeAmp > 0.001)  {
     float ssp = posW.y;

     float sp = g_swipePos;

     if (g_swipeFFT < 0.5) {
         // manual pos
         sp -= ssp;
         sp = abs(sp);
         sp = 1.0-smoothstep(0.0, g_swipeWidth, sp);
         sp = pow(sp, g_swipePow);
         sp *= g_swipeAmp;
     } else {
         // fft delay buffer values
         ssp += sp;
         //float jor = clamp(ssp*g_swipeFFTSpeed, 0.0, 1.0);
         float jor = ssp*g_swipeFFTSpeed;
         vec4 fftd = texture2D(texFFT, vec2(g_swipeFFTFreq, jor));
         sp = abs(fftd.r);
         sp = clamp(sp-g_swipeFFTThr, 0.0, 10.0);
         sp *= g_swipeAmp;
         sp = pow(sp, g_swipePow);
     }

     if (g_swipeBlend < 0.5) {
       diffuse.rgb += g_fadeColor.rgb*sp;
     } else if (g_swipeBlend < 1.5) {
       diffuse.rgb *= (g_swipeAmbient+g_fadeColor.rgb*sp);
     }

   //  diffuse.rgb = vec3(ssp);
 }



 frag.rgb = pow(diffuse.rgb, vec3(0.5));
 frag.a = 1.0;




  frag2.rgb = normalize(normalWSG).xyz;
  frag2 = clamp(frag2, -1.0, 1.0);
  frag2.a = 1.0;


  frag3.rgba = vec4(0.0, 0.0, 0.0, 1.0);
}


