"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OtVarOps = exports.OtVarValueFactory = void 0;
const master_set_1 = require("./master-set");
const value_1 = require("./value");
class OtVarValueFactory {
    constructor(masterSet = new master_set_1.OtVarMasterSet()) {
        this.masterSet = masterSet;
    }
    create(origin = 0, variance = []) {
        if (!variance)
            return origin;
        return value_1.OtVarValueC.Create(this.masterSet, origin, variance);
    }
    make(...xs) {
        let v = exports.OtVarOps.neutral;
        for (const x of xs) {
            if (Array.isArray(x))
                v = exports.OtVarOps.add(v, this.create(0, [x]));
            else
                v = exports.OtVarOps.add(v, x);
        }
        return v;
    }
}
exports.OtVarValueFactory = OtVarValueFactory;
class OrVarOpsImpl {
    constructor() {
        this.neutral = 0;
    }
    scaleAdd(sa, a, sb, b) {
        if (typeof a === "number") {
            if (typeof b === "number") {
                return sa * a + sb * b;
            }
            else {
                return b.scaleAddNumber(sb, sa * a);
            }
        }
        else {
            if (typeof b === "number") {
                return a.scaleAddNumber(sa, sb * b);
            }
            else {
                return a.scaleAddScaleVariable(sa, sb, b);
            }
        }
    }
    add(a, b) {
        return this.scaleAdd(1, a, 1, b);
    }
    minus(a, b) {
        return this.scaleAdd(1, a, -1, b);
    }
    negate(a) {
        return this.scaleAdd(-1, a, 1, 0);
    }
    scale(s, a) {
        return this.scaleAdd(s, a, 1, 0);
    }
    addScale(a, s, b) {
        return this.scaleAdd(1, a, s, b);
    }
    originOf(a) {
        if (typeof a === "number")
            return a;
        else
            return a.origin;
    }
    varianceDeltaOf(a, m) {
        if (typeof a === "number")
            return 0;
        else
            return a.getDelta(m);
    }
    varianceOf(a) {
        if (typeof a === "number")
            return [];
        else
            return a.variance();
    }
    removeOrigin(a) {
        return this.minus(a, this.originOf(a));
    }
    evaluate(a, instance) {
        if (typeof a === "number")
            return a;
        else
            return a.evaluate(instance);
    }
    equal(a, b, err = 1) {
        if (typeof a === "number" && typeof b === "number")
            return Math.abs(a - b) <= err;
        if (Math.abs(this.evaluate(a, null) - this.evaluate(b, null)) > err)
            return false;
        for (const [m, delta] of [...this.varianceOf(a), ...this.varianceOf(b)]) {
            const peak = m.getPeak();
            if (Math.abs(this.evaluate(a, peak) - this.evaluate(b, peak)) > err) {
                return false;
            }
        }
        return true;
    }
    sum(...xs) {
        let s = 0;
        for (const x of xs)
            s = this.add(s, x);
        return s;
    }
    isConstant(x) {
        if (typeof x === "number")
            return true;
        return this.equal(x, this.originOf(x), 1 / 0x10000);
    }
    isZero(x) {
        return this.isConstant(x) && this.originOf(x) === 0;
    }
    Creator(ms) {
        return new OtVarValueFactory(ms || new master_set_1.OtVarMasterSet());
    }
}
exports.OtVarOps = new OrVarOpsImpl();
//# sourceMappingURL=ops.js.map