/*
 * =======================================================================================
 *
 * ENVIRONMENTAL EFFECTS MODULE
 * Lunara Shader - Weather & Dimensional Effects
 *
 * =======================================================================================
 *
 * Copyright (c) 2025 Lunara Development
 * All rights reserved. Unauthorized reproduction or distribution is prohibited.
 *
 * This consolidated module handles environmental atmospheric effects including
 * rainbow rendering, disabled volumetric effects (ender beams, nether storm),
 * and weather-based visual enhancements. Optimized for performance.
 *
 * =======================================================================================
 */

#ifndef LU_INCLUDE_ENVIRONMENTAL_EFFECTS
#define LU_INCLUDE_ENVIRONMENTAL_EFFECTS

//=======================================================================================
// RAINBOW MODULE
//=======================================================================================

#define LU_RAINBOW_DIAMETER 1.00
#define LU_RAINBOW_STYLE 1

/**
 * Generates rainbow effects after rain with realistic atmospheric conditions
 * @param translucentMult: Translucent material color multiplier
 * @param z0: Near depth value
 * @param z1: Far depth value
 * @param lViewPos: View distance for rainbow calculation
 * @param lViewPos1: Extended view distance
 * @param VdotL: View direction dot light vector
 * @param dither: Temporal dithering value
 * @return: RGB rainbow color contribution
 *
 * Features:
 * - Post-rain atmospheric conditions
 * - Configurable rainbow diameter and style
 * - Realistic light scattering simulation
 * - Cloud interaction and depth awareness
 */
vec3 lu_GetRainbow(vec3 translucentMult, float z0, float z1, float lViewPos, float lViewPos1, float VdotL, float dither) {
    vec3 rainbow = vec3(0.0);

    float rainbowTime = lu_min1(lu_max0(SdotU - 0.1) / 0.15);
    rainbowTime = clamp(rainbowTime - lu_pow2(lu_pow2(lu_pow2(noonFactor))) * 8.0, 0.0, 0.85);

    #if LU_RAINBOWS == 1 // After Rain
        rainbowTime *= lu_sqrt2(lu_max0(wetness - 0.333) * 1.5) * invRainFactor * inRainy;
    #endif

    if (rainbowTime > 0.001) {
        float cloudLinearDepth = texelFetch(colortex4, texelCoord, 0).r;
        float cloudDistance = lu_pow2(cloudLinearDepth + OSIEBCA * dither) * far;
        if (cloudDistance < lViewPos1) lViewPos = cloudDistance;

        float rainbowLength = max(far, 128.0) * 0.9;

        float rainbowCoord = lu_clamp01(1.0 - (VdotL + 0.75) / (0.0625 * LU_RAINBOW_DIAMETER));
        float rainbowFactor = rainbowCoord * (1.0 - rainbowCoord);
              rainbowFactor = lu_pow2(lu_pow2(rainbowFactor * 3.7));
              rainbowFactor *= lu_pow2(lu_min1(lViewPos / rainbowLength));
              rainbowFactor *= rainbowTime;
              rainbowFactor *= 1.0 - lu_GetDepthFactor();

        if (rainbowFactor > 0.0) {
            #if LU_RAINBOW_STYLE == 1
                // rainbow with multiple layers
                float rainbowCoordM = pow(rainbowCoord, 1.4 + max(rainbowCoord - 0.5, 0.0) * 1.6);
                rainbowCoordM = smoothstep(0.0, 1.0, rainbowCoordM) * 0.85;
                rainbowCoordM += (dither - 0.5) * 0.1;

                // Triple-layer rainbow for realism
                rainbow += clamp(abs(mod(rainbowCoordM * 6.0 + vec3(-0.55,4.3,2.2) ,6.0)-3.0)-1.0, 0.0, 1.0);
                rainbowCoordM += 0.1;
                rainbow += clamp(abs(mod(rainbowCoordM * 6.0 + vec3(-0.55,4.3,2.2) ,6.0)-3.0)-1.0, 0.0, 1.0);
                rainbowCoordM -= 0.2;
                rainbow += clamp(abs(mod(rainbowCoordM * 6.0 + vec3(-0.55,4.3,2.2) ,6.0)-3.0)-1.0, 0.0, 1.0);
                rainbow /= 3.0;

                // Red enhancement for outer edge
                rainbow.r += lu_pow2(max(rainbowCoord - 0.5, 0.0)) * (max(1.0 - rainbowCoord, 0.0)) * 26.0;
                rainbow = pow(rainbow, vec3(2.2)) * vec3(0.25, 0.075, 0.25) * 3.0;
            #else
                // Simple rainbow style
                float rainbowCoordM = pow(rainbowCoord, 1.35);
                rainbowCoordM = smoothstep(0.0, 1.0, rainbowCoordM);
                rainbow += clamp(abs(mod(rainbowCoordM * 6.0 + vec3(0.0,4.0,2.0) ,6.0)-3.0)-1.0, 0.0, 1.0);
                rainbow *= rainbow * (3.0 - 2.0 * rainbow);
                rainbow = pow(rainbow, vec3(2.2)) * vec3(0.25, 0.075, 0.25) * 3.0;
            #endif

            // Apply translucent material interaction
            if (z1 > z0 && lViewPos < rainbowLength)
                rainbow *= mix(translucentMult, vec3(1.0), lViewPos / rainbowLength);

            rainbow *= rainbowFactor;
        }
    }

    return rainbow;
}

//=======================================================================================
// DISABLED VOLUMETRIC EFFECTS
//=======================================================================================

/**
 * Ender Beams Effect (DISABLED)
 * Originally provided mystical light beams in End dimension
 * Disabled to remove floating volumetric effects for cleaner visuals
 * @return: Always returns vec3(0.0) - no effect
 */
vec3 lu_DrawEnderBeams(float VdotU, vec3 playerPos) {
    // Lunara Shader: Disabled ender beams to remove floating light beams
    return vec3(0.0);
}

/**
 * Nether Storm Effect (DISABLED)
 * Originally provided volumetric storm effects in Nether dimension
 * Disabled to remove floating volumetric effects for cleaner visuals
 * @return: Always returns vec4(0.0) - no effect
 */
vec4 lu_GetNetherStorm(vec3 color, vec3 translucentMult, vec3 nPlayerPos, vec3 playerPos, float lViewPos, float lViewPos1, float dither) {
    // Lunara Shader: Disabled nether storm to remove floating volumetric effects
    return vec4(0.0);
}

vec4 lu_GetEndStorm(vec3 color, vec3 translucentMult, vec3 nPlayerPos, vec3 playerPos, float lViewPos, float lViewPos1, float dither) {
    return vec4(0.0);
}

//=======================================================================================
// LEGACY COMPATIBILITY
//=======================================================================================

// Maintain backward compatibility with existing environmental systems
#define LU_GetWeatherEffects GetRainbow
#define LU_GetEnvironmentalFog GetNetherStorm

#endif // LU_INCLUDE_ENVIRONMENTAL_EFFECTS
