"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CReadLookupList = void 0;
const ImpLib = require("@ot-builder/common-impl");
const errors_1 = require("@ot-builder/errors");
const ot_layout_1 = require("@ot-builder/ot-layout");
const general_1 = require("./general");
class CReadLookupList {
    readExtensionSubtables(subtableViews) {
        let extensionLookupType = undefined;
        const realSubtables = [];
        for (const vSubTable of subtableViews) {
            const format = vSubTable.uint16();
            errors_1.Assert.FormatSupported("ExtensionSubstFormat::format", format, 1);
            const type = vSubTable.uint16();
            if (extensionLookupType === undefined)
                extensionLookupType = type;
            errors_1.Assert.FormatSupported(`ExtensionSubstFormat::extensionLookupType`, type, extensionLookupType || 0);
            realSubtables.push(vSubTable.ptr32());
        }
        if (!realSubtables.length || extensionLookupType == null) {
            throw errors_1.Errors.Layout.EmptyExtensionLookup();
        }
        return { extensionLookupType, realSubtables };
    }
    applyGdefClassDefIgnores(ignores, flags, gdef) {
        if (gdef.glyphClassDef) {
            for (const [g, cls] of gdef.glyphClassDef) {
                if (flags & general_1.LookupFlag.IgnoreBaseGlyphs && cls === ot_layout_1.Gdef.GlyphClass.Base) {
                    ignores.add(g);
                }
                if (flags & general_1.LookupFlag.IgnoreMarks && cls === ot_layout_1.Gdef.GlyphClass.Mark) {
                    ignores.add(g);
                }
                if (flags & general_1.LookupFlag.IgnoreLigatures && cls === ot_layout_1.Gdef.GlyphClass.Ligature) {
                    ignores.add(g);
                }
            }
        }
    }
    applyGdefMarkAttachDefIgnores(ignores, flags, gdef) {
        if (gdef.glyphClassDef &&
            gdef.markAttachClassDef &&
            flags & general_1.LookupFlag.MarkAttachmentType) {
            const maCls = (flags & general_1.LookupFlag.MarkAttachmentType) >>> 8;
            for (const [g, cls] of gdef.glyphClassDef) {
                if (cls !== ot_layout_1.Gdef.GlyphClass.Mark)
                    continue;
                const k = gdef.markAttachClassDef.get(g) || 0;
                if (k !== maCls)
                    ignores.add(g);
            }
        }
    }
    applyGdefMarkGlyphSetIgnores(ignores, flags, markFilteringSet, gdef) {
        if (gdef.glyphClassDef &&
            gdef.markGlyphSets &&
            flags & general_1.LookupFlag.UseMarkFilteringSet &&
            markFilteringSet != null) {
            const mgs = gdef.markGlyphSets[markFilteringSet];
            if (!mgs)
                return;
            for (const [g, cls] of gdef.glyphClassDef) {
                if (cls !== ot_layout_1.Gdef.GlyphClass.Mark)
                    continue;
                if (!mgs.has(g))
                    ignores.add(g);
            }
        }
    }
    applyIgnoreSet(lookup, flags, markFilteringSet, gdef) {
        if (flags & general_1.LookupFlag.RightToLeft)
            lookup.rightToLeft = true;
        if (!gdef)
            return;
        const ignores = new Set();
        this.applyGdefClassDefIgnores(ignores, flags, gdef);
        this.applyGdefMarkAttachDefIgnores(ignores, flags, gdef);
        this.applyGdefMarkGlyphSetIgnores(ignores, flags, markFilteringSet, gdef);
        if (ignores.size)
            lookup.ignoreGlyphs = ignores;
    }
    read(view, lrf, lrc) {
        const lookupCount = view.uint16();
        const lookups = [];
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const readers = [];
        const subtables = [];
        for (let lid = 0; lid < lookupCount; lid++) {
            const vLookup = view.ptr16();
            let lookupType = vLookup.uint16();
            const lookupFlag = vLookup.uint16();
            const subtableCount = vLookup.uint16();
            let subtableViews = [];
            for (let stid = 0; stid < subtableCount; stid++) {
                subtableViews.push(vLookup.ptr16());
            }
            const markFilteringSet = lookupFlag & general_1.LookupFlag.UseMarkFilteringSet ? vLookup.uint16() : undefined;
            // Override data if the lookup is extension
            if (lrf.isExtendedFormat(lookupType)) {
                const r = this.readExtensionSubtables(subtableViews);
                lookupType = r.extensionLookupType;
                subtableViews = r.realSubtables;
            }
            const reader = lrf.createReader(lookupType);
            const lookup = reader.createLookup();
            readers.push(reader);
            lookups.push(lookup);
            subtables.push(subtableViews);
            this.applyIgnoreSet(lookup, lookupFlag, markFilteringSet, lrc.gdef);
        }
        const lookupOrder = ImpLib.Order.fromList(`Lookups`, lookups);
        for (const [lookup, reader, sts] of ImpLib.Iterators.Zip3WithIndex(lookups, readers, subtables)) {
            for (const st of sts) {
                reader.parseSubtable(st, lookup, {
                    ivs: lrc.ivs,
                    gOrd: lrc.gOrd,
                    crossReferences: lookupOrder
                });
            }
        }
        return lookups;
    }
}
exports.CReadLookupList = CReadLookupList;
//# sourceMappingURL=read-lookup-list.js.map