#version 330 core 
#define GLSL_VERSION 3.00
#define PI 3.14159265359

out vec4 FragColor;
uniform vec3 sunPos;
uniform vec3 moonPos;

in vec3 ourNormal;
in vec2 uv;
in float ypos;
in vec3 FragPos;

uniform vec3 data;  // data.x time
//uniform sampler2D texture1;
uniform float daytime; // -1-0-1 night-day-night

// Pseudo-random hash function based on 2D coordinates
float hash(vec2 p) {
    return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
}

// Generate four random values per grid cell
vec4 hash42(ivec2 p) {
    vec2 p2 = vec2(p);
    return vec4(
        hash(p2),
        hash(p2 + vec2(1.0, 0.0)),
        hash(p2 + vec2(0.0, 1.0)),
        hash(p2 + vec2(1.0, 1.0))
    );
}

void main()
{
   vec3 norm=normalize(ourNormal);
   vec3 sunColor = vec3(1.0f, 0.93f, 0.74f); // sky sphere 
   vec3 moonColor = vec3(0.7f, 1.0f, 0.8f); // lumination
   float sunStrength=1.0f;
   float moonStrength=1.0f;
   vec3 sunDir=normalize(sunPos - FragPos);
   float diff=max(dot(norm, sunDir), 0.0);
   vec3 diffuse=diff*sunColor*sunStrength;
   vec3 moonDir=normalize(moonPos - FragPos);
   float diff2=max(dot(norm, moonDir), 0.0);
   vec3 diffuse2=diff2*moonColor*moonStrength;

	//colorSample = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); // sky colors, not light
   vec3 color1 = vec3(0.5,0.6,0.9); // day
   vec3 color2 = vec3(0.28,0.6,0.87);
   vec3 color3 = vec3(0.08,0.82,1.0);
   //vec3 color1 = vec3(1,0,0); // //bottom
   //vec3 color2 = vec3(0,1,0); // top
   //vec3 color3 = vec3(0,0,1); // middle?
   vec3 color4 = vec3(0.05,0.0,0.2); // night
   vec3 color5 = vec3(0.0,0.05,0.3);
   vec3 color6 = vec3(0.08,0.0,0.1);
   
   float methodA=ypos;
   float methodB=(ypos*0.5f)+0.5f;
   float methodC=1.0f-abs(ypos);
   float methodD=(methodA*2);
   float methodE=(methodA*2)-1;
  

    float dt=abs(daytime);
 
   
   //float ambientStrength = 0.1f;
	vec3 ourColor = vec3(mix(color3,color2,methodD));
	ourColor = mix(ourColor,color1,methodE);
	vec3 ourColor2 = vec3(mix(color5,color4,methodD));
	ourColor2 = mix(ourColor2,color6,methodE);
   vec3 blendColor = vec3(mix(ourColor,ourColor2,dt));
   //vec3 ambient = ambientStrength * blendColor;
   vec3 finalColor = (blendColor + ((diffuse + diffuse2) * 0.1)) * blendColor;
   //vec3 finalColor = (blendColor + ((diffuse + diffuse2) * 0.5)) * sin(ypos);






    // night stars
    float rad=PI/180.0;
    //float time=(data.x * 1.0 / 86400) * 25000; // 50 breaks
    //float time = ((data.x * 25000.0f) * rad) * 25; // 50 breaks
    float phase = data.x;




//-- // Example: Day-night cycle
   //-- float light = 0.5 + 0.5 * sin(uTime); // 0 to 1 over 86400 seconds
   //-- 
   //-- // Example: Cloud movement
   //-- vec2 cloudOffset = vec2(sin(uTime), cos(uTime)) * 0.5;
   //-- 
   //-- // Example: Star twinkle every 10 seconds
   float twinkleSpeed = 86400.0 / 50.0;
   //-- float twinkle = sin(uTime * twinkleSpeed);

    //float time = sin(phase * twinkleSpeed);
    float time = phase / (2.0 * 3.14159); // Normalizes phase from 0-2π to 0-1

    time *= twinkleSpeed;



    // Configuration parameters (adjustable)
    float numCells = 43.0;      // Number of grid cells across UV space (20x20 grid)
    float maxBrightness = 1.0;  // Maximum star brightness
    //float twinkleSpeed = 2.0;   // Speed of twinkling
    //float sigma = 0.0000002;      // Glow size (in UV space, tweak based on resolution)
    float sigma = 0.000002;      // Glow size (in UV space, tweak based on resolution)
    float starDensity = 0.5;    // Fraction of cells with stars (0.0 to 1.0)


    vec2 moving_uv = uv + vec2(0.0, time / (2.0 * 3.14159));
    //vec2 moving_uv = uv + vec2(0.0, time / (1.0 * 6.28));
    //vec2 moving_uv = uv + vec2(time, 0.0);
    ivec2 cell = ivec2(floor(moving_uv * numCells));

    vec3 totalColor = vec3(0.0);  // Accumulate star contributions

    // Check the current cell and its 8 neighbors for star contributions
    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            ivec2 neighbor = cell + ivec2(i, j);
            vec4 h = hash42(neighbor);

            // Only create a star if the random value meets density threshold
            if (h.w < starDensity) {
                // Random position offset within the cell
                vec2 starOffset = h.xy;
                vec2 starPos = (vec2(neighbor) + starOffset) / numCells;

                // Distance from fragment to star
                float d = length(moving_uv - starPos);

                // Star brightness with twinkling
                float baseBrightness = h.z * maxBrightness;
                float twinklePhase = h.w * 6.28318; // 2π for phase
                float twinkle = 0.5 + 0.5 * sin(phase * twinkleSpeed + twinklePhase);
                float totalBrightness = baseBrightness * twinkle;

                // Glow effect using Gaussian falloff
                float glow = exp(-d * d / sigma);
                totalColor += vec3(totalBrightness * glow);
            }
        }
    }

    // Output star color for additive blending
    //gl_FragColor = vec4(totalColor, 1.0);

    // adding stars
    finalColor += (totalColor * clamp(dt*2-1.0,0.0,1.0));



   FragColor = vec4(finalColor, 1.0f);
};
