import { Arr, Optional } from '@ephox/katamari';
import * as PositionArray from '../alien/PositionArray';
const output = (within, extra, withinWidth) => ({
    within,
    extra,
    withinWidth
});
const apportion = (units, total, len) => {
    const parray = PositionArray.generate(units, (unit, current) => {
        const width = len(unit);
        return Optional.some({
            element: unit,
            start: current,
            finish: current + width,
            width
        });
    });
    const within = Arr.filter(parray, (unit) => unit.finish <= total);
    const withinWidth = Arr.foldr(within, (acc, el) => acc + el.width, 0);
    const extra = parray.slice(within.length);
    return {
        within,
        extra,
        withinWidth
    };
};
const toUnit = (parray) => Arr.map(parray, (unit) => unit.element);
const fitLast = (within, extra, withinWidth) => {
    const fits = toUnit(within.concat(extra));
    return output(fits, [], withinWidth);
};
const overflow = (within, extra, overflower, withinWidth) => {
    const fits = toUnit(within).concat([overflower]);
    return output(fits, toUnit(extra), withinWidth);
};
const fitAll = (within, extra, withinWidth) => output(toUnit(within), [], withinWidth);
const tryFit = (total, units, len) => {
    const divide = apportion(units, total, len);
    return divide.extra.length === 0 ? Optional.some(divide) : Optional.none();
};
const partition = (total, units, len, overflower) => {
    // Firstly, we try without the overflower.
    const divide = tryFit(total, units, len).getOrThunk(() => 
    // If that doesn't work, overflow
    apportion(units, total - len(overflower), len));
    const within = divide.within;
    const extra = divide.extra;
    const withinWidth = divide.withinWidth;
    if (extra.length === 1 && extra[0].width <= len(overflower)) {
        return fitLast(within, extra, withinWidth);
    }
    else if (extra.length >= 1) {
        return overflow(within, extra, overflower, withinWidth);
    }
    else {
        return fitAll(within, extra, withinWidth);
    }
};
export { partition };
//# sourceMappingURL=Overflows.js.map