"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var lodash_1 = tslib_1.__importDefault(require("lodash"));
var Core = tslib_1.__importStar(require("@intelligentgraphics/ig.gfx.core"));
/** Class for filtering in the multi articles package  */
var MultiArticleFilter = /** @class */ (function () {
    /**
     * The constructor.
     * @param multiArticles
     */
    function MultiArticleFilter(multiArticles) {
        var _this = this;
        /** The current configuration */
        this.configuration = {};
        this.multiArticles = multiArticles;
        this.availableArticles = this.multiArticles
            .getAllConcreteArticles()
            .map(function (article) {
            return _this.multiArticles.FilterBehaviour[article] || article;
        });
        this.allArticles = this.availableArticles;
    }
    /**
     * Start the filter with the given mode. Reset configurations.
     * @param mode
     */
    MultiArticleFilter.prototype.startMode = function (mode) {
        this.mode = mode;
        this.configuration = {};
        var rootDescendants = new Set(this.multiArticles.getDescendants(this.mode.root));
        this.allArticles = this.availableArticles.filter(function (name) {
            return rootDescendants.has(name);
        });
    };
    /**
     * Set the property to the given name in the current configuration
     * @param name
     * @param value
     */
    MultiArticleFilter.prototype.setProperty = function (name, value) {
        if (value === undefined) {
            delete this.configuration[name];
        }
        else {
            this.configuration[name] = value;
        }
    };
    /**
     * Use the filter mode to obtain all properties available for the current configuration.
     * @returns {Array<string>}
     */
    MultiArticleFilter.prototype.getProperties = function () {
        return this.getMode().getProperties(this.configuration);
    };
    /**
     * Use the filter mode to get the viable values for a given property.
     * @param property
     * @returns {Array<string>}
     */
    MultiArticleFilter.prototype.getValues = function (property) {
        var values = this.getMode().getPropertyValues(property, this.configuration);
        if (values.length && values[0].match(/^\d+(\.\d*)?$/)) {
            values.sort(function (a, b) { return parseFloat(a) - parseFloat(b); });
        }
        return values;
    };
    /**
     * Get the current value of a property.
     * @param property
     * @returns {any}
     */
    MultiArticleFilter.prototype.getCurrentValue = function (property) {
        return this.configuration[property];
    };
    MultiArticleFilter.prototype.getPropertyInformation = function (type, property) {
        return this.multiArticles.getPropertyInformation(type, property);
    };
    /**
     * Get all concrete articles that fit the current configuration
     * @returns {string[]}
     */
    MultiArticleFilter.prototype.getViableArticles = function () {
        var _this = this;
        var config = lodash_1.default.omitBy(this.configuration, function (x) { return _this.configuration[x] === ""; });
        var alwaysShow = function (article) {
            return lodash_1.default.includes(lodash_1.default.keys(_this.multiArticles.getCategories(article)), Core.Category.DontFilter);
        };
        var matchesConfig = function (article) {
            if (_this.multiArticles.isConcreteArticle(article)) {
                return _this.multiArticles.matchesConfiguration(article, config);
            }
            return _this.multiArticles
                .getDescendants(article)
                .some(function (a) { return _this.multiArticles.matchesConfiguration(a, config); });
        };
        var isAllowed = function (article) {
            return matchesConfig(article) || alwaysShow(article);
        };
        var filteredMultiArticles = this.allArticles.filter(isAllowed);
        return lodash_1.default.uniq(lodash_1.default.flatMap(filteredMultiArticles, function (article) {
            return _this.concreteIdsFromMultiArticleId(article);
        }));
    };
    MultiArticleFilter.prototype.concreteIdsFromMultiArticleId = function (article) {
        var inverted = lodash_1.default.invertBy(this.multiArticles.FilterBehaviour);
        return inverted[article] || [article];
    };
    /**
     * Reset the internal configuration, preserving the mode
     */
    MultiArticleFilter.prototype.reset = function () {
        this.configuration = {};
    };
    MultiArticleFilter.prototype.setRoot = function (newRoot, reset) {
        if (reset === void 0) { reset = true; }
        var mode = this.getMode();
        mode.root = newRoot;
        if (reset) {
            this.reset();
        }
        var rootDescendants = this.multiArticles.getDescendants(mode.root);
        this.allArticles = this.availableArticles.filter(function (name) {
            return lodash_1.default.includes(rootDescendants, name);
        });
    };
    MultiArticleFilter.prototype.getMode = function () {
        if (this.mode === undefined) {
            throw new Error("This filter has not yet been started with a filter mode!");
        }
        return this.mode;
    };
    return MultiArticleFilter;
}());
exports.MultiArticleFilter = MultiArticleFilter;
