/*
 * =======================================================================================
 *
 * SKY COORDINATE SYSTEM MODULE
 * Lunara Shader - Atmosphere System
 *
 * =======================================================================================
 *
 * Copyright (c) 2025 Lunara Development
 * All rights reserved. Unauthorized reproduction or distribution is prohibited.
 *
 * This module handles atmospheric coordinate transformations and positioning calculations
 * for volumetric atmospheric effects including cloud formations and weather systems.
 *
 * =======================================================================================
 */

#ifndef LU_INCLUDE_SKY_COORDINATE_SYSTEM
#define LU_INCLUDE_SKY_COORDINATE_SYSTEM

//=======================================================================================
// CONSTANTS SECTION
//=======================================================================================

/**
 * Controls the horizontal compression factor for atmospheric layers
 * Lower values = more compressed, Higher values = more stretched
 * @range: 0.01 - 0.1 (recommended: 0.04)
 */
const float atmosphericNarrowness = 0.04;

//=======================================================================================
// COORDINATE TRANSFORMATION FUNCTIONS
//=======================================================================================

/**
 * Calculates rounded atmospheric coordinates with smoothing
 * @param pos: World position coordinates (2D)
 * @param smoothness: Smoothing factor for coordinate rounding
 * - 0.125 for standard atmospheric effects
 * - 0.35 for shadow calculations
 * @return: Transformed coordinates scaled for atmospheric sampling
 * @credit: Original algorithm by SixthSurge
 */
vec2 lu_GetRoundedAtmosphericCoord(vec2 pos, float smoothness)
{
    // Offset coordinates to center grid
    vec2 coord = pos.xy + 0.5;

    // Store sign for later restoration
    vec2 signCoord = sign(coord);

    // Work with absolute values
    coord = abs(coord) + 1.0;

    // Separate integer and fractional parts
    vec2 integerPart, fractionalPart = modf(coord, integerPart);

    // Apply smooth interpolation based on smoothness parameter
    fractionalPart = smoothstep(0.5 - smoothness, 0.5 + smoothness, fractionalPart);

    // Reconstruct coordinate
    coord = integerPart + fractionalPart;

    // Restore sign and apply final scaling
    return (coord - 0.5) * signCoord / 256.0;
}

/**
 * Modifies trace position for atmospheric layer sampling
 * @param tracePos: Original trace position in world space
 * @param altitudeLevel: Altitude level identifier for layer offset
 * @return: Modified position for atmospheric sampling
 */
vec3 lu_ModifyAtmosphericTracePosition(vec3 tracePos, int altitudeLevel)
{
    // Calculate wind displacement based on time
    float windOffset;

    #if LU_CLOUD_SPEED_MULT == 100
        // Use synchronized time for consistent movement
        windOffset = syncedTime;
    #else
        // Use frame time with speed multiplier
        #define LU_CLOUD_SPEED_MULT_M LU_CLOUD_SPEED_MULT * 0.01
        windOffset = frameTimeCounter * LU_CLOUD_SPEED_MULT_M;
    #endif

    // Apply wind displacement to X axis
    tracePos.x += windOffset;

    // Apply altitude-based offset to Z axis (layer separation)
    tracePos.z += altitudeLevel * 64.0;

    // Apply horizontal compression
    tracePos.xz *= atmosphericNarrowness;

    return tracePos.xyz;
}

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

// Maintain compatibility with existing code
#define LU_GetRoundedCloudCoord lu_GetRoundedAtmosphericCoord
#define LU_ModifyTracePos lu_ModifyAtmosphericTracePosition

#endif // LU_INCLUDE_SKY_COORDINATE_SYSTEM
