// Time is in hours [0,24)
const int FOG_KEYS = 7;

#define DAWN_DENSITY 0.6
#define DAWN_DENSITY2 0.3
#define DUSK_DENSITY 0.7
#define DUSK_START_DENSITY 0.1
#define NIGHT_DENSITY 0.3
#define DAY_DENSITY 0.05

const vec2 fogKeys[FOG_KEYS] = vec2[](
    vec2(0.0, NIGHT_DENSITY), // midnight
    vec2(3.0, NIGHT_DENSITY), // pre-dawn
    vec2(6.0, DAWN_DENSITY),  // sunrise
    vec2(12.0, DAY_DENSITY),  // noon
    vec2(16.5, DUSK_START_DENSITY), // sunset
    vec2(19.0, DUSK_DENSITY), // sunset
    vec2(24.0, NIGHT_DENSITY) // wrap point
);

float catmullRom(float p0, float p1, float p2, float p3, float x)
{
	float a = p1;
	float b = 0.5 * (p2 - p0);
	float c = p0 - 2.5 * p1 + 2.0 * p2 - 0.5 * p3;
        float d = 1.5 * (p1 - p2) + 0.5 * (p3 - p0);
	return(a + x*(b + x*(c + x*d)));
}


float sampleFogSpline(float tod)
{
    tod = mod(tod, 24.0);

    int i;
    for (i = 0; i < FOG_KEYS - 1; i++)
    {
        if (tod >= fogKeys[i].x && tod <= fogKeys[i + 1].x)
            break;
    }

    int i0 = max(i - 1, 0);
    int i1 = i;
    int i2 = i + 1;
    int i3 = min(i + 2, FOG_KEYS - 1);

    float t = (tod - fogKeys[i1].x) /
              (fogKeys[i2].x - fogKeys[i1].x);

    return catmullRom(
        fogKeys[i0].y,
        fogKeys[i1].y,
        fogKeys[i2].y,
        fogKeys[i3].y,
        t);
}

float getFogDensity(float worldTime)
{

    float tod = mod((worldTime + 6000.0) / 1000.0, 24.0);

    float fog = sampleFogSpline(tod);
    fog = clamp(fog, 0.0, 1.0);

    // Rain influence
    fog = max(fog, mix(fog, 0.75, rainStrength));

    return fog;
}

float getFogDensity()
{

    return getFogDensity(worldTime);
}