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

out vec4 FragColor;

uniform vec3 data;  // data.x time, data.y freq, data.z amp
uniform vec3 sunPos;
uniform vec3 moonPos;
uniform float daytime;  // -1-0-1

in vec3 ourNormal;
in vec2 uv;     // UV coordinates from the vertex shader
in vec3 FragPos;
in float ypos;

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

// 2D value noise with smooth interpolation
float noise(vec2 p) {
    vec2 i = floor(p);          // Integer part
    vec2 f = fract(p);          // Fractional part
    float a = hash(i);
    float b = hash(i + vec2(1.0, 0.0));
    float c = hash(i + vec2(0.0, 1.0));
    float d = hash(i + vec2(1.0, 1.0));
    vec2 u = f * f * (3.0 - 2.0 * f); // Cubic interpolation
    return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}

// Fractal Brownian motion for detailed cloud patterns
float fbm(vec2 p) {
    float value = 0.0;
    //float amplitude = 0.5;
    float frequency = 0.222;
    float amplitude = data.z;
    //float frequency = data.y;
    for (int i = 0; i < 4; i++) { // 4 octaves for detail
        value += amplitude * noise(p * frequency);
        frequency *= 2.0;         // Double frequency each octave
        amplitude *= 0.5;         // Halve amplitude each octave
    }
    return value;
}

// clouds by grok
void main() {
    //float time = data.x;
    float rad=PI/180.0;
    //float time=(data.x * 1.0 / 86400) * 25000; // 50 breaks
    float phase = data.x;



    float twinkleSpeed = 86400.0 / 3;
   //-- float twinkle = sin(uTime * twinkleSpeed);

    //float time = sin(phase * twinkleSpeed);

    float time = phase / (2.0 * 3.14159) * twinkleSpeed;
    ///vec2 flame_uv = uv + vec2(0.0, offset_y);







    float speed = 0.1;        // Speed of cloud movement
    float cloudScale = 100.0;   // Scale of cloud patterns
    // Circular offset for looping animation
    //vec2 offset = vec2(sin(time * speed), cos(time * speed)) * 0.5;
    vec2 offset = vec2(sin(time), cos(time)) * 0.5;


    
    // Scale UV coordinates and apply offset
    vec2 scaledUV = uv * cloudScale;
    scaledUV.x*=2; //
    float cloudValue = fbm(scaledUV + offset);
    
    // Map noise to alpha for cloud density with soft edges
    float alpha = smoothstep(0.0, 0.7, cloudValue);
    //float alpha=0.5;
    // Purplish cloud color (stylized)
    //vec3 cloudColor = vec3(0.6, 0.6, 0.66) * (1.0 - daytime);



    // color blendings
    float methodA=abs(daytime);
    float methodD=(methodA*2);
    float methodE=(methodA*2)-1;

    // day/night cloud colors  blend
    vec3 color1 = vec3(0.5,0.3,0.5); // day end
    vec3 color2 = vec3(0.6,0.6,0.7);
    vec3 color3 = vec3(0.7,0.6,0.7); // <<day begin
    //
    vec3 color4 = vec3(0.63,0.43,0.43); // night end
    vec3 color5 = vec3(0.43,0.36,0.43);
    vec3 color6 = vec3(0.15,0.16,0.43); // night begin

    // hard color test
  //  vec3 color1 = vec3(1.0,0.0,0.0); // day end 3
  //  vec3 color2 = vec3(0.0,1.0,0.0); // mid day 2
  //  vec3 color3 = vec3(0.0,0.0,1.0); // day begin 1
  //  //
  //  vec3 color4 = vec3(0.5,0.0,0.0); // night end 6
  //  vec3 color5 = vec3(0.0,0.5,0.0); // mid night 5
  //  vec3 color6 = vec3(0.0,0.0,0.5); // night begin 4
 
    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 cloudColor = vec3(mix(ourColor,ourColor2,abs(daytime)));


   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=10.0f;
   float moonStrength=3.0f;
   vec3 sunDir=normalize(FragPos - sunPos);
    sunDir.yx = sunDir.xy;
   float diff=max(dot(norm, sunDir), 0.0);
   vec3 diffuse=diff*sunColor*sunStrength;
   vec3 moonDir=normalize(FragPos - moonPos);
    moonDir.yx = moonDir.xy;
   float diff2=max(dot(norm, moonDir), 0.0);
   vec3 diffuse2=diff2*moonColor*moonStrength;

  
   //methodA=ypos;
   //float methodB=(ypos*0.5f)+0.5f;
   //float methodC=1.0f-abs(ypos);
   //methodD=(methodA*2);
   //methodE=(methodA*2)-1;
   //
   //
   vec3 finalColor = (cloudColor + ((diffuse + diffuse2) * 0.1)) * cloudColor;


    
    // Output color with transparency
    //FragColor = vec4(cloudColor, alpha);
    FragColor = vec4(finalColor, alpha);
    //FragColor = vec4(1.0,0.0,0.0,1.0);
}
