"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var lodash_1 = tslib_1.__importDefault(require("lodash"));
var ig_gfx_core_1 = require("@intelligentgraphics/ig.gfx.core");
var Associates = tslib_1.__importStar(require("./Associates"));
var Interactor_1 = require("./Interactor");
var SnapPoints_1 = tslib_1.__importDefault(require("./Interactor/SnapPoints"));
var Util_1 = require("./Util");
/** Class for repositioning children after actions or changes of a parent have been applied. */
var ChildRepositioner = /** @class */ (function () {
    function ChildRepositioner(parentId) {
        this.parentId = parentId;
        this.previousChildren = Associates.getChildren([this.parentId], false);
    }
    /**
     * Reposition all the children so that they again snap to the parent object.
     */
    ChildRepositioner.prototype.repositionChildren = function () {
        var _this = this;
        var currentChildren = Associates.getChildren([this.parentId], false);
        var parentsPoints = new SnapPoints_1.default({ id: this.parentId }, true).strongChildPoints.filter(function (pt) { return pt.type === "Child"; });
        var childrenToReposition = lodash_1.default.without.apply(lodash_1.default, tslib_1.__spread([this.previousChildren], currentChildren));
        childrenToReposition.forEach(function (childThatIsNoLonger) {
            var pointsOfChild = new SnapPoints_1.default({ id: childThatIsNoLonger }, true).strongChildPoints.filter(function (pt) { return pt.type === "Origin"; });
            var childMatch = _this.bestMatch(pointsOfChild, parentsPoints, childThatIsNoLonger, _this.parentId);
            if (!childMatch) {
                return;
            }
            var childTrafo = ig_gfx_core_1.getWorldTransformation(childThatIsNoLonger);
            var adaptedTrafo = childMatch.adaptTransformation(childTrafo);
            ig_gfx_core_1.State.API.SetTransformation(childThatIsNoLonger, adaptedTrafo);
        });
    };
    /**
     * Get the best match that can be made of the array of given points.
     * The best match is determined by minimal distance.
     * @param firstPoints
     * @param secondPoints
     * @param first
     * @param second
     * @returns {StrongChildMatch}
     */
    ChildRepositioner.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 Interactor_1.StrongChildMatch(firstPoint, secondPoint, first, second);
        })
            .filter(function (match) { return match.isCoreMatch; });
        return lodash_1.default.first(lodash_1.default.orderBy(matches, function (m) { return m.distance; }, "asc"));
    };
    return ChildRepositioner;
}());
exports.ChildRepositioner = ChildRepositioner;
