// Flow family: streaks advected along a curl-noise field.
//
// Uses the compositor's feedback texture rather than integrating positions, so
// the trails cost nothing in state and a seek still lands correctly once the
// feedback buffer has converged.

export const curlFlow = {
    name: 'Curl Flow',
    family: 'flow',
    kind: 'fragment',
    // Personality: see look/Personality.js.
    traits: ['camera', 'space', 'style'],

    params: {
        scale:    { type: 'float', range: [0.5, 6],   default: 2.0, uniform: 'u_scale', bias: 'density' },
        speed:    { type: 'float', range: [0.02, 0.5], default: 0.12, uniform: 'u_speed', bias: 'motion', rate: true },
        streak:   { type: 'float', range: [0, 1],     default: 0.55, uniform: 'u_streak' },
        contrast: { type: 'float', range: [0.5, 4],   default: 1.6, uniform: 'u_contrast' },
        veins:    { type: 'float', range: [1, 12],    default: 5.0, uniform: 'u_veins', bias: 'density' },
        glow:     { type: 'float', range: [0, 1.2],   default: 0.35, uniform: 'u_glow', bias: 'energy' },
        palette:  { type: 'palette', count: 5 },
    },

    reactive: {
        glow:   { feature: 'beat',    amount: 0.3, response: 'spike' },
        veins:  { feature: 'bandMid', amount: 0.25 },
        streak: { feature: 'flux',    amount: 0.2, response: 'smooth' },
    },

    shader: `
vec4 scene(vec2 uv, vec2 p) {
    float t = u_time * u_speed + u_seed;
    p = sigCamera(p);

    vec2 flow = curl(p * u_scale + vec2(t, -t * 0.7), t * 0.5);
    vec2 q = p + flow * 0.35;

    // Ridged noise gives filament-like veins rather than soft cloud.
    float n = fbm(q * u_scale * 1.4 + t * 0.6, 5);
    float veins = 1.0 - abs(sin(n * u_veins + t * 2.0));
    veins = pow(sat(veins), u_contrast);

    vec3 col = mix(pal(0) * 0.12, pal(1), veins);
    col += pal(2) * pow(veins, 3.0) * u_glow;
    col = mix(col, pal(3), sat(length(flow) * 0.4) * 0.35);

    // Feedback trails: the previous frame, pulled slightly along the flow.
    vec3 trail = prev(uv - flow * 0.004);
    col = max(col, trail * u_streak);

    col *= 0.6 + 0.4 * exp(-dot(p, p) * 0.35);
    col = sigAir(col, p, smoothstep(0.0, 1.7, length(p)));
    col += sigGrain(uv);
    return vec4(col, 1.0);
}
`,
};

export default curlFlow;
