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

out vec4 FragColor;

in vec3 FragPos;
in vec3 ourNormal;
in vec2 TexCoord;
in float time;
in float height;

//uniform sampler2D texture1;
uniform vec3 sunPos;
uniform vec3 moonPos;

// Sine-based noise function for wave generation
float sineFunction(vec2 uv) {
    // Adjusting the frequency based on distance from origin
    //float frequency = smoothstep(0.1, 1000.0) * 10.0;
    float frequency = smoothstep(0.1, 1000.0, 0.2);
    //float frequency = 1.0;

    float x = sin(uv.y * frequency) + sin(uv.x * frequency);
    return (x / 2.0) - 0.5;
}

// Simple 2D noise function
float noise3(vec2 p) {
    // A basic pseudo-random function (not true Perlin noise, but sufficient for perturbation)
    return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
    //return sin(dot(p, vec2(25, 125))) * 5;
}

// Simple fractal noise with wrapping behavior
vec3 fractalNoise(vec2 uv) {
    vec3 result;

    // Generate a smooth sine wave that wraps around horizontally
    float x = sin(uv.y * 2.0 + time) * 0.5; // Frequency (25 is a good starting point)
    x += sin(((uv.x * 0.5) * 5.0 + time) * 0.3); // Add a sub-wave for more detail
    //float z = sin(uv.x * 2.0 + time) * 0.5; // Frequency (25 is a good starting point)
    //z += sin((uv.x * 5.0 + time) * 0.3); // Add a sub-wave for more detail
    
    // Create a smoother transition between waves
    x = x * 0.8 + 0.4; // Offset to prevent sharp peaks
    //z = z * 0.8 + 0.4; // Offset to prevent sharp peaks
    
    // Apply the noise pattern to UV coordinates
    result.x = x;
    result.y = uv.y;
    //result.z = (x > 0.5) ? sqrt(x - 0.5) : 0; // Create a dynamic depth effect that fades out
    result.z = x;
    
    return result;
}


void main() {
    vec3 resultColor = vec3(1.0, 1.0, 1.0);
    
    // Calculate UV coordinates based on position
    //vec2 uv = TexCoord.xy / (1000.0 * min(1.0, 1.0)); // max w/h view
    vec2 uv = TexCoord.xy * 25.0; // max w/h view
    //vec2 uv = ourNormal.xy / (1000.0 * min(1.0, 1.0)); // max w/h view
    //vec2 uv = FragPos.xy / (1000.0 * min(1.0, 1.0)); // max w/h view

    //float time = data.x;
    float speed = 1.0-sin(uv.y*.01);
    float noiseStrength = 1.0;
    float rippleStrength = 1.0;
   
    // Generate water waves using noise functions
    //float noise2 = sineFunction(uv) * noiseStrength;
    float noise2=1.0;
    //float noise2=sin(uv.x);
    //float noise2=sin(uv.x) * cos(fract(uv.y));
    //float noise2=sin(time);

    vec3 basePlaneTexture = vec3(0.5,0.0,0.0);
    vec3 waveTexture = vec3(0.8, 0.3, 0.0);
    //vec3 finalPassTexture = vec3(1.0,0.0,0.0);

    
    // Combine base plane with vertex-generated waves and ripples
    resultColor = mix(basePlaneTexture, waveTexture, sin(uv.y));
    
    //// Apply post-processing effects for smooth transitions
    //resultColor = blendColors(resultColor, finalPassTexture);
	
	// Cross-like wave patterns with different frequencies and amplitudes
	//float waveX = sin(FragPos.x * time * speed) * 0.3;
	//float waveY = sin(FragPos.y * time * speed) * 0.5 + sin(FragPos.x * (time * speed) * 0.8) * 0.3;
	//float waveX = sin(uv.x * time * speed) * 0.3;
	//float waveY = sin(uv.y * time * speed) * 0.5 + sin(uv.x * (time * speed) * 0.8) * 0.3;

	// Adding random variations to create natural imperfections
	//float randomValue = noise3(FragPos.yz) * 0.2;
	//float randomValue = noise3(uv) * 0.2;
	//waveY += randomValue;

	// Smooth transition to reduce wave strength with distance from origin
	//float waveStrength = smoothstep(0.1, 10.0, length(FragPos)) * 0.5;
	//float waveStrength = smoothstep(0.1, 10.0, length(uv)) * 0.5;
	//waveX *= waveStrength;
	//waveY *= waveStrength;
    //float rippleEffect = sin(time + uv.x * speed) * rippleStrength * height;
    //resultColor += rippleEffect * 0.5;
	
	vec3 noise = fractalNoise(uv);
	
	// Apply the noise to create a dynamic, looping pattern
    float timeMultiplier = 1.0 + sin(time * .4); // Create a slow animation of the noise pattern
    
    vec3 finalColor = vec3(
        (noise.x * 0.7) * timeMultiplier,
        (noise.z * 0.3) * (timeMultiplier),
        0.0
    );
    //resultColor += noise * 0.5;
    resultColor += finalColor;

	// Combining and scaling the waves for final color
	//resultColor += vec3(waveX + waveY) * 0.4 + vec3(0.5, 0.5, 0.5);
    //resultColor = vec3(0.0, noise3(FragPos.xz), 0.0);
    //resultColor = vec3(0.0, noise3(uv), 0.0);

    //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;


    vec3 normal = normalize(ourNormal);
    //vec3 light = normalize(lightDir);
    //float diff = max(dot(normal, sunDir), 0.0);
    //vec3 color = vec3(0.0, 0.5, 1.0) * (0.3 + 0.7 * diff); // Blue water with diffuse lighting
    FragColor = vec4(resultColor, 1.0);
	
    
    //FragColor = vec4(resultColor, 1.0);
    //FragColor = vec4(ourNormal, 1.0);
    //FragColor = vec4(0.0, noise, 0.0, 1.0);
    //FragColor = vec4(TexCoord, 0.0, 1.0);
    //FragColor = vec4(1.0,0.0,0.4, 1.0);



    //--float ambientStrength = 0.5f;
    //--vec3 sunColor = vec3(1.0f, 0.93f, 0.74f); // luminate color
    //--vec3 moonColor = vec3(0.38f, 0.5f, 0.5f); // _sky and _moon
    //--//vec3 objColor = vec3(0.2f, 0.9f, 0.1f); // for sphere color
    //--vec3 norm=normalize(ourNormal);

    //--float sunY=sunPos.y*0.01; // 1000th = normalized?~
    //--float sunStrength=clamp(sunY,0.0,2.5); // sun brightness
    //--float moonStrength=clamp(1.5-sunStrength,0.0,0.5);
    //--vec3 blendColor = mix(sunColor,moonColor,0.0-sunStrength); // tone?
    //--vec3 ambient = ambientStrength * blendColor;
    //--vec3 result=(ambient + ((diffuse + diffuse2) * 0.5)) * resultColor;
    //--FragColor = vec4(result, 1.0f);
}
