import { describe, it } from '@ephox/bedrock-client';
import { Fun } from '@ephox/katamari';
import { SugarElement, SugarPosition } from '@ephox/sugar';
import { assert } from 'chai';
import { bounds } from 'ephox/alloy/alien/Boxes';
import * as LayoutInset from 'ephox/alloy/positioning/layout/LayoutInset';
import * as Bounder from 'ephox/alloy/positioning/view/Bounder';
describe('BounderOverlappingTest', () => {
    const check = (expected, preference, anchor, panel, bubbles, bounds) => {
        const placee = SugarElement.fromTag('div');
        const actual = Bounder.attempts(placee, preference, anchor, panel, bubbles, bounds);
        assert.equal(actual.layout, expected.layout, 'layout');
        assert.equal(actual.rect.x, expected.x, 'X');
        assert.equal(actual.rect.y, expected.y, 'Y');
        if (expected.candidateY !== undefined) {
            assert.equal(actual.testY, expected.candidateY, 'Candidate Y');
        }
    };
    // Layout is for boxes with a bubble pointing to a cursor position (vertically aligned to nearest side)
    const bubble = () => {
        const northeast = () => ({
            offset: SugarPosition(1, -1),
            classesOn: [],
            classesOff: []
        });
        const northwest = () => ({
            offset: SugarPosition(-1, -1),
            classesOn: [],
            classesOff: []
        });
        const southeast = () => ({
            offset: SugarPosition(1, 2),
            classesOn: [],
            classesOff: []
        });
        const southwest = () => ({
            offset: SugarPosition(-1, 2),
            classesOn: [],
            classesOff: []
        });
        const south = () => ({
            offset: SugarPosition(-1, -1),
            classesOn: [],
            classesOff: []
        });
        const north = () => ({
            offset: SugarPosition(-1, -1),
            classesOn: [],
            classesOff: []
        });
        const east = () => ({
            offset: SugarPosition(1, 1),
            classesOn: [],
            classesOff: []
        });
        const west = () => ({
            offset: SugarPosition(1, 1),
            classesOn: [],
            classesOff: []
        });
        const notImplemented = Fun.die('Not implemented');
        return {
            northwest: notImplemented,
            northeast: notImplemented,
            southwest: notImplemented,
            southeast: notImplemented,
            south: notImplemented,
            north: notImplemented,
            east: notImplemented,
            west: notImplemented,
            insetSouthwest: southwest,
            insetSoutheast: southeast,
            insetSouth: south,
            insetNorthwest: northwest,
            insetNortheast: northeast,
            insetNorth: north,
            insetWest: west,
            insetEast: east
        };
    };
    const four = [LayoutInset.southeast, LayoutInset.southwest, LayoutInset.northeast, LayoutInset.northwest];
    const two = [LayoutInset.east, LayoutInset.west];
    const panelBox = bounds(0, 0, 15, 10);
    const bigPanel = bounds(0, 0, 100, 100);
    const view = bounds(50, 50, 350, 220);
    const bubb = bubble();
    it('an empty input array is invalid and just returns anchor coordinates', () => {
        check({
            layout: 'none',
            x: 0,
            y: 0
        }, [], bounds(0, 0, 10, 10), bounds(0, 0, 50, 50), bubble(), bounds(0, 0, 1000, 1000));
        check({
            layout: 'none',
            x: 100,
            y: 0
        }, [], bounds(100, 0, 200, 50), bounds(0, 0, 150, 25), bubble(), bounds(0, 0, 1000, 1000));
    });
    /*
     * The expected values include the calculations that layout and bounder are doing
     */
    it('southeast', () => {
        const anchor = bounds(340, 45, 80, 80);
        check({
            layout: 'layout-inset-southeast',
            x: anchor.x + 1,
            y: anchor.bottom - panelBox.height + 2 // 117
        }, four, anchor, panelBox, bubb, view);
    });
    it('southwest', () => {
        const anchor = bounds(40, 45, 50, 50);
        check({
            layout: 'layout-inset-southwest',
            x: anchor.right - panelBox.width - 1,
            y: anchor.bottom - panelBox.height + 2 // 87
        }, four, anchor, panelBox, bubb, view);
    });
    it('northeast', () => {
        const anchor = bounds(340, 235, 80, 80);
        check({
            layout: 'layout-inset-northeast',
            x: anchor.x + 1,
            y: anchor.y - 1 // 234
        }, four, anchor, panelBox, bubb, view);
    });
    it('northwest', () => {
        const anchor = bounds(40, 235, 50, 50);
        check({
            layout: 'layout-inset-northwest',
            x: anchor.right - panelBox.width - 1,
            y: anchor.y - 1 // 234
        }, four, anchor, panelBox, bubb, view);
    });
    it('all fit -> southeast because of order of preference', () => {
        const anchor = bounds(270, 100, 100, 100);
        check({
            layout: 'layout-inset-southeast',
            x: anchor.x + 1,
            y: anchor.bottom - panelBox.height + 2 // 192
        }, four, anchor, panelBox, bubb, view);
    });
    it('none -> best fit is southeast', () => {
        const anchor = bounds(60, 40, view.width, view.height + 15);
        check({
            layout: 'layout-inset-southeast',
            x: anchor.x + 1,
            y: view.bottom - bigPanel.height,
            candidateY: anchor.bottom - bigPanel.height + 2, // 177
        }, four, anchor, bigPanel, bubb, view);
    });
    it('none -> best fit is southwest', () => {
        const anchor = bounds(40, 40, view.width + 15, view.height);
        check({
            layout: 'layout-inset-southwest',
            x: view.right - bigPanel.width - 1,
            y: anchor.bottom - bigPanel.height + 2, // 177
        }, four, anchor, bigPanel, bubb, view);
    });
    it('none -> best fit is northeast', () => {
        const anchor = bounds(45, 55, view.width + 15, view.height);
        check({
            layout: 'layout-inset-northeast',
            x: view.x + 1,
            y: anchor.y - 1, // 54
        }, four, anchor, bigPanel, bubb, view);
    });
    it('none -> best fit is northwest', () => {
        const anchor = bounds(40, 45, view.width, view.height + 15);
        check({
            layout: 'layout-inset-northwest',
            x: anchor.right - bigPanel.width - 1,
            y: view.y,
            candidateY: anchor.y - 1, // 44
        }, four, anchor, bigPanel, bubb, view);
    });
    it('southeast (1px short on x and y)', () => {
        // Note: The additional -2 here is to account for the southeast bubble y offsets
        const anchor = bounds(view.y + 1, view.bottom - 20 - 2 - 1, 20, 20);
        check({
            layout: 'layout-inset-southeast',
            x: anchor.x + 1,
            y: anchor.bottom - panelBox.height + 2, // 259
        }, four, anchor, panelBox, bubb, view);
    });
    it('southeast (exactly for x and y)', () => {
        // Note: The additional -2 here is to account for the southeast bubble y offsets
        const anchor = bounds(view.y, view.bottom - 20 - 2, 20, 20);
        check({
            layout: 'layout-inset-southeast',
            x: anchor.x + 1,
            y: anchor.bottom - panelBox.height + 2, // 260
        }, four, anchor, panelBox, bubb, view);
    });
    it('southeast -> southwest (1px too far on x)', () => {
        // Note: The additional -2 here is to account for the southeast bubble y offsets
        const anchor = bounds(view.y - 1, view.bottom - 30 - 2, 30, 30);
        check({
            layout: 'layout-inset-southwest',
            x: anchor.right - panelBox.width - 1,
            y: anchor.bottom - panelBox.height + 2, // 260
        }, four, anchor, panelBox, bubb, view);
    });
    it('southeast -> northeast (1px too far on y)', () => {
        // Note: The additional -2 here is to account for the southeast bubble y offsets
        const anchor = bounds(view.y, view.bottom - 30 - 2 + 1, 30, 30);
        check({
            layout: 'layout-inset-northeast',
            x: anchor.x + 1,
            y: anchor.y - 1 // 238
        }, four, anchor, panelBox, bubb, view);
    });
    it('southeast -> northwest (1px too far on x and y)', () => {
        // Note: The additional -2 here is to account for the southeast bubble y offsets
        const anchor = bounds(view.y - 1, view.bottom - 30 - 2 + 1, 30, 30);
        check({
            layout: 'layout-inset-northwest',
            x: anchor.right - panelBox.width - 1,
            y: anchor.y - 1 // 238
        }, four, anchor, panelBox, bubb, view);
    });
    it('east', () => {
        const anchor = bounds(55, 150, 100, 100);
        check({
            layout: 'layout-inset-east',
            x: anchor.right - panelBox.width + 1,
            y: anchor.y + (anchor.height / 2) - (panelBox.height / 2) + 1 // 196
        }, two, anchor, panelBox, bubb, view);
    });
    it('none near bottom left -> best fit is east (limited to bottom bounds)', () => {
        const anchor = bounds(55, 240, 100, 100);
        check({
            layout: 'layout-inset-east',
            x: anchor.right - panelBox.width + 1,
            y: view.bottom - panelBox.height // 260 - constrained within viewport
        }, two, anchor, panelBox, bubb, view);
    });
    it('none near top left -> best fit is east (limited to top bounds)', () => {
        const anchor = bounds(55, 0, 100, 100);
        check({
            layout: 'layout-inset-east',
            x: anchor.right - panelBox.width + 1,
            y: view.y, // 50 - constrained within viewport
        }, two, anchor, panelBox, bubb, view);
    });
    it('west', () => {
        const anchor = bounds(320, 150, 100, 100);
        check({
            layout: 'layout-inset-west',
            x: anchor.x + 1,
            y: anchor.y + (anchor.height / 2) - (panelBox.height / 2) + 1 // 196
        }, two, anchor, panelBox, bubb, view);
    });
    it('none near bottom right -> best fit is west (limited to bottom bounds)', () => {
        const anchor = bounds(320, 240, 100, 100);
        check({
            layout: 'layout-inset-west',
            x: anchor.x + 1,
            y: view.bottom - panelBox.height // 260 - constrained within viewport
        }, two, anchor, panelBox, bubb, view);
    });
    it('none near top right -> best fit is west (limited to top bounds)', () => {
        const anchor = bounds(320, 0, 100, 100);
        check({
            layout: 'layout-inset-west',
            x: anchor.x + 1,
            y: view.y, // 50 - constrained within viewport
        }, two, anchor, panelBox, bubb, view);
    });
});
//# sourceMappingURL=BounderOverlappingTest.js.map