#version 410

//#pragma include "include/skyboxes.glsl"
#pragma include "spect.glsl"
#pragma include "effects.glsl"
#pragma include "rand.glsl"
#pragma include "simplex3d.glsl"

//// Uniforms for the texture, fade effect

uniform float u_Brightness;
//uniform float u_MixFactor;
//uniform int u_From;
//uniform int u_To;
uniform sampler2D u_SpectrogramTex;
uniform float u_Time;
uniform bool u_Atmosphere;
uniform float osg_FrameTime;
//uniform bool u_Waveform;
//uniform float u_Surface;
//uniform bool u_Eq;

uniform int u_Skybox;
uniform sampler2D u_Texture1;
uniform sampler2D u_Texture2;
uniform sampler2D u_Texture3;
uniform sampler2D u_Texture4;
uniform float u_Flash;

//uniform sampler2D u_Texture;
uniform sampler2D p3d_TextureModulate[]; // default color: (1, 1, 1, 1)


// Input texture coordinates from the vertex shader
in vec2 vertMultiTexCoord0;
in vec4 vertPosition;


// Output fragment color
out vec4 p3d_FragColor;


// The MIT License
// Copyright © 2013 Inigo Quilez
float noise( in vec2 p )
{
    vec2 i = floor( p );
    vec2 f = fract( p );
    vec2 u = f*f*(3.0-2.0*f);
    return mix( mix( rand( i + vec2(0.0,0.0) ),
                     rand( i + vec2(1.0,0.0) ), u.x),
                mix( rand( i + vec2(0.0,1.0) ),
                     rand( i + vec2(1.0,1.0) ), u.x), u.y);
}


float computeWeight(float lim, float transition) {
    return smoothstep(0.0, transition, lim) *
           smoothstep(1.0, 1.0 - transition, lim);
}


float getCoefficient(vec2 lim, float transition) {
    return computeWeight(lim.x, transition) * computeWeight(lim.y, transition);
}


const float overallSpeed = 0.2;
const float gridSmoothWidth = 0.015;
const float axisWidth = 0.05;
const float majorLineWidth = 0.025;
const float minorLineWidth = 0.0125;
const float majorLineFrequency = 5.0;
const float minorLineFrequency = 1.0;
const vec4 gridColor = vec4(0.5);
const float scale = 5.0;
const vec4 lineColor = vec4(0.25, 0.5, 1.0, 1.0);
const float minLineWidth = 0.02;
const float maxLineWidth = 0.5;
const float lineSpeed = 1.0 * overallSpeed;
const float lineAmplitude = 1.0;
const float lineFrequency = 0.2;
const float warpSpeed = 0.2 * overallSpeed;
const float warpFrequency = 0.5;
const float warpAmplitude = 1.0;
const float offsetFrequency = 0.5;
const float offsetSpeed = 1.33 * overallSpeed;
const float minOffsetSpread = 0.6;
const float maxOffsetSpread = 2.0;
const int linesPerGroup = 16;

const vec4[] bgColors = vec4[]
    (
        lineColor * 0.5,
        lineColor - vec4(0.2, 0.2, 0.7, 1)
        );

#define drawCircle(pos, radius, coord) smoothstep(radius + gridSmoothWidth, radius, length(coord - (pos)))

#define drawSmoothLine(pos, halfWidth, t) smoothstep(halfWidth, 0.0, abs(pos - (t)))

#define drawCrispLine(pos, halfWidth, t) smoothstep(halfWidth + gridSmoothWidth, halfWidth, abs(pos - (t)))

#define drawPeriodicLine(freq, width, t) drawCrispLine(freq / 2.0, width, abs(mod(t, freq) - (freq) / 2.0))

float drawGridLines(float axis)
{
    return   drawCrispLine(0.0, axisWidth, axis)
           + drawPeriodicLine(majorLineFrequency, majorLineWidth, axis)
           + drawPeriodicLine(minorLineFrequency, minorLineWidth, axis);
}

float drawGrid(vec2 space)
{
    return min(1., drawGridLines(space.x)
                  +drawGridLines(space.y));
}

// probably can optimize w/ noise, but currently using fourier transform
float random(float t)
{
    return (cos(t) + cos(t * 1.3 + 1.3) + cos(t * 1.4 + 1.4)) / 3.0;
}

float getPlasmaY(float x, float horizontalFade, float offset)
{
    return random(x * lineFrequency + u_Time * lineSpeed) * horizontalFade * lineAmplitude + offset;
}

#define IN 0.15
#define OUT 0.25
#define SUNCOL vec3(1.00, 1.00, 0.95)
#define DAYCOL vec3(0.70, 0.70, 0.75)
#define NIGCOL vec3(0.02, 0.02, 0.03)
#define SPACOL vec3(0.00, 0.00, 0.00)
#define LIGCOL vec3(1.00, 1.00, 0.95)

void main() {
    // Apply the fade effect to the texture and output the final color


    vec2 vertMultiTexCoord0 = vertMultiTexCoord0;  // Dummy assignment to avoid unused variable warning

    vec3 backgroundColor;
    vec3 color;
    if (u_Atmosphere) {
        backgroundColor = SUNCOL;
        color = mix(NIGCOL, DAYCOL, smoothstep(1.0, -1.0, vertPosition.y));
    } else {
        backgroundColor = SPACOL;
        color = vec4(0.0, 0.0, 0.0, 1.0).rgb;  // Default space color
//        float r = rand(vertPosition.xyz);
//        float r = rand(vertMultiTexCoord0.xy);
//        if (r < 0.001) {
//            color.rgb = vec3(r);
//            color.rgb = vec3(1.0);
//        }
    }

    vec3 tex;
    switch (u_Skybox) {
        case 0:
            tex = texture(p3d_TextureModulate[0], vertMultiTexCoord0).rgb * u_Brightness;
            tex *= pow(abs(simplex3d(vec3(vertMultiTexCoord0 * 100., u_Time))), 4.0) * 1000.0 * u_Flash + 1.0;
            break;
        case 1:
            tex = texture(u_Texture1, vertMultiTexCoord0).rgb * u_Brightness;
            break;
        case 2:
            tex = texture(u_Texture2, vertMultiTexCoord0).rgb * u_Brightness;
            break;
        case 3:
            tex = texture(u_Texture3, vertMultiTexCoord0).rgb * u_Brightness;
            break;
        case 4:
            tex = texture(u_Texture4, vertMultiTexCoord0).rgb * u_Brightness;
            break;
    }

    if (vertPosition.y < 0.0) {
        float intensity = smoothstep(IN, OUT, length(vertPosition.xz));
        color = mix(SUNCOL, color, intensity);
        tex = mix(color, tex, intensity);
    }

//    color = tex;
//    color *= u_SkyboxFade;
//    color *= 0.5;

    p3d_FragColor = vec4(tex, 1.0);

}
