"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FeatureConsolidator = void 0;
const zone_dicing_1 = require("./zone-dicing");
class FeatureConsolidator {
    constructor(env, tag, featureList) {
        this.env = env;
        this.tag = tag;
        this.featureList = featureList;
        this.result = { tag, lookups: [] };
        this.resultFeatureVariation = [];
        let hash = tag;
        for (const feature of featureList) {
            hash += "/" + this.env.getFeatureHash(feature);
        }
        this.hash = hash;
    }
    resolve() {
        const primeLookupSet = new Set();
        for (const feature of this.featureList) {
            for (const lookup of feature.lookups)
                primeLookupSet.add(lookup);
        }
        this.result.lookups = Array.from(primeLookupSet);
        if (this.env.variationDimensions.length)
            this.resolveFeatureVariations();
    }
    resolveFeatureVariations() {
        const fvs = this.env.getFeatureVariations();
        const srcZones = [];
        for (const fv of fvs) {
            for (const feature of this.featureList) {
                const substituted = fv.substitutions.get(feature);
                if (substituted)
                    srcZones.push([this.conditionToZone(fv.conditions), [feature, substituted]]);
            }
        }
        if (!srcZones.length)
            return;
        for (const [zone, tfm] of (0, zone_dicing_1.diceZones)(this.env.variationDimensions.length, srcZones)) {
            const hash = (0, zone_dicing_1.hashZone)(zone);
            let fv = this.env.featureVariationCollection.get(hash);
            if (!fv) {
                fv = { conditions: this.zoneToConditions(zone), substitutions: new Map() };
                this.env.featureVariationCollection.set(hash, fv);
            }
            const lookupSet = new Set();
            for (const feature of this.featureList) {
                let f = feature;
                for (const t of tfm)
                    if (f === t[0])
                        f = t[1];
                for (const lookup of f.lookups)
                    lookupSet.add(lookup);
            }
            fv.substitutions.set(this.result, { tag: this.tag, lookups: Array.from(lookupSet) });
        }
    }
    conditionToZone(fvc) {
        const zone = [];
        for (let d = 0; d < this.env.variationDimensions.length; d++) {
            zone[d] = [-0x10000, 0x10000];
        }
        for (const c of fvc) {
            const d = this.env.variationDimensions.reverse(c.dim);
            zone[d][0] = Math.max(-0x10000, Math.min(0x10000, Math.round(c.min * 0x10000)));
            zone[d][1] = Math.max(-0x10000, Math.min(0x10000, Math.round(c.max * 0x10000)));
        }
        return zone;
    }
    zoneToConditions(zone) {
        const cond = [];
        for (let d = 0; d < zone.length; d++) {
            if (zone[d][0] >= -0x10000 && zone[d][1] <= 0x10000)
                cond.push({
                    dim: this.env.variationDimensions.at(d),
                    min: zone[d][0] / 0x10000,
                    max: zone[d][1] / 0x10000
                });
        }
        return cond;
    }
}
exports.FeatureConsolidator = FeatureConsolidator;
//# sourceMappingURL=feature.js.map