"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"));
var Associates = tslib_1.__importStar(require("./Associates"));
var SnapMatches_1 = require("./Interactor/SnapMatches");
var SnapPoints_1 = tslib_1.__importDefault(require("./Interactor/SnapPoints"));
var Util_1 = require("./Util");
/**
 * Class for connecting articles (e.g. after a change in dimension or a movement)
 * Has to be initiated before the disconnection starts.
 */
var ArticleConnector = /** @class */ (function () {
    function ArticleConnector(left, right) {
        this.left = left;
        this.right = right;
    }
    /**
     * Restore the connection.
     * Only works if there are matching attachpoints in the neighbor group of the left and right element.
     */
    ArticleConnector.prototype.connect = function () {
        var neighbors = tslib_1.__spread(Associates.getNeighbors([this.right], true), [
            this.right,
        ]);
        var gfxIdsToMove = tslib_1.__spread(neighbors, Associates.getChildren(neighbors, true));
        // component are already neighbors
        if (lodash_1.default.includes(gfxIdsToMove, this.left)) {
            return;
        }
        var match = this.closestMatch();
        if (!match) {
            return;
        }
        gfxIdsToMove.forEach(function (id) {
            var componentTrafo = Core.getWorldTransformation(id);
            var adaptedTrafo = match.adaptTransformation(componentTrafo);
            Core.State.API.SetTransformation(id, adaptedTrafo);
        });
    };
    /**
     * Get the closest match to use for the connection.
     * We need to consider the "Left" points of the right group and the "Right" points of the left group.
     * @returns {any}
     */
    ArticleConnector.prototype.closestMatch = function () {
        var pointsOnTheRight = new SnapPoints_1.default({ id: this.right }, true).strongNeighborSnapPoints.filter(function (pt) { return pt.type === "Left"; });
        var pointsOnTheLeft = new SnapPoints_1.default({ id: this.left }, true).strongNeighborSnapPoints.filter(function (pt) { return pt.type === "Right"; });
        return this.bestMatch(pointsOnTheRight, pointsOnTheLeft, this.left, this.right);
    };
    /**
     * Make all possible matches and sort by distance so that the first match is the one with the closest distance
     * @param firstPoints
     * @param secondPoints
     * @param first
     * @param second
     * @returns {any}
     */
    ArticleConnector.prototype.bestMatch = function (firstPoints, secondPoints, first, second) {
        var matches = Util_1.cartesianProduct(firstPoints, secondPoints).map(function (_a) {
            var _b = tslib_1.__read(_a, 2), firstPoint = _b[0], secondPoint = _b[1];
            return new SnapMatches_1.StrongNeighborMatch(firstPoint, secondPoint, first, second);
        });
        return lodash_1.default.first(lodash_1.default.orderBy(matches, function (m) { return m.distance; }, "asc"));
    };
    return ArticleConnector;
}());
exports.ArticleConnector = ArticleConnector;
