import { nu as NuSpotInfo } from '../view/SpotInfo';
import * as Direction from './Direction';
import { boundsRestriction } from './LayoutBounds';
import { getPlacement } from './Placement';
/*
  Layouts for things that overlay over the anchor element/box. These are designed to mirror
  the `Layout` logic.

  As an example `Layout.north` will appear horizontally centered above the anchor, whereas
  `LayoutInset.north` will appear horizontally centered overlapping the top of the anchor.
 */
const labelPrefix = 'layout-inset';
// returns left edge of anchor - used to display element to the left, left edge against the anchor
const westEdgeX = (anchor) => anchor.x;
// returns middle of anchor minus half the element width - used to horizontally centre element to the anchor
const middleX = (anchor, element) => anchor.x + (anchor.width / 2) - (element.width / 2);
// returns right edge of anchor minus element width - used to display element to the right, right edge against the anchor
const eastEdgeX = (anchor, element) => anchor.x + anchor.width - element.width;
// returns top edge - used to display element to the top, top edge against the anchor
const northY = (anchor) => anchor.y;
// returns bottom edge minus element height - used to display element at the bottom, bottom edge against the anchor
const southY = (anchor, element) => anchor.y + anchor.height - element.height;
// returns centre of anchor minus half the element height - used to vertically centre element to the anchor
const centreY = (anchor, element) => anchor.y + (anchor.height / 2) - (element.height / 2);
// positions element relative to the bottom right of the anchor
const southwest = (anchor, element, bubbles) => NuSpotInfo(eastEdgeX(anchor, element), southY(anchor, element), bubbles.insetSouthwest(), Direction.northwest(), "southwest" /* Southwest */, boundsRestriction(anchor, { right: 0 /* RightEdge */, bottom: 3 /* BottomEdge */ }), labelPrefix);
// positions element relative to the bottom left of the anchor
const southeast = (anchor, element, bubbles) => NuSpotInfo(westEdgeX(anchor), southY(anchor, element), bubbles.insetSoutheast(), Direction.northeast(), "southeast" /* Southeast */, boundsRestriction(anchor, { left: 1 /* LeftEdge */, bottom: 3 /* BottomEdge */ }), labelPrefix);
// positions element relative to the top right of the anchor
const northwest = (anchor, element, bubbles) => NuSpotInfo(eastEdgeX(anchor, element), northY(anchor), bubbles.insetNorthwest(), Direction.southwest(), "northwest" /* Northwest */, boundsRestriction(anchor, { right: 0 /* RightEdge */, top: 2 /* TopEdge */ }), labelPrefix);
// positions element relative to the top left of the anchor
const northeast = (anchor, element, bubbles) => NuSpotInfo(westEdgeX(anchor), northY(anchor), bubbles.insetNortheast(), Direction.southeast(), "northeast" /* Northeast */, boundsRestriction(anchor, { left: 1 /* LeftEdge */, top: 2 /* TopEdge */ }), labelPrefix);
// positions element relative to the top of the anchor, horizontally centered
const north = (anchor, element, bubbles) => NuSpotInfo(middleX(anchor, element), northY(anchor), bubbles.insetNorth(), Direction.south(), "north" /* North */, boundsRestriction(anchor, { top: 2 /* TopEdge */ }), labelPrefix);
// positions element relative to the bottom of the anchor, horizontally centered
const south = (anchor, element, bubbles) => NuSpotInfo(middleX(anchor, element), southY(anchor, element), bubbles.insetSouth(), Direction.north(), "south" /* South */, boundsRestriction(anchor, { bottom: 3 /* BottomEdge */ }), labelPrefix);
// positions element with the right edge against the anchor, vertically centered
const east = (anchor, element, bubbles) => NuSpotInfo(eastEdgeX(anchor, element), centreY(anchor, element), bubbles.insetEast(), Direction.west(), "east" /* East */, boundsRestriction(anchor, { right: 0 /* RightEdge */ }), labelPrefix);
// positions element with the left each against the anchor, vertically centered
const west = (anchor, element, bubbles) => NuSpotInfo(westEdgeX(anchor), centreY(anchor, element), bubbles.insetWest(), Direction.east(), "west" /* West */, boundsRestriction(anchor, { left: 1 /* LeftEdge */ }), labelPrefix);
const all = () => [southeast, southwest, northeast, northwest, south, north, east, west];
const allRtl = () => [southwest, southeast, northwest, northeast, south, north, east, west];
const lookupPreserveLayout = (lastPlacement) => {
    switch (lastPlacement) {
        case "north" /* North */:
            return north;
        case "northeast" /* Northeast */:
            return northeast;
        case "northwest" /* Northwest */:
            return northwest;
        case "south" /* South */:
            return south;
        case "southeast" /* Southeast */:
            return southeast;
        case "southwest" /* Southwest */:
            return southwest;
        case "east" /* East */:
            return east;
        case "west" /* West */:
            return west;
    }
};
const preserve = (anchor, element, bubbles, placee, bounds) => {
    const layout = getPlacement(placee).map(lookupPreserveLayout).getOr(north);
    return layout(anchor, element, bubbles, placee, bounds);
};
const lookupFlippedLayout = (lastPlacement) => {
    switch (lastPlacement) {
        case "north" /* North */:
            return south;
        case "northeast" /* Northeast */:
            return southeast;
        case "northwest" /* Northwest */:
            return southwest;
        case "south" /* South */:
            return north;
        case "southeast" /* Southeast */:
            return northeast;
        case "southwest" /* Southwest */:
            return northwest;
        case "east" /* East */:
            return west;
        case "west" /* West */:
            return east;
    }
};
const flip = (anchor, element, bubbles, placee, bounds) => {
    const layout = getPlacement(placee).map(lookupFlippedLayout).getOr(north);
    return layout(anchor, element, bubbles, placee, bounds);
};
export { southeast, northeast, southwest, northwest, south, north, east, west, all, allRtl, preserve, flip };
//# sourceMappingURL=LayoutInset.js.map