shader_type canvas_item;

uniform vec4 target_color : source_color = vec4(0.0, 0.0, 1.0, 1.0);
uniform float tolerance : hint_range(0.0, 1.0) = 0.1;
uniform vec4 water_deep_color : source_color = vec4(0.0, 0.4, 0.8, 1.0);
uniform vec4 foam_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);

vec2 random(vec2 uv) {
    return vec2(fract(sin(dot(uv.xy, vec2(12.9898,78.233))) * 43758.5453123));
}

float worley(vec2 uv, float columns, float rows) {
    vec2 index_uv = floor(vec2(uv.x * columns, uv.y * rows));
    vec2 fract_uv = fract(vec2(uv.x * columns, uv.y * rows));
    float minimum_dist = 1.0;  
    for (int y= -1; y <= 1; y++) {
        for (int x= -1; x <= 1; x++) {
            vec2 neighbor = vec2(float(x),float(y));
            vec2 point = random(index_uv + neighbor);
            vec2 diff = neighbor + point - fract_uv;
            float dist = length(diff);
            minimum_dist = min(minimum_dist, dist);
        }
    }
    return minimum_dist;
}

float noise(vec2 uv) {
    vec2 uv_index = floor(uv);
    vec2 uv_fract = fract(uv);
    vec2 blur = smoothstep(0.0, 1.0, uv_fract);
    return mix( mix( dot( random(uv_index + vec2(0.0,0.0) ), uv_fract - vec2(0.0,0.0) ),
                     dot( random(uv_index + vec2(1.0,0.0) ), uv_fract - vec2(1.0,0.0) ), blur.x),
                mix( dot( random(uv_index + vec2(0.0,1.0) ), uv_fract - vec2(0.0,1.0) ),
                     dot( random(uv_index + vec2(1.0,1.0) ), uv_fract - vec2(1.0,1.0) ), blur.x), blur.y) + 0.5;
}

varying vec2 world_pos;

void vertex() {
    world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0, 1.0)).xy;
}

void fragment() {
    vec4 tex_color = texture(TEXTURE, UV);
    
    float color_diff = distance(tex_color.rgb, target_color.rgb);
    
    if (color_diff < tolerance) {
        vec2 w_uv = world_pos * 0.01;
        float noise_value = noise(world_pos * 0.1 - TIME * 0.1) * 0.1;
        w_uv.x += noise_value;

        float worley_val = worley(w_uv + TIME * 0.1, 6.0, 10.0);

        vec4 final_water = mix(water_deep_color, foam_color, step(0.7, worley_val));
        
        COLOR = vec4(final_water.rgb, tex_color.a);
    } else {
        COLOR = tex_color;
    }
}