import { HitTestBehavior } from '../../../math/geometry/RTree/HitTestBehavior';
import { Cdt } from '../../ConstrainedDelaunayTriangulation/Cdt';
import { HubRadiiCalculator } from './HubRadiiCalculator';
// Stores intersections between edges, hubs, and obstacles to speed up simulated annealing
export class IntersectionCache {
    constructor(metroGraphData, bundlingSettings, costCalculator, cdt) {
        this.metroGraphData = metroGraphData;
        this.bundlingSettings = bundlingSettings;
        this.costCalculator = costCalculator;
        this.cdt = cdt;
    }
    InitializeCostCache() {
        for (const v of this.metroGraphData.VirtualNodes()) {
            v.cachedIdealRadius = HubRadiiCalculator.CalculateIdealHubRadiusWithNeighborsMBS(this.metroGraphData, this.bundlingSettings, v);
            v.cachedRadiusCost = this.costCalculator.RadiusCost(v, v.Position);
            v.cachedBundleCost = 0;
        }
        for (const edge of this.metroGraphData.VirtualEdges()) {
            const v = edge[0];
            const u = edge[1];
            const edgeInfo = this.metroGraphData.GetIjInfo(v, u);
            edgeInfo.cachedBundleCost = this.costCalculator.BundleCost(v, u, v.Position);
            v.cachedBundleCost += edgeInfo.cachedBundleCost;
            u.cachedBundleCost += edgeInfo.cachedBundleCost;
        }
    }
    UpdateCostCache(node) {
        const cdtTree = this.cdt.GetCdtTree();
        node.CdtTriangle = cdtTree.FirstHitNodeWithPredicate(node.Position, IntersectionCache.testPointInside).UserData;
        node.cachedIdealRadius = HubRadiiCalculator.CalculateIdealHubRadiusWithNeighborsMBS(this.metroGraphData, this.bundlingSettings, node);
        node.cachedRadiusCost = this.costCalculator.RadiusCost(node, node.Position);
        node.cachedBundleCost = 0;
        for (const adj of node.Neighbors) {
            if (!adj.IsRealNode) {
                adj.cachedIdealRadius = HubRadiiCalculator.CalculateIdealHubRadiusWithNeighborsMBS(this.metroGraphData, this.bundlingSettings, adj);
                adj.cachedRadiusCost = this.costCalculator.RadiusCost(adj, adj.Position);
            }
            const edgeInfo = this.metroGraphData.GetIjInfo(node, adj);
            adj.cachedBundleCost -= edgeInfo.cachedBundleCost;
            edgeInfo.cachedBundleCost = this.costCalculator.BundleCost(node, adj, node.Position);
            node.cachedBundleCost += edgeInfo.cachedBundleCost;
            adj.cachedBundleCost += edgeInfo.cachedBundleCost;
        }
    }
    static testPointInside(pnt, t) {
        return Cdt.PointIsInsideOfTriangle(pnt, t) ? HitTestBehavior.Stop : HitTestBehavior.Continue;
    }
}
//# sourceMappingURL=IntersectionCache.js.map