"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PositionData = void 0;
class PositionData {
    shape;
    positioned;
    isCandidate;
    sequence;
    initialX;
    initialY;
    constructor(shape, positioned, isCandidate, sequence, initialX, initialY) {
        this.shape = shape;
        this.positioned = positioned;
        this.isCandidate = isCandidate;
        this.sequence = sequence;
        this.initialX = initialX;
        this.initialY = initialY;
    }
    static positionOneSequence(positionMe, ranges) {
        let newPos = this.findGapBetweenSequences(positionMe, ranges);
        positionMe.shape.top = newPos;
        positionMe.sequence.y = positionMe.shape.top;
        positionMe.positioned = true;
    }
    static findGapBetweenSequences(forSeq, stacksNear) {
        stacksNear = stacksNear
            .filter((s) => {
            // remove ones that are inside others as they cause layout to get weird.
            for (let possibleBigger of stacksNear) {
                if (s.shape.top > possibleBigger.shape.top && s.shape.bottom < possibleBigger.shape.bottom) {
                    return false;
                }
            }
            return true;
        })
            .sort((a, b) => {
            if (a.shape.top > b.shape.top) {
                return 1;
            }
            else {
                return -1;
            }
        });
        // -------------
        // -- case 4 : it did not fit into a gap, need to place below..
        // -------------
        if (stacksNear.length === 0) {
            // -------------
            // -- case 1 : this is first stack.  just place where it is to go.
            // -------------
            return forSeq.shape.top;
        }
        else if (forSeq.shape.top > stacksNear[stacksNear.length - 1].shape.bottom) {
            // -------------
            // -- case 2 : it is below the last one (they are sorted).
            // -------------
            return forSeq.shape.top;
        }
        else if (stacksNear.length === 1) {
            // -------------
            // -- case 3 : there is only one other stack.
            // -------------
            // see if can it go where it wants to go
            if (forSeq.shape.bottom < stacksNear[0].shape.topWithPadding)
                return forSeq.shape.top;
            else if (stacksNear[0].shape.bottom < forSeq.shape.topWithPadding)
                return forSeq.shape.top;
            // put below
            return stacksNear[0].shape.bottom;
        }
        else {
            // -------------
            // -- case 4 : position inside the different stacks.
            // -------------
            // if it is above the top one (they are sorted) it can go where it wants.
            if (forSeq.shape.bottom < stacksNear[0].shape.topWithPadding) {
                return forSeq.shape.top;
            }
            let height = forSeq.shape.height;
            // iterate leaving off the last item in array
            for (let _i = 0; _i < stacksNear.length - 1; _i++) {
                let fixed = stacksNear[_i];
                let fixedNext = stacksNear[_i + 1];
                // skip ahead of the top of this is ABOVE the top of the one we are considering.
                if (forSeq.shape.top > fixedNext.shape.top) {
                    continue;
                }
                let gapBetween = fixedNext.shape.top - fixed.shape.bottom;
                // only if gap is big enough consider it.
                if (gapBetween > height) {
                    // it can go here...
                    if (fixed.shape.bottom < forSeq.shape.top && forSeq.shape.bottom < fixedNext.shape.top) {
                        // it can go where it wants
                        return forSeq.shape.top;
                    }
                    else {
                        return fixed.shape.bottom;
                    }
                }
            }
        }
        return stacksNear[stacksNear.length - 1].shape.bottom;
    }
    inRange(otherData) {
        if (this.compare(this.shape.left, { low: otherData.shape.left, high: otherData.shape.right }))
            return true;
        if (this.compare(this.shape.right, { low: otherData.shape.left, high: otherData.shape.right }))
            return true;
        if (this.compare(otherData.shape.right, { low: this.shape.left, high: this.shape.right }))
            return true;
        return false;
    }
    compare(item, between) {
        return item >= between.low && item <= between.high;
    }
}
exports.PositionData = PositionData;
//# sourceMappingURL=FlowEditContext.PositionData.js.map