// eslint-disable-next-line @typescript-eslint/no-namespace
export var Dimension;
(function (Dimension) {
    let enableCaching = false;
    let cache;
    Dimension.configure = {
        enableCaching: (c) => {
            enableCaching = true;
            cache = c;
        }
    };
    function build(valueOrDimension, mode_) {
        const [value, mode] = typeof valueOrDimension === 'number' ? [valueOrDimension, mode_] : [valueOrDimension.value, valueOrDimension.mode];
        if (!enableCaching) {
            return { value, mode };
        }
        const key = `${value}-${mode}`;
        let dimension = cache.get(key);
        if (!dimension) {
            dimension = Object.freeze({ value, mode });
            cache.set(key, dimension);
        }
        return dimension;
    }
    Dimension.build = build;
    Dimension.gridUnit = (value) => build(value, 'gridUnit');
    Dimension.fitContent = (value) => build(value, 'fitContent');
    Dimension.fillParent = (value) => build(value, 'fillParent');
    Dimension.px = (value) => build(value, 'px');
    Dimension.percent = (value) => build(value, '%');
    // note: return.value is represented in px if any of the inputs are in px
    const mixedOperationHelper = (d, d2, parentSpace = 12, op) => {
        const d1Px = d.mode === 'px' ? d.value : Dimension.toPx(d, parentSpace).value;
        const d2Px = d2.mode === 'px' ? d2.value : Dimension.toPx(d2, parentSpace).value;
        const valuePx = op(d1Px, d2Px);
        const valueGU = valuePx / parentSpace;
        return {
            asFirst: () => build(d.mode === 'px' ? valuePx : valueGU, d.mode),
            asSecond: () => build(d2.mode === 'px' ? valuePx : valueGU, d2.mode),
            as: (mode) => build(mode === 'px' ? valuePx : valueGU, mode),
            value: d.mode === 'px' || d2.mode === 'px' ? valuePx : valueGU
        };
    };
    function add(d, d2, parentSpace) {
        return mixedOperationHelper(d, d2, parentSpace, (a, b) => a + b);
    }
    Dimension.add = add;
    function minus(d, d2, parentSpace) {
        return mixedOperationHelper(d, d2, parentSpace, (a, b) => a - b);
    }
    Dimension.minus = minus;
    function min(d, d2, parentSpace) {
        return mixedOperationHelper(d, d2, parentSpace, (a, b) => Math.min(a, b));
    }
    Dimension.min = min;
    function max(d, d2, parentSpace) {
        return mixedOperationHelper(d, d2, parentSpace, (a, b) => Math.max(a, b));
    }
    Dimension.max = max;
    Dimension.toPx = (d, parentSpace) => {
        if (d === undefined) {
            return d;
        }
        if (d.mode === 'px') {
            return d;
        }
        return build(d.value * parentSpace, 'px');
    };
    Dimension.toGridUnit = (d, parentSpace) => new GridUnitBuilder(d, parentSpace);
})(Dimension || (Dimension = {}));
class GridUnitBuilder {
    dimension;
    parentSpace;
    constructor(dimension, parentSpace) {
        this.dimension = { ...dimension };
        this.parentSpace = parentSpace;
    }
    roundDown() {
        if (this.dimension === undefined) {
            return this.dimension;
        }
        if (this.dimension.mode === 'gridUnit' || this.dimension.mode === 'fitContent' || this.dimension.mode === 'fillParent') {
            return this.dimension;
        }
        return Dimension.gridUnit(Math.floor(this.dimension.value / this.parentSpace));
    }
    roundUp() {
        if (this.dimension === undefined) {
            return this.dimension;
        }
        if (this.dimension.mode === 'gridUnit' || this.dimension.mode === 'fitContent' || this.dimension.mode === 'fillParent') {
            return this.dimension;
        }
        return Dimension.gridUnit(Math.ceil(this.dimension.value / this.parentSpace));
    }
    raw() {
        if (this.dimension === undefined) {
            return this.dimension;
        }
        if (this.dimension.mode === 'gridUnit' || this.dimension.mode === 'fitContent' || this.dimension.mode === 'fillParent') {
            return this.dimension;
        }
        return Dimension.gridUnit(this.dimension.value / this.parentSpace);
    }
}
//# sourceMappingURL=Dimension.js.map