// Ported from party-stage's "Synthwave Run".
//
// The original hardcoded magenta and cyan and drew a car silhouette with
// red taillights. The car is kept — it is the scene's whole identity — but the
// colours now come from the palette, and the elements (grid, mountains, sun,
// car) are individually switchable so the arc driver can strip it back to just
// the grid during a breakdown and bring the rest in for the drop.

export const synthwaveRun = {
    name: 'Synthwave Run',
    family: 'structural',
    kind: 'fragment',
    // Personality: see look/Personality.js.
    consumes: ['ink'],
    traits: ['space', 'camera', 'style'],

    params: {
        speed:      { type: 'float', range: [0.3, 4],   default: 1.5, uniform: 'u_speed', bias: 'motion', rate: true },
        gridDensity:{ type: 'float', range: [0.5, 3],   default: 1.0, uniform: 'u_gridDensity', bias: 'density' },
        horizon:    { type: 'float', range: [-0.3, 0.3],default: 0.0, uniform: 'u_horizon' },
        sun:        { type: 'float', range: [0, 1],     default: 1.0, uniform: 'u_sun' },
        mountains:  { type: 'float', range: [0, 1],     default: 1.0, uniform: 'u_mountains' },
        car:        { type: 'float', range: [0, 1],     default: 1.0, uniform: 'u_car' },
        palette:    { type: 'palette', count: 4 },
    },


    shader: `
vec4 scene(vec2 uv, vec2 p) {
    float t = u_time * u_speed + u_seed;
    float beat = u_beat;
    p = sigCamera(p);
    // Shares the track's ground line with every other scene that has one.
    float horizon = clamp(u_horizon + sigHorizonY() * 0.35, -0.85, 0.85);

    vec3 colorMain = pal(0);
    vec3 colorSec = pal(1);
    vec3 col = pal(3) * 0.08;

    // --- perspective ground grid ---
    if (p.y < horizon) {
        float perspective = 1.0 / (horizon - p.y + 0.05);
        vec2 g = vec2(p.x * perspective, perspective + t * 2.0) * u_gridDensity;
        float lines = smoothstep(0.05, 0.0, abs(fract(g.x + 0.5) - 0.5))
                    + smoothstep(0.05, 0.0, abs(fract(g.y + 0.5) - 0.5));
        col = mix(col, colorSec, lines * 0.5 * (0.5 + beat));
        if (abs(p.x * perspective) < 0.8) col += colorMain * 0.15 * perspective;
    }

    // --- wireframe mountains ---
    if (u_mountains > 0.01 && p.y > horizon - 0.1) {
        float mx = abs(p.x) - 0.5;
        if (mx > 0.0) {
            float h = vnoise(vec2(mx * 2.0 + t * 0.1, u_seed)) * 0.6 * smoothstep(0.0, 0.5, mx);
            if (p.y - horizon < h) {
                float edge = abs(p.y - horizon - h);
                float wire = smoothstep(0.02, 0.0, edge)
                           + smoothstep(0.01, 0.0, abs(fract((p.y - horizon) * 10.0) - 0.5))
                           + smoothstep(0.01, 0.0, abs(fract(mx * 10.0) - 0.5));
                col = mix(col, colorMain, wire * 0.4 * u_mountains);
            }
        }
    }

    // --- retro sun with scanline cutouts ---
    if (u_sun > 0.01) {
        vec2 sunPos = vec2(0.0, 0.1);
        float sunRad = 0.4;
        float dSun = length(p - sunPos);
        if (dSun < sunRad && p.y > horizon) {
            float scan = sin((p.y - t * 0.1) * 50.0);
            if (scan < mix(0.8, -1.0, (p.y - sunPos.y + sunRad) / (sunRad * 2.0))) {
                vec3 sunCol = mix(colorMain, pal(2), sat(p.y * 2.0));
                col = mix(col, sunCol, (0.8 + beat * 0.2) * u_sun);
            }
        }
    }

    // --- car silhouette ---
    if (u_car > 0.01) {
        vec2 carPos = vec2(sin(t * 0.1) * 0.2, -0.78 + sin(t * 30.0) * 0.001);
        vec2 cp = p - carPos;
        float cpX = abs(cp.x);

        float body = step(cpX, 0.35) * step(abs(cp.y), 0.12);
        float glass = step(cpX, 0.22) * step(abs(cp.y - 0.18), 0.07);
        float wingTop = step(cpX, 0.32) * step(abs(cp.y - 0.20), 0.025);
        float wingSide = step(abs(cpX - 0.30), 0.03) * step(abs(cp.y - 0.12), 0.1);

        if (body + glass + wingTop + wingSide > 0.0) {
            col = mix(col, vec3(0.015), 0.95 * u_car);
            float r = 0.025;
            float l1 = smoothstep(r, r * 0.6, length(vec2(cpX - 0.21, cp.y - 0.03)));
            float l2 = smoothstep(r, r * 0.6, length(vec2(cpX - 0.29, cp.y - 0.03)));
            col = mix(col, pal(2) * (0.6 + beat * 1.4), sat(l1 + l2) * u_car);
        }
    }

    // Horizon haze, scaled by the glow param.

    return vec4(inkValue(col), 1.0);
}
`,
};

export default synthwaveRun;
