#include "/lib/colors/skyColors.glsl"

float GetStarNoise(vec2 pos) {
    return fract(sin(dot(pos, vec2(12.9898, 4.1414))) * 43758.54953);
}

vec2 GetStarCoord(vec3 viewPos, float sphereness) {
    vec3 wpos = normalize((gbufferModelViewInverse * vec4(viewPos * 1000.0, 1.0)).xyz);
    vec3 starCoord = wpos / (wpos.y + length(wpos.xz) * sphereness);
    starCoord.x += 0.006 * syncedTime;
    return starCoord.xz;
}

vec3 GetStars(vec2 starCoord, float VdotU, float VdotS) {
    #if NIGHT_STAR_AMOUNT == 0
        return vec3(0.0, 0.0, 0.0);
    #endif
    if (VdotU < 0.0) return vec3(0.0);

    starCoord *= 0.2;
    float starFactor = 1024.0;
    vec2 starCell = floor(starCoord * starFactor) / starFactor;

    float star = 1.0;
    star *= GetStarNoise(starCell.xy);
    star *= GetStarNoise(starCell.xy+0.1);
    star *= GetStarNoise(starCell.xy+0.23);

    #if NIGHT_STAR_AMOUNT == 1
        star -= 0.88;
        star *= 3.0;
    #elif NIGHT_STAR_AMOUNT == 2
        star -= 0.82;
        star *= 2.2;
    #elif NIGHT_STAR_AMOUNT == 3
        star -= 0.74;
        star *= 1.6;
    #elif NIGHT_STAR_AMOUNT == 4
        star -= 0.66;
        star *= 1.2;
    #endif
    star = max0(star);
    star *= star;

    // ("bintang kebanyakan & gede kotak" fix): sebelumnya begitu satu
    // grid cell lolos ambang, SELURUH cell itu diisi penuh (persis kotak)
    // karena tidak ada perhitungan jarak/bentuk sama sekali. Sekarang
    // dihitung jarak dari satu titik di dalam cell (sama seperti teknik di
    // GetPlanets) dan di-smoothstep supaya jadi titik bulat kecil, bukan
    // kotak penuh satu cell. NIGHT_STAR_AMOUNT default juga diturunkan dari
    // 4 (paling padat) ke 2 (sedang) di common.glsl.
    vec2 starJitter = vec2(GetStarNoise(starCell + 3.3), GetStarNoise(starCell + 5.7));
    vec2 starCellUV = fract(starCoord * starFactor) - starJitter;
    float starSize = 0.09 + 0.08 * GetStarNoise(starCell + 9.1);
    star *= 1.0 - smoothstep(0.0, starSize, length(starCellUV));

    star *= min1(VdotU * 2.0) * max0(1.0 - pow(abs(VdotS) * 1.002, 100.0));
    star *= invRainFactor * pow2(pow2(invNoonFactor2)) * (1.0 - 0.3 * sunVisibility);

    return 85.0 * star * vec3(0.5, 0.52, 0.62); // v9.0: brighter stars for better night visibility
}

// A handful of large, non-twinkling, colored dots scattered very sparsely
// across the night sky, reading as distant "planets" among the star field.
vec3 GetPlanets(vec2 starCoord, float VdotU, float VdotS) {
    #ifndef NIGHT_PLANETS
        return vec3(0.0);
    #endif
    // ("banyak bulet gede di langit" fix): dekat horizon, proyeksi
    // starCoord (1/(wpos.y + ...)) makin ekstrem/nyaris singular, jadi grid
    // planet ikut "termampatkan" dan banyak cell numpuk kelihatan sekaligus
    // di layar - itu sumber "bulet gede" bejibun yang dilaporkan. Dibatasi
    // supaya cuma muncul jauh dari horizon (VdotU > 0.2) tempat proyeksinya
    // masih wajar.
    if (VdotU < 0.2) return vec3(0.0);

    float planetGridScale = 0.006; // much coarser grid than stars -> far fewer, bigger dots
    vec2 planetCell = floor(starCoord * planetGridScale * 1024.0) / 1024.0;

    // Dinaikkan dari 0.965 -> 0.995: dari ~3.5% cell berisi planet jadi
    // cuma ~0.5%, biar benar-benar jarang/sparse sesuai niat awal.
    float presence = GetStarNoise(planetCell + 7.31);
    if (presence > 0.995) return vec3(0.0); // most cells have no planet at all

    // Position the "planet" somewhere inside its cell, and give it a size + color
    vec2 jitter = vec2(GetStarNoise(planetCell + 1.7), GetStarNoise(planetCell + 4.2));
    vec2 cellUV = fract(starCoord * planetGridScale * 1024.0) - jitter;
    float dist = length(cellUV);

    // Ukuran dikecilkan (0.10-0.22 -> 0.03-0.05) supaya jadi titik terang
    // kecil seperti planet sungguhan, bukan blob besar yang dominan.
    float size = 0.03 + 0.02 * GetStarNoise(planetCell + 2.5);
    float planet = 1.0 - smoothstep(0.0, size, dist);
    planet *= planet;

    vec3 planetPalette[4] = vec3[4](
        vec3(1.00, 0.75, 0.45), // warm orange, Mars-like
        vec3(0.95, 0.90, 0.65), // pale yellow, Jupiter-like
        vec3(0.55, 0.75, 1.00), // cool blue
        vec3(0.85, 0.60, 0.85)  // faint violet
    );
    int paletteIndex = int(GetStarNoise(planetCell + 9.9) * 3.999);
    vec3 planetColor = planetPalette[paletteIndex];

    planet *= min1(VdotU * 3.0) * max0(1.0 - pow(abs(VdotS) * 1.002, 100.0));
    planet *= invRainFactor * pow2(pow2(invNoonFactor2)) * (1.0 - 0.5 * sunVisibility);

    return 5.0 * planet * planetColor;
}