import { __read, __spread } from "tslib";
import _ from "lodash";
import { getWorldTransformation, State as CoreState, } from "@intelligentgraphics/ig.gfx.core";
import * as Associates from "./Associates";
import { StrongChildMatch } from "./Interactor";
import SnapPoints from "./Interactor/SnapPoints";
import { cartesianProduct } from "./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({ id: this.parentId }, true).strongChildPoints.filter(function (pt) { return pt.type === "Child"; });
        var childrenToReposition = _.without.apply(_, __spread([this.previousChildren], currentChildren));
        childrenToReposition.forEach(function (childThatIsNoLonger) {
            var pointsOfChild = new SnapPoints({ 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 = getWorldTransformation(childThatIsNoLonger);
            var adaptedTrafo = childMatch.adaptTransformation(childTrafo);
            CoreState.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 = cartesianProduct(firstPoints, secondPoints)
            .map(function (_a) {
            var _b = __read(_a, 2), firstPoint = _b[0], secondPoint = _b[1];
            return new StrongChildMatch(firstPoint, secondPoint, first, second);
        })
            .filter(function (match) { return match.isCoreMatch; });
        return _.first(_.orderBy(matches, function (m) { return m.distance; }, "asc"));
    };
    return ChildRepositioner;
}());
export { ChildRepositioner };
