"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExprEvalContext = void 0;
var expr_eval_1 = require("expr-eval");
var string_1 = require("../utils/string");
var ol_style_helpers_1 = require("./ol-style-helpers");
var ExprEvalContext = /** @class */ (function () {
    function ExprEvalContext() {
        this.exprCache = {};
        this.filterCache = {};
        this.clusterExprCache = {};
        this.clusterFilterCache = {};
        this.parser = new expr_eval_1.Parser();
        this.parser.functions.agg_sum = function (collectionProperty, property) {
            if (Array.isArray(collectionProperty)) {
                var res = collectionProperty.reduce(function (running, currentItem) { var _a; return running + ((_a = currentItem.get(property)) !== null && _a !== void 0 ? _a : 0); }, 0);
                return res;
            }
            return undefined;
        };
        this.parser.functions.arr_size = function (collectionProperty) {
            if (Array.isArray(collectionProperty)) {
                return collectionProperty.length;
            }
            return 1;
        };
        this.parser.functions.feat_property = function (feature, name) {
            if (feature) {
                return feature.get(name);
            }
            else {
                return undefined;
            }
        };
    }
    ExprEvalContext.prototype.addFilter = function (expr) {
        if (!this.filterCache[expr]) {
            this.filterCache[expr] = this.parser.parse(expr);
        }
    };
    ExprEvalContext.prototype.addExpr = function (expr) {
        if (!this.exprCache[expr]) {
            this.exprCache[expr] = this.parser.parse(expr);
        }
    };
    ExprEvalContext.prototype.addClusterFilter = function (expr) {
        if (!this.clusterFilterCache[expr]) {
            this.clusterFilterCache[expr] = this.parser.parse(expr);
        }
    };
    ExprEvalContext.prototype.addClusterExpr = function (expr) {
        if (!this.clusterExprCache[expr]) {
            this.clusterExprCache[expr] = this.parser.parse(expr);
        }
    };
    ExprEvalContext.prototype.cleanValues = function (feat) {
        var vals = feat.getProperties();
        //UGLY: We have no guarantee that the properties in question will not have
        //spaces in them (that will break evaluation), so force the matter by replacing
        //spaces with underscores. What this means is if we find a property named "OFFICE TYPE", it
        //will be converted to "OFFICE_TYPE"
        var keys = Object.keys(vals);
        var cvals = {};
        for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
            var k = keys_1[_i];
            cvals[(0, string_1.strReplaceAll)(k, " ", "_")] = vals[k];
        }
        return cvals;
    };
    ExprEvalContext.prototype.evaluateFilter = function (feat) {
        var cvals = this.cleanValues(feat);
        var cache = (0, ol_style_helpers_1.isClusteredFeature)(feat) ? this.clusterFilterCache : this.filterCache;
        for (var filter in cache) {
            // Does this feature match an expression?
            if (cache[filter].evaluate(cvals) == true) {
                return filter;
            }
        }
        return undefined;
    };
    ExprEvalContext.prototype.evaluate = function (expr, feat) {
        var cvals = this.cleanValues(feat);
        if ((0, ol_style_helpers_1.isClusteredFeature)(feat)) {
            this.addClusterExpr(expr);
            return this.clusterExprCache[expr].evaluate(cvals);
        }
        else {
            this.addExpr(expr);
            return this.exprCache[expr].evaluate(cvals);
        }
    };
    return ExprEvalContext;
}());
exports.ExprEvalContext = ExprEvalContext;
//# sourceMappingURL=expr-eval-context.js.map