// What a layer stack is made of, and how to ask it questions.
//
// A stack used to be "the scene, then whatever was composited over it", so
// `layers[0]` meant the section's scene everywhere in the program. It no longer
// does: every stack now starts with a GROUND — a filled canvas the shot happens
// on — and the scene the section is ABOUT sits above it.
//
// Everything that used to reach for `layers[0]` wants the subject, not the
// ground: the param panel edits it, the HUD names it, and the variety report
// counts it. Those all go through `subjectOf` now. Reading the ground as the
// section's scene would be actively wrong for the measurements — grounds come
// from a twenty-scene pool, so a report that counted them would show a library
// three times smaller than the one actually on screen.

import { coverageOf } from '../scenes/surface.js';

/** Layers carrying this role are the bed, not the shot. */
export const GROUND = 'ground';

export function isGround(layer) {
    return !!layer && layer.role === GROUND;
}

/** Index of the layer the section is about. */
export function subjectIndexOf(stack) {
    const at = stack.findIndex((l) => !isGround(l));
    return at < 0 ? 0 : at;
}

/** The layer the section is about — the shot, as opposed to what it stands on. */
export function subjectOf(stack) {
    return stack[subjectIndexOf(stack)];
}

/** The ground under a stack, or null if the subject is its own ground. */
export function groundOf(stack) {
    return stack.find(isGround) || null;
}

/** Everything above the subject: the passes composited over the shot. */
export function overlaysOf(stack) {
    return stack.slice(subjectIndexOf(stack) + 1);
}

/**
 * How much painted frame a stack adds up to, in units of one filled frame.
 *
 * Deliberately a SUM and not a union: two layers each painting 60% do not add
 * up to 120% of a screen, but they do add up to two things happening at once,
 * and that is the quantity the budget is about. 2.0 is the ceiling — see
 * MAX_COVERAGE in LookGenerator.
 */
export function stackCoverage(stack) {
    return stack.reduce((sum, l) => sum + coverageOf(l.module), 0);
}
