import { VerticalConstraintsForSugiyama } from './VerticalConstraintsForSugiyama';
import { HorizontalConstraintsForSugiyama } from './HorizontalConstraintsForSugiyama';
import { LayerDirectionEnum } from './layerDirectionEnum';
import { PlaneTransformation } from '../../math/geometry/planeTransformation';
import { closeDistEps } from '../../utils/compare';
import { EdgeRoutingSettings } from '../../routing/EdgeRoutingSettings';
import { EdgeRoutingMode } from '../../routing/EdgeRoutingMode';
export var SnapToGridByY;
(function (SnapToGridByY) {
    SnapToGridByY[SnapToGridByY["None"] = 0] = "None";
    SnapToGridByY[SnapToGridByY["Top"] = 1] = "Top";
    SnapToGridByY[SnapToGridByY["Bottom"] = 2] = "Bottom";
})(SnapToGridByY || (SnapToGridByY = {}));
export class LayoutSettings {
    constructor() {
        this.edgeRoutingSettings = new EdgeRoutingSettings();
        this.minimalWidth = 0;
        this.minimalHeight = 0;
        this.nodeSeparation = 10;
        this.packingAspectRatio = 1.5;
    }
    // The resulting layout should be at list this wide
    get MinimalWidth() {
        return this.minimalWidth;
    }
    set MinimalWidth(value) {
        this.minimalWidth = Math.max(value, 0);
    }
    // The resulting layout should be at least this tall
    get MinimalHeight() {
        return this.minimalHeight;
    }
    set MinimalHeight(value) {
        this.minimalHeight = Math.max(value, 0);
    }
    get NodeSeparation() {
        return this.nodeSeparation;
    }
    set NodeSeparation(value) {
        this.nodeSeparation = value;
    }
    get PackingAspectRatio() {
        return this.packingAspectRatio;
    }
    set PackingAspectRatio(value) {
        this.packingAspectRatio = value;
    }
}
export class SugiyamaLayoutSettings extends LayoutSettings {
    constructor() {
        super();
        this.margins = { left: 0, top: 0, bottom: 0, right: 0 };
        this.sameRanks = new Array();
        this.verticalConstraints = new VerticalConstraintsForSugiyama();
        this.horizontalConstraints = new HorizontalConstraintsForSugiyama();
        this.NoGainAdjacentSwapStepsBound = 5;
        this.RepetitionCoefficientForOrdering = 1;
        this.AspectRatio = 0;
        this.MaxNumberOfPassesInOrdering = 24;
        // When the number of vertices in the proper layered graph
        // is at least threshold  we switch to the faster, but not so accurate,
        // method for x-coordinates calculations.
        this.BrandesThreshold = 600;
        this.LabelCornersPreserveCoefficient = 0.1;
        this.MinNodeHeight = (72 * 0.5) / 4;
        this.MinNodeWidth = (72 * 0.75) / 4;
        this.SnapToGridByY = SnapToGridByY.None;
        this.yLayerSep = 10 * 3;
        this.transform = PlaneTransformation.getIdentity();
        this.GridSizeByY = 0;
        this.GridSizeByX = 0;
        this.edgeRoutingSettings.EdgeRoutingMode = EdgeRoutingMode.SugiyamaSplines;
    }
    get LayerSeparation() {
        return this.yLayerSep;
    }
    set LayerSeparation(value) {
        this.yLayerSep = Math.max(10 * 3, value);
    }
    ActualLayerSeparation(layersAreDoubled) {
        return layersAreDoubled ? this.LayerSeparation / 2.0 : this.LayerSeparation;
    }
    transformIsRotation(ang) {
        const p = PlaneTransformation.rotation(ang);
        for (let i = 0; i < 2; i++) {
            for (let j = 0; j < 3; j++)
                if (!closeDistEps(p.elements[i][j], this.transform.elements[i][j]))
                    return false;
        }
        return true;
    }
    get layerDirection() {
        if (this.transformIsRotation(0))
            return LayerDirectionEnum.TB;
        if (this.transformIsRotation(Math.PI / 2))
            return LayerDirectionEnum.LR;
        if (this.transformIsRotation(-Math.PI / 2))
            return LayerDirectionEnum.RL;
        if (this.transformIsRotation(Math.PI))
            return LayerDirectionEnum.BT;
        return LayerDirectionEnum.None;
    }
    set layerDirection(value) {
        switch (value) {
            case LayerDirectionEnum.TB:
                break;
            case LayerDirectionEnum.LR:
                this.transform = PlaneTransformation.rotation(Math.PI / 2);
                break;
            case LayerDirectionEnum.RL:
                this.transform = PlaneTransformation.rotation(-Math.PI / 2);
                break;
            case LayerDirectionEnum.BT:
                this.transform = PlaneTransformation.rotation(Math.PI);
                break;
            default:
                throw new Error('unexpected layout direction');
        }
    }
}
//# sourceMappingURL=SugiyamaLayoutSettings.js.map