/*
  End Dragon Aurora
  Serpentine bands of corrupted energy that snake across the End sky.
  More chaotic and alien than the Overworld aurora — jagged, flickering,
  with the End's purple/cyan palette.
  Based on the proven Overworld aurora framework.
*/

#ifdef END

float EndAuroraSample(vec2 coord, vec2 wind, float time) {
    // Primary curtain band
    float noise1 = texture2D(noisetex, coord * 0.04 + wind * 0.25).b * 3.0;
          noise1+= texture2D(noisetex, coord * 0.02 - wind * 0.15).b * 3.0;
    float curtain1 = max(1.0 - 2.0 * abs(noise1 - 3.0), 0.0);

    // Secondary ribbon band (offset, thinner)
    float noise2 = texture2D(noisetex, coord * 0.07 + wind * 0.35 + 0.5).b * 3.0;
          noise2+= texture2D(noisetex, coord * 0.035 - wind * 0.12 + 0.3).b * 3.0;
    float curtain2 = max(1.0 - 2.5 * abs(noise2 - 3.0), 0.0);

    float combined = curtain1 + curtain2 * 0.5;

    // Aggressive fold distortion — more chaotic than Overworld
    combined *= 1.0 + sin(coord.x * 18.0 + time * 0.5) * 0.2;
    combined *= 1.0 + sin(coord.x * 9.0 - time * 0.3) * 0.1;

    return max(combined, 0.0);
}

vec3 DrawEndAurora(vec3 viewPos, float dither, int samples) {
    float sampleStep = 1.0 / float(samples);
    float currentStep = dither * sampleStep;

    float VoU = dot(normalize(viewPos), upVec);

    // Only visible in upper hemisphere
    if (VoU <= 0.0) return vec3(0.0);

    vec3 wPos = normalize((gbufferModelViewInverse * vec4(viewPos, 1.0)).xyz);

    float time = frametime * END_AURORA_SPEED;

    // Chaotic, multi-directional wind
    vec2 wind = vec2(
        time * 0.00015 + sin(time * 0.0003) * 0.0005,
        cos(time * 0.00025) * 0.0003
    );

    // End aurora color palette — purple/cyan/magenta
    vec3 lowCol  = endCol.rgb * vec3(1.2, 0.6, 1.5) * 0.8;
    vec3 midCol  = endRiftCol * vec3(0.8, 1.2, 1.0) * 0.8;
    vec3 highCol = vec3(0.9, 0.4, 1.2) * 0.6;

    vec3 aurora = vec3(0.0);

    for (int i = 0; i < samples; i++) {
        // Project onto dome planes at increasing heights — same as Overworld
        vec3 planeCoord = wPos * ((6.0 + currentStep * 16.0) / wPos.y) * 0.003;

        vec2 coord = cameraPosition.xz * 0.00004 + planeCoord.xz;
             coord += vec2(coord.y, -coord.x) * 0.6;

        float noise = EndAuroraSample(coord, wind, time);

        if (noise > 0.0) {
            // Detail and spatial masking — same pattern as Overworld
            noise *= texture2D(noisetex, coord * 0.125 + wind * 0.25).b;
            noise *= texture2D(noisetex, coord + wind * 16.0).b * 0.5 + 0.75;
            noise = pow(noise, 0.85);
            noise = noise * noise * 3.0 * sampleStep;
            noise *= max(sqrt(1.0 - length(planeCoord.xz) * 3.0), 0.0);

            // Irregular pulsation
            float pulse = 0.6 + 0.4 * sin(time * 0.001 + coord.x * 10.0);
            float shimmer = 0.85 + 0.15 * sin(time * 0.005 + coord.y * 25.0 + float(i) * 1.5);
            noise *= pulse * shimmer;

            // 3-stop color gradient
            float t = pow(currentStep, 0.4);
            vec3 auroraColor = t < 0.5
                ? mix(lowCol, midCol, t * 2.0)
                : mix(midCol, highCol, (t - 0.5) * 2.0);

            // Bottom-lit depth falloff
            float depthFade = exp2(-6.0 * float(i) * sampleStep) * (1.0 + 0.5 * (1.0 - currentStep));
            aurora += noise * auroraColor * depthFade;
        }
        currentStep += sampleStep;
    }

    // Always visible in End, modulated by brightness setting
    float visibility = END_AURORA_BRIGHTNESS;
    visibility *= 0.7 + 0.3 * sin(frametime * 0.0006);

    return aurora * visibility * 1.15;
}

#endif
