"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PostAndNameIo = 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 mac_glyph_names_1 = require("./mac-glyph-names");
const coMacGlyphNames = (function () {
    const m = new Map();
    for (let nid = 0; nid < mac_glyph_names_1.default.length; nid++) {
        m.set(mac_glyph_names_1.default[nid], nid);
    }
    return m;
})();
class PostFormat1Names {
    getName(gid) {
        return mac_glyph_names_1.default[gid];
    }
}
class PostFormat2Names {
    constructor(mapping) {
        this.mapping = mapping;
    }
    getName(gid) {
        return this.mapping.get(gid) || "";
    }
}
const PascalString = {
    read(bp) {
        const pascalStringLength = bp.uint8();
        const buf = bp.bytes(pascalStringLength);
        return buf.toString("utf-8");
    },
    write(b, name) {
        const buf = Buffer.from(name, "utf-8");
        b.uint8(buf.length);
        b.bytes(buf);
    }
};
function nameGlyphPostVersion2(bp) {
    const numGlyphs = bp.uint16();
    const glyphNameIDList = [];
    const extraGlyphNameMap = new Map();
    let maxNewGlyphNameID = -1;
    for (let gid = 0; gid < numGlyphs; gid++) {
        glyphNameIDList[gid] = bp.uint16();
        if (glyphNameIDList[gid] >= mac_glyph_names_1.default.length) {
            const newGlyphID = glyphNameIDList[gid] - mac_glyph_names_1.default.length;
            if (newGlyphID > maxNewGlyphNameID)
                maxNewGlyphNameID = newGlyphID;
        }
    }
    if (maxNewGlyphNameID >= 0) {
        for (let id = 0; id <= maxNewGlyphNameID; id++) {
            const name = bp.next(PascalString);
            extraGlyphNameMap.set(id, name);
        }
    }
    const glyphNames = new Map();
    for (let gid = 0; gid < numGlyphs; gid++) {
        const nameID = glyphNameIDList[gid];
        if (nameID < mac_glyph_names_1.default.length) {
            glyphNames.set(gid, mac_glyph_names_1.default[nameID]);
        }
        else {
            const ngn = extraGlyphNameMap.get(nameID - mac_glyph_names_1.default.length);
            if (ngn)
                glyphNames.set(gid, ngn);
        }
    }
    return new PostFormat2Names(glyphNames);
}
exports.PostAndNameIo = {
    read(view) {
        const majorVersion = view.uint16();
        const minorVersion = view.uint16();
        const table = new ot_metadata_1.Post.Table(majorVersion, minorVersion);
        table.italicAngle = view.next(primitive_1.F16D16);
        table.underlinePosition = view.int16();
        table.underlineThickness = view.int16();
        table.isFixedPitch = !!view.uint32();
        table.minMemType42 = view.uint32();
        table.maxMemType42 = view.uint32();
        table.minMemType1 = view.uint32();
        table.maxMemType1 = view.uint32();
        let naming = null;
        if (table.majorVersion === 1 && table.minorVersion === 0) {
            naming = new PostFormat1Names();
        }
        else if (table.majorVersion === 2 && table.minorVersion === 0) {
            naming = nameGlyphPostVersion2(view);
        }
        return { post: table, naming };
    },
    write(frag, post, glyphCount, nameSource, keepMemorySettings) {
        frag.uint16(post.majorVersion);
        frag.uint16(post.minorVersion);
        frag.push(primitive_1.F16D16, post.italicAngle);
        frag.int16(variance_1.OtVar.Ops.originOf(post.underlinePosition));
        frag.int16(variance_1.OtVar.Ops.originOf(post.underlineThickness));
        frag.uint32(post.isFixedPitch ? 1 : 0);
        if (keepMemorySettings) {
            frag.uint32(post.minMemType42);
            frag.uint32(post.maxMemType42);
            frag.uint32(post.minMemType1);
            frag.uint32(post.maxMemType1);
        }
        else {
            frag.uint32(0);
            frag.uint32(0);
            frag.uint32(0);
            frag.uint32(0);
        }
        if (post.majorVersion === 2 && post.minorVersion === 0 && glyphCount && nameSource) {
            frag.push(PostVersion2NameList, glyphCount, nameSource);
        }
    }
};
const PostVersion2NameList = (0, bin_util_1.Write)((frag, glyphCount, nameSource) => {
    frag.uint16(glyphCount);
    // Collect "new" glyph names
    const glyphNameMap = new Map(coMacGlyphNames);
    const newGlyphNames = [];
    // glyphNameIndex
    for (let gid = 0; gid < glyphCount; gid++) {
        const glyphName = nameSource.getName(gid);
        if (!glyphName)
            throw errors_1.Errors.Post.MissingName(gid);
        let nid = glyphNameMap.get(glyphName);
        if (nid === undefined) {
            nid = glyphNameMap.size;
            glyphNameMap.set(glyphName, nid);
            if (nid >= mac_glyph_names_1.default.length) {
                newGlyphNames[nid - mac_glyph_names_1.default.length] = glyphName;
            }
        }
        frag.uint16(nid);
    }
    // names
    for (const name of newGlyphNames)
        frag.push(PascalString, name);
});
//# sourceMappingURL=index.js.map