"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ig_gfx_core_1 = require("@intelligentgraphics/ig.gfx.core");
var ig_utilities_1 = require("@intelligentgraphics/ig.utilities");
var igd_core_1 = require("@intelligentgraphics/igd.core");
exports.createArticleQuery = function (articleState) {
    var getPropertyOfArticle = function (comId, property) {
        var article = articleState.getArticleByComId(comId);
        if (article === undefined) {
            throw new Error("Can not access property \"" + property + "\" of unknown article \"" + comId + "\"");
        }
        return article[property];
    };
    var createPropertyExtractor = function (property) { return function (comId) { return getPropertyOfArticle(comId, property); }; };
    var getAllArticles = function () {
        return articleState
            .getAllComIds()
            .map(function (comId) { return articleState.getArticleByComId(comId); });
    };
    var getFilteredArticles = function (filter) {
        return getAllArticles().filter(filter);
    };
    var getArticlesOfSource = function (sourceId) {
        return getFilteredArticles(function (_a) {
            var source = _a.source;
            return source === sourceId;
        });
    };
    var getArticlesWithCategory = function (category) {
        return getFilteredArticles(function (_a) {
            var categories = _a.categories;
            return categories[category];
        });
    };
    var getArticlesOfType = function (type) {
        return getFilteredArticles(function (article) { return article.type === type; });
    };
    var getGraphicalArticles = function () { return getArticlesOfType("graphical"); };
    var getFirstArticle = function (where) {
        if (where === void 0) { where = function () { return true; }; }
        return getAllArticles().find(where);
    };
    var getFirstArticleParent = function (comId, where) {
        if (where === void 0) { where = function () { return true; }; }
        var article = articleState.getArticleByComId(comId);
        if (article === undefined) {
            throw new Error("Can not query parents of unknown article \"" + comId + "\"");
        }
        while (article.parent !== undefined) {
            article = articleState.getArticleByComId(article.parent);
            if (article === undefined) {
                throw new Error("Parent of article \"" + comId + "\" no longer exists");
            }
            if (where(article)) {
                return article;
            }
        }
        return undefined;
    };
    var getDeepArticleChildren = function (comId) {
        var result = [];
        var collect = function (comId) {
            var article = articleState.getArticleByComId(comId);
            result.push(comId);
            article.children.forEach(collect);
        };
        var children = getPropertyOfArticle(comId, "children");
        children.forEach(collect);
        return result;
    };
    var getArticleProperty = function (comId, propertyKey) {
        var properties = getPropertyOfArticle(comId, "properties");
        return igd_core_1.IGXE.findProperty(properties, propertyKey);
    };
    var getHeadItem = function (sourceId) {
        return getAllArticles().find(function (article) {
            return article.type === "headItem" && article.source === sourceId;
        });
    };
    var getArticlesByComIds = function (comIds) {
        return comIds
            .map(function (comId) { return articleState.getArticleByComId(comId); })
            .filter(ig_utilities_1.isValue);
    };
    var getArticleByGfxId = function (gfxId) {
        var article = articleState.getArticleByGfxId(gfxId);
        if (article !== undefined) {
            return article;
        }
        var rootId = ig_gfx_core_1.Hierarchy.fixIfSuperRoot(gfxId);
        return articleState.getArticleByGfxId(rootId);
    };
    var getArticleGfxSuperRootId = function (comId) {
        var gfxId = getPropertyOfArticle(comId, "gfxId");
        if (gfxId === undefined) {
            return undefined;
        }
        return ig_gfx_core_1.Hierarchy.getSuperRootGfxId(gfxId) || undefined;
    };
    var getAllGfxIds = function () {
        return getFilteredArticles(function (article) {
            return article.type === "graphical" && article.gfxId !== undefined;
        }).map(function (article) { return article.gfxId; });
    };
    return {
        getHeadItem: getHeadItem,
        getAllComIds: articleState.getAllComIds,
        getAllArticles: getAllArticles,
        getFilteredArticles: getFilteredArticles,
        getArticlesOfSource: getArticlesOfSource,
        getArticlesWithCategory: getArticlesWithCategory,
        getArticlesOfType: getArticlesOfType,
        getArticlesByComIds: getArticlesByComIds,
        getGraphicalArticles: getGraphicalArticles,
        getAllGfxIds: getAllGfxIds,
        getComIdByGfxId: articleState.getComIdByGfxId,
        getArticleByComId: articleState.getArticleByComId,
        getArticleId: createPropertyExtractor("articleId"),
        getArticleGfxId: createPropertyExtractor("gfxId"),
        getArticleGfxSuperRootId: getArticleGfxSuperRootId,
        getArticleConfiguration: createPropertyExtractor("configuration"),
        getArticleProperties: createPropertyExtractor("properties"),
        getArticleProperty: getArticleProperty,
        getArticleCategories: createPropertyExtractor("categories"),
        getArticleData: createPropertyExtractor("data"),
        getArticleSourceData: createPropertyExtractor("sourceData"),
        getArticleSource: createPropertyExtractor("source"),
        getArticleParent: createPropertyExtractor("parent"),
        getArticleChildren: createPropertyExtractor("children"),
        getArticlePlacement: createPropertyExtractor("placement"),
        getArticleInfo: createPropertyExtractor("info"),
        getFirstArticle: getFirstArticle,
        getFirstArticleParent: getFirstArticleParent,
        getDeepArticleChildren: getDeepArticleChildren,
        getArticleByGfxId: getArticleByGfxId,
    };
};
