"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FvarIo = void 0;
const bin_util_1 = require("@ot-builder/bin-util");
const errors_1 = require("@ot-builder/errors");
const ot_metadata_1 = require("@ot-builder/ot-metadata");
const primitive_1 = require("@ot-builder/primitive");
const variance_1 = require("@ot-builder/variance");
const AxisRecord = {
    size: 20,
    ...(0, bin_util_1.Read)((view, index, ctx) => {
        const axisTag = view.next(primitive_1.Tag);
        const minValue = view.next(primitive_1.F16D16);
        const defaultValue = view.next(primitive_1.F16D16);
        const maxValue = view.next(primitive_1.F16D16);
        const flags = view.uint16();
        const axisNameID = view.uint16();
        const rawAxis = new ot_metadata_1.Fvar.Axis(new variance_1.OtVar.Dim(axisTag, minValue, defaultValue, maxValue), flags, axisNameID);
        if (ctx && ctx.mapAxis) {
            return ctx.mapAxis(rawAxis, index);
        }
        else {
            return rawAxis;
        }
    }),
    ...(0, bin_util_1.Write)((frag, axis) => {
        frag.push(primitive_1.Tag, axis.dim.tag);
        frag.push(primitive_1.F16D16, axis.dim.min);
        frag.push(primitive_1.F16D16, axis.dim.default);
        frag.push(primitive_1.F16D16, axis.dim.max);
        frag.uint16(axis.flags);
        frag.uint16(axis.axisNameID);
    })
};
const InstanceRecord = {
    size(axesCount, hasPostNameID) {
        return axesCount * primitive_1.F16D16.size + primitive_1.UInt16.size * 2 + (hasPostNameID ? primitive_1.UInt16.size : 0);
    },
    ...(0, bin_util_1.Read)((view, axes, hasPostNameID) => {
        const subfamilyNameID = view.uint16();
        const flags = view.uint16();
        const coordinates = new Map();
        for (const [p, index] of view.repeat(axes.length)) {
            coordinates.set(axes[index].dim, view.next(primitive_1.F16D16));
        }
        const postScriptNameID = hasPostNameID ? view.uint16() : undefined;
        return new ot_metadata_1.Fvar.Instance(subfamilyNameID, flags, coordinates, postScriptNameID);
    }),
    ...(0, bin_util_1.Write)((frag, inst, axes, hasPostNameID) => {
        frag.uint16(inst.subfamilyNameID);
        frag.uint16(inst.flags);
        for (const axis of axes) {
            frag.push(primitive_1.F16D16, inst.coordinates ? inst.coordinates.get(axis.dim) || 0 : 0);
        }
        if (hasPostNameID)
            frag.uint16(inst.postScriptNameID || 0);
    })
};
exports.FvarIo = {
    ...(0, bin_util_1.Read)((view, context) => {
        const majorVersion = view.uint16();
        const minorVersion = view.uint16();
        errors_1.Assert.SubVersionSupported("fvar::minorVersion", majorVersion, minorVersion, [1, 0]);
        const vwAxesArray = view.ptr16();
        const reserved1 = view.uint16();
        const axisCount = view.uint16();
        const axisSize = view.uint16();
        const instanceCount = view.uint16();
        const instanceSize = view.uint16();
        errors_1.Assert.SizeMatch("fvar::axisSize", axisSize, AxisRecord.size);
        errors_1.Assert.SizeMatch("fvar::instanceSize", instanceSize, InstanceRecord.size(axisCount, false), InstanceRecord.size(axisCount, true));
        const fvar = new ot_metadata_1.Fvar.Table();
        const hasPostNameID = instanceSize === InstanceRecord.size(axisCount, true);
        for (const [vw, index] of vwAxesArray.repeat(axisCount)) {
            fvar.axes[index] = vw.next(AxisRecord, index, context);
        }
        for (const [vw, index] of vwAxesArray.repeat(instanceCount)) {
            fvar.instances[index] = vw.next(InstanceRecord, fvar.axes, hasPostNameID);
        }
        return fvar;
    }),
    ...(0, bin_util_1.Write)((frag, fvar) => {
        frag.uint16(1).uint16(0);
        const frAxesArray = frag.ptr16New();
        frag.uint16(2); // Reserved 2
        errors_1.Assert.NoGap(`fvar::axes`, fvar.axes);
        errors_1.Assert.NoGap(`fvar::instances`, fvar.instances);
        let fHasPostScriptName = false;
        let fDoesNotHavePostScriptName = false;
        for (const instance of fvar.instances) {
            if (instance.postScriptNameID)
                fHasPostScriptName = true;
            else
                fDoesNotHavePostScriptName = true;
        }
        if (fHasPostScriptName && fDoesNotHavePostScriptName) {
            throw errors_1.Errors.Fvar.MixedPostScriptNamePresence();
        }
        frag.uint16(fvar.axes.length);
        frag.uint16(AxisRecord.size);
        frag.uint16(fvar.instances.length);
        frag.uint16(InstanceRecord.size(fvar.axes.length, fHasPostScriptName));
        for (const axis of fvar.axes) {
            frAxesArray.push(AxisRecord, axis);
        }
        for (const inst of fvar.instances) {
            frAxesArray.push(InstanceRecord, inst, fvar.axes, fHasPostScriptName);
        }
    })
};
//# sourceMappingURL=index.js.map