#version 150

vec4 linear_fog(vec4 inColor, float vertexDistance, float fogStart, float fogEnd, vec4 fogColor) {

    float rainingness = length(fogColor.rgb - vec3(91, 102, 145) / 255);
    rainingness = smoothstep(0.0, 0.2, rainingness);
    float thunderness = length(fogColor.rgb - vec3(44, 49, 70) / 255);
    thunderness = smoothstep(0.0, 0.1, thunderness);
    float thundernessNight = length(fogColor.rgb - vec3(3, 3, 6) / 255);
    thundernessNight = smoothstep(0.0, 0.095, thundernessNight);
    float nightness = length(fogColor.rgb - vec3(10, 12, 20) / 255);
    nightness = smoothstep(0.0, 0.095, nightness);
    float oceaness = length(fogColor.rgb - vec3(22, 23, 214) / 255);
    oceaness = smoothstep(0.2, 0.5, oceaness);
    float netherness = length(fogColor.rgb - vec3(25, 65, 64) / 255);
    netherness = smoothstep(0.0, 0.3, netherness);
    float enderness = length(fogColor.rgb - vec3(22, 18, 22) / 255);
    enderness = smoothstep(0.0, 0.3, enderness);

    vec3 thunderFog = vec3(35, 39, 56) / 255;
    vec3 rainFog = vec3(85, 89, 106) / 255;
    vec3 nightRainFog = vec3(6, 8, 22) / 255;
    vec3 nightFog = vec3(7, 13, 38) / 255;
    vec3 oceanFog = vec3(10, 52, 102) / 255;

    fogColor.rgb = mix(oceanFog, mix(rainFog, mix(thunderFog, mix(nightRainFog, mix(nightFog, fogColor.rgb, nightness), thundernessNight), thunderness), rainingness), oceaness);
    fogStart = mix(3, mix(2, mix(2, fogStart, thundernessNight), thunderness), rainingness);
    fogEnd = mix(70, mix(60, mix(60, fogEnd, thundernessNight), thunderness), rainingness);

    if(enderness < 0.01){
        fogColor.rgb = vec3(21, 9, 52) / 255;  
        fogStart = mix(10, fogStart, enderness);
        fogEnd = mix(120, fogEnd, enderness);
    }

    if (vertexDistance <= fogStart) {
        return inColor;
    }

    float fogValue = vertexDistance < fogEnd ? smoothstep(fogStart, fogEnd, vertexDistance) : 1.0;
    return vec4(mix(inColor.rgb, fogColor.rgb, fogValue * fogColor.a), inColor.a);
}

float linear_fog_fade(float vertexDistance, float fogStart, float fogEnd) {
    if (vertexDistance <= fogStart) {
        return 1.0;
    } else if (vertexDistance >= fogEnd) {
        return 0.0;
    }

    return smoothstep(fogEnd, fogStart, vertexDistance);
}

float fog_distance(mat4 modelViewMat, vec3 pos, int shape) {
    if (shape == 0) {
        return length((modelViewMat * vec4(pos, 1.0)).xyz);
    } else {
        float distXZ = length((modelViewMat * vec4(pos.x, 0.0, pos.z, 1.0)).xyz);
        float distY = length((modelViewMat * vec4(0.0, pos.y, 0.0, 1.0)).xyz);
        return max(distXZ, distY);
    }
}

