"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.traceGsub = traceGsub;
exports.traceGpos = traceGpos;
const tslib_1 = require("tslib");
const Ot = tslib_1.__importStar(require("@ot-builder/ot"));
const TraceImpl_Glyph = tslib_1.__importStar(require("./trace-impl/glyph"));
function traceGsub(table) {
    const alg = new ItTraceGlyph();
    return TraceImpl_Glyph.Seq(table.lookups.map(lookup => alg.process(lookup)));
}
function traceGpos(table) {
    const alg = new ItTraceGlyph();
    return TraceImpl_Glyph.Seq(table.lookups.map(lookup => alg.process(lookup)));
}
class ItTraceGlyph {
    process(lookup) {
        switch (lookup.type) {
            case Ot.Gsub.LookupType.Single:
                return this.gsubSingle(lookup);
            case Ot.Gsub.LookupType.Multi:
            case Ot.Gsub.LookupType.Alternate:
                return this.gsubMulti(lookup);
            case Ot.Gsub.LookupType.Ligature:
                return this.gsubLigature(lookup);
            case Ot.Gsub.LookupType.Reverse:
                return this.gsubReverse(lookup);
            default:
                return tracer => { };
        }
    }
    gsubSingle(props) {
        return tracer => {
            for (const [src, dst] of props.mapping) {
                if (tracer.has(src) && !tracer.has(dst))
                    tracer.add(dst);
            }
        };
    }
    gsubMulti(props) {
        return tracer => {
            for (const [src, dst] of props.mapping.entries()) {
                if (tracer.has(src))
                    for (const g of dst)
                        if (!tracer.has(g))
                            tracer.add(g);
            }
        };
    }
    gsubLigature(props) {
        return tracer => {
            for (const { from, to } of props.mapping) {
                let found = true;
                for (const part of from)
                    if (!tracer.has(part))
                        found = false;
                if (found && !tracer.has(to))
                    tracer.add(to);
            }
        };
    }
    gsubReverse(props) {
        return tracer => {
            for (const rule of props.rules) {
                for (const [src, dst] of rule.replacement) {
                    if (tracer.has(src) && !tracer.has(dst))
                        tracer.add(dst);
                }
            }
        };
    }
}
//# sourceMappingURL=gsub-gpos.js.map