// Organic family: an abstract plant — a plume of swaying stalks with teardrop
// leaves and a glowing bloom at each crown.
//
// Abstract on purpose: no soil, no foreground, just the silhouette of growth.
// Every petal and the crown are stamped in the track's signature form, so a
// hexagonal track grows hexagonal flora. The stalk bends on bass and the bloom
// pulses on the beat — the plant dances to the track rather than the camera
// shaking.

export const flora = {
    name: 'Flora',
    family: 'organic',
    kind: 'fragment',
    // Personality: see look/Personality.js.
    traits: ['shape', 'camera', 'style'],

    params: {
        count:   { type: 'float', range: [1, 5],    default: 3,   uniform: 'u_count', bias: 'density' },
        height:  { type: 'float', range: [0.6, 2.0], default: 1.1, uniform: 'u_height', bias: 'energy' },
        stem:    { type: 'float', range: [0.008, 0.05], default: 0.02, uniform: 'u_stem' },
        sway:    { type: 'float', range: [0.05, 0.5], default: 0.2,   uniform: 'u_sway', bias: 'motion' },
        swayRate:{ type: 'float', range: [0.1, 1.2], default: 0.6,  uniform: 'u_swayRate', rate: true },
        leaf:    { type: 'float', range: [0.12, 0.5], default: 0.26, uniform: 'u_leaf' },
        bud:     { type: 'float', range: [0, 1],     default: 0.55, uniform: 'u_bud', bias: 'energy' },
        palette: { type: 'palette', count: 4 },
    },

    reactive: {
        sway: { feature: 'bandLow', amount: 0.25, response: 'smooth' },
        bud:  { feature: 'beat',    amount: 0.3,  response: 'smooth' },
    },

    shader: `
// Horizontal lean of a spine at parametric height h (0 base .. 1 tip), seeded
// per plant and swaying more toward the crown like a real stem. Returns a value
// scaled by u_sway later, so the reactive bend applies to every part at once.
float swayAt(float h, float phase, float t) {
    return sin(t * (0.35 + fract(phase * 1.7)) + phase)
         + h * sin(t * (0.35 + fract(phase * 0.6)) + phase * 2.1);
}

// A petal: an elongated blossom drawn in the track's signature form, growing
// forward along dir from a node and clipped to a blade shape.
float petal(vec2 p, vec2 node, vec2 dir, float len, float width) {
    vec2 off = p - node;
    float along = dot(off, dir);
    vec2 perp = vec2(-dir.y, dir.x);
    float across = dot(off, perp);
    float taper = 0.6 + 0.4 * sat(along / max(len, 1e-3));
    vec2 q = vec2(along / max(len, 1e-3), across / max(width * taper, 1e-3));
    float form = sigForm(q * 0.5, vec2(0.0), 0.5);
    float clip = smoothstep(0.0, -0.1, along) * smoothstep(len + 0.12, len * 0.72, along);
    return form * clip;
}

vec4 scene(vec2 uv, vec2 p) {
    float t = u_time * u_swayRate + u_seed;
    float beat = u_beat;
    p = sigCamera(p);

    // Soft vertical wash behind the plants.
    vec3 col = mix(pal(0) * 0.03, pal(1) * 0.06, sat((p.y + 1.0) * 0.5));

    for (int i = 0; i < 5; i++) {
        if (i >= int(u_count)) break;
        float fi = float(i);
        float s = u_seed + fi * 43.7;
        float baseX = (hash11(s * 1.7) - 0.5) * 1.25;
        float height = u_height * (0.55 + 0.45 * hash11(s * 3.1));
        float baseY = -0.92;

        // Stem, sampled so the bend follows the sway curve rather than a chord.
        float stemMask = 0.0;
        for (int j = 0; j < 12; j++) {
            float hj = (float(j) + 0.5) / 12.0;
            float cx = baseX + swayAt(hj, s, t) * u_sway;
            float cy = baseY + hj * height;
            float d = length(p - vec2(cx, cy));
            float taper = max(u_stem * (1.0 - hj * 0.8) + 0.002, 0.003);
            stemMask = max(stemMask, smoothstep(taper + 0.004, taper - 0.004, d));
        }
        col = mix(col, mix(pal(1), pal(3), 0.3), stemMask);

        // Stalk tip, reused for the petal rows and the bloom.
        float tipX = baseX + swayAt(1.0, s, t) * u_sway;
        float tipY = baseY + height;

        // Petals up the upper half, alternating sides.
        for (int l = 0; l < 6; l++) {
            float fll = float(l);
            float node = 0.45 + floor(fll * 0.5) * 0.12;
            float side = fract(fll * 0.5) < 0.5 ? -1.0 : 1.0;
            float nx = baseX + swayAt(node, s, t) * u_sway;
            float ny = baseY + node * height;
            vec2 dir = normalize(vec2(side, 0.55));
            float len = u_leaf * 2.0;
            float m = petal(p, vec2(nx, ny), dir, len, u_leaf);
            vec3 leafCol = mix(pal(2), pal(3), fract(s * 0.4));
            col = mix(col, leafCol, m);
            col += pal(3) * m * (0.2 + 0.3 * beat);
        }

        // Bloom: a small corona of signature forms around the crown.
        float bloom = 0.0;
        for (int k = 0; k < 6; k++) {
            float a = 6.2831853 * (float(k) + 0.5) / 6.0 + s;
            vec2 off = vec2(cos(a), sin(a)) * u_leaf * (0.30 + 0.2 * beat);
            bloom += sigForm(p - vec2(tipX, tipY), off, u_leaf * 0.5);
        }
        col = mix(col, pal(2), sat(bloom) * u_bud * (0.6 + 0.4 * beat));
    }

    col += sigGrain(uv);
    return vec4(col, 1.0);
}
`,
};

export default flora;