#version 330 core

in float celestialAlpha;

uniform bool moon;
uniform float lunarPhase;
uniform float elevation;

out vec4 color;

const float pi = 3.14159265358979323846;

void main() {
    vec2 point = gl_PointCoord * 2.0 - 1.0;
    float radiusSquared = dot(point, point);

    if(radiusSquared > 1.0)
        discard;

    float radius = sqrt(radiusSquared);
    float edge = 1.0 - smoothstep(0.84, 1.0, radius);

    if(!moon) {
        float core = 1.0 - smoothstep(0.28, 0.36, radius);
        float innerGlow = (1.0 - smoothstep(0.20, 0.72, radius)) * 0.38;
        float outerGlow = exp(-3.2 * radius) * edge * 0.32;
        float glow = max(innerGlow, outerGlow) * (1.0 - core);
        float horizon = 1.0 - smoothstep(0.02, 0.45, max(elevation, 0.0));

        vec3 overheadCore = vec3(1.0, 0.88, 0.48);
        vec3 horizonCore = vec3(1.0, 0.43, 0.08);

        vec3 haloColor = mix(
            vec3(1.0, 0.68, 0.20),
            vec3(1.0, 0.30, 0.055),
            horizon
        );

        vec3 coreColor = mix(overheadCore, horizonCore, horizon);
        vec3 sunColor = mix(haloColor, coreColor, core);

        float alpha = clamp(core * 0.96 + glow, 0.0, 1.0) * celestialAlpha;
        color = vec4(sunColor, alpha);

        return;
    }

    const float moonRadius = 0.62;
    vec2 moonPoint = point / moonRadius;
    float moonRadiusSquared = dot(moonPoint, moonPoint);
    float phaseAngle = lunarPhase * 2.0 * pi;
    float phaseBrightness = 0.5 - 0.5 * cos(phaseAngle);

    float halo = (1.0 - smoothstep(0.46, 1.0, radius)) *
        (0.08 + phaseBrightness * 0.22);

    if(moonRadiusSquared > 1.0) {
        color = vec4(vec3(0.58, 0.70, 1.0), celestialAlpha * halo);
        return;
    }

    float moonEdge = 1.0 - smoothstep(0.90, 1.0, sqrt(moonRadiusSquared));
    vec3 normal = vec3(
        moonPoint.x,
        -moonPoint.y,
        sqrt(max(0.0, 1.0 - moonRadiusSquared))
    );

    vec3 lightDirection = normalize(vec3(sin(phaseAngle), 0.0, -cos(phaseAngle)));
    float illumination = pow(max(dot(normal, lightDirection), 0.0), 0.70);
    illumination = max(illumination, phaseBrightness * 0.22);
    vec3 moonDark = vec3(0.075, 0.090, 0.13);
    vec3 moonLight = vec3(0.94, 0.97, 1.0);
    vec3 moonColor = mix(moonDark, moonLight, illumination);
    color = vec4(moonColor, celestialAlpha * moonEdge);
}
