"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StatWrite = void 0;
const bin_util_1 = require("@ot-builder/bin-util");
const ImpLib = require("@ot-builder/common-impl");
const errors_1 = require("@ot-builder/errors");
const ot_name_1 = require("@ot-builder/ot-name");
const primitive_1 = require("@ot-builder/primitive");
exports.StatWrite = (0, bin_util_1.Write)((frag, stat) => {
    const stValueRecordOffset = new ImpLib.State(0);
    const stNeedFormat12 = new ImpLib.State(false);
    const body = bin_util_1.Frag.from(StatTableBody, stat, stValueRecordOffset, stNeedFormat12);
    frag.uint16(1)
        .uint16(stNeedFormat12.get() ? 2 : 1)
        .uint16(primitive_1.Tag.size + primitive_1.UInt16.size * 2)
        .uint16(stat.designAxes.length)
        .ptr32(body)
        .uint16(stat.assignments.length)
        .ptr32(body, bin_util_1.FragPointerEmbedding.Relative, stValueRecordOffset.get())
        .uint16(stat.elidedFallbackNameID);
});
const StatTableBody = (0, bin_util_1.Write)((frag, stat, acValueRecordOffset, acNeedFormat12) => {
    const start = frag.size;
    frag.push(DesignAxisArray, stat.designAxes);
    acValueRecordOffset.set(frag.size - start);
    frag.embed(bin_util_1.Frag.from(AxisValueArray, stat.assignments, ImpLib.Order.fromList(`DesignAxes`, stat.designAxes), acNeedFormat12));
});
const DesignAxisArray = (0, bin_util_1.Write)((frag, axes) => {
    for (const axis of axes)
        frag.push(DesignAxisRecord, axis);
});
const DesignAxisRecord = (0, bin_util_1.Write)((frag, axis) => {
    frag.push(primitive_1.Tag, axis.tag).uint16(axis.axisNameID).uint16(axis.axisOrdering);
});
const AxisValueArray = (0, bin_util_1.Write)((frag, ava, axes, acNeedFormat12) => {
    for (const item of ava) {
        frag.ptr16New(bin_util_1.FragPointerEmbedding.EmbedRelative).push(AxisValue, item, axes, acNeedFormat12);
    }
});
const AxisValue = (0, bin_util_1.Write)((frag, [av, asg], axes, acNeedFormat12) => {
    if (av instanceof ot_name_1.Stat.AxisValue.Static) {
        frag.push(AxisValueFormat1, [av, asg], axes);
    }
    else if (av instanceof ot_name_1.Stat.AxisValue.Variable) {
        frag.push(AxisValueFormat2, [av, asg], axes);
    }
    else if (av instanceof ot_name_1.Stat.AxisValue.Linked) {
        frag.push(AxisValueFormat3, [av, asg], axes);
    }
    else if (av instanceof ot_name_1.Stat.AxisValue.PolyAxis) {
        acNeedFormat12.set(true);
        frag.push(AxisValueFormat4, [av, asg], axes);
    }
    else {
        throw errors_1.Errors.STAT.UnknownAxisValueFormat();
    }
});
const AxisValueFormat1 = (0, bin_util_1.Write)((frag, [av, asg], axes) => {
    frag.uint16(1)
        .uint16(axes.reverse(av.axis))
        .uint16(asg.flags)
        .uint16(asg.valueNameID)
        .push(primitive_1.F16D16, av.value);
});
const AxisValueFormat2 = (0, bin_util_1.Write)((frag, [av, asg], axes) => {
    frag.uint16(2)
        .uint16(axes.reverse(av.axis))
        .uint16(asg.flags)
        .uint16(asg.valueNameID)
        .push(primitive_1.F16D16, av.nominal)
        .push(primitive_1.F16D16, av.min)
        .push(primitive_1.F16D16, av.max);
});
const AxisValueFormat3 = (0, bin_util_1.Write)((frag, [av, asg], axes) => {
    frag.uint16(3)
        .uint16(axes.reverse(av.axis))
        .uint16(asg.flags)
        .uint16(asg.valueNameID)
        .push(primitive_1.F16D16, av.value)
        .push(primitive_1.F16D16, av.linkedValue);
});
const AxisValueFormat4 = (0, bin_util_1.Write)((frag, [av, asg], axes) => {
    frag.uint16(4).uint16(av.assignments.length).uint16(asg.flags).uint16(asg.valueNameID);
    for (const [axis, value] of av.assignments) {
        frag.uint16(axes.reverse(axis)).push(primitive_1.F16D16, value);
    }
});
//# sourceMappingURL=write.js.map