in vec2 texCoord;
out vec4 fragColor;
uniform sampler2D texture0;
uniform vec4 color;
uniform float time;
uniform float fireSpeed;        // Speed of upward movement
uniform float fireScale;        // Scale of the noise pattern
uniform float turbulence;       // Amount of horizontal turbulence
uniform float brightness;       // Overall brightness/intensity
uniform float contrast;         // Contrast adjustment
uniform float fadeTop;          // Where fire starts to fade (0-1)
uniform float fadeBottom;       // Where fire starts to appear (0-1)
uniform float fireIntensity;   // Intensity multiplier for the fire

// Simple hash function for noise
float hash(vec2 p) {
    return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
}

// 2D noise function
float noise(vec2 p) {
    vec2 i = floor(p);
    vec2 f = fract(p);
    f = f * f * (3.0 - 2.0 * f);
    
    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));
    
    return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
}

// Fractal noise
float fbm(vec2 p) {
    float value = 0.0;
    float amplitude = 0.5;
    float frequency = 1.0;
    
    for(int i = 0; i < 5; i++) {
        value += amplitude * noise(p * frequency);
        frequency *= 2.0;
        amplitude *= 0.5;
    }
    return value;
}

void main()
{
    vec2 coord = texCoord;
    
    // Create fire movement - scroll upward and add turbulence
    vec2 fireCoord = coord;
    fireCoord.y -= time * fireSpeed;
    fireCoord.x += sin(coord.y * 3.0 + time) * turbulence;
    
    // Generate noise pattern
    float n = fbm(fireCoord * fireScale);
    
    // Add more turbulence at the bottom
    n += (1.0 - coord.y) * 0.3;
    n *= fireIntensity;
    // Clamp noise to 0-1 range
    n = clamp(n, 0.0, 1.0);
    
    // Make fire fade at top and bottom
    float fadeMask = smoothstep(fadeBottom, fadeTop, coord.y);
    fadeMask *= smoothstep(1.0, fadeTop, coord.y);
    
    // Fire color gradient - predominantly red with orange and yellow accents (use raw noise for grading)
    vec3 fireColor;
    if(n < 0.15) {
        // Black to very dark red
        fireColor = mix(vec3(0.0), vec3(0.3, 0.0, 0.0), n / 0.15);
    } else if(n < 0.35) {
        // Dark red to medium red
        fireColor = mix(vec3(0.3, 0.0, 0.0), vec3(0.7, 0.0, 0.0), (n - 0.15) / 0.2);
    } else if(n < 0.55) {
        // Medium red to bright red
        fireColor = mix(vec3(0.7, 0.0, 0.0), vec3(1.0, 0.05, 0.0), (n - 0.35) / 0.2);
    } else if(n < 0.7) {
        // Bright red to red-orange
        fireColor = mix(vec3(1.0, 0.05, 0.0), vec3(1.0, 0.25, 0.0), (n - 0.55) / 0.15);
    } else if(n < 0.85) {
        // Red-orange to orange
        fireColor = mix(vec3(1.0, 0.25, 0.0), vec3(1.0, 0.5, 0.0), (n - 0.7) / 0.15);
    } else {
        // Orange to yellow (hottest parts)
        fireColor = mix(vec3(1.0, 0.5, 0.0), vec3(1.0, 0.9, 0.4), (n - 0.85) / 0.15);
    }
    
    // Apply brightness and contrast to final color (AFTER color grading)
    fireColor *= brightness * fadeMask;
    fireColor = pow(fireColor, vec3(contrast));
    
    fragColor = vec4(fireColor * color.rgb, n * fadeMask * color.a);
}
