import { Chain, FocusTools, Keyboard, Keys, Logger, NamedChain, Step, UiFinder, Waiter } from '@ephox/agar';
import { Assert, UnitTest } from '@ephox/bedrock-client';
import { Fun, Result } from '@ephox/katamari';
import { Keying } from 'ephox/alloy/api/behaviour/Keying';
import { Representing } from 'ephox/alloy/api/behaviour/Representing';
import * as GuiFactory from 'ephox/alloy/api/component/GuiFactory';
import * as GuiSetup from 'ephox/alloy/api/testhelpers/GuiSetup';
import { Slider } from 'ephox/alloy/api/ui/Slider';
import * as RepresentPipes from 'ephox/alloy/test/behaviour/RepresentPipes';
UnitTest.asynctest('Browser Test: ui.slider.HorizontalSliderTest', (success, failure) => {
    GuiSetup.setup((_store, _doc, _body) => GuiFactory.build(Slider.sketch({
        dom: {
            tag: 'div',
            classes: ['horizontal-slider-test'],
            styles: {
                border: '1px solid black',
                height: '20px',
                display: 'flex'
            }
        },
        model: {
            mode: 'x',
            minX: 50,
            getInitialValue: Fun.constant(200),
            maxX: 200
        },
        stepSize: 10,
        snapToGrid: true,
        components: [
            Slider.parts['left-edge']({ dom: { tag: 'div', classes: ['horizontal-slider-test-left-edge'], styles: {
                        width: '40px',
                        height: '20px',
                        background: 'black'
                    } } }),
            Slider.parts.spectrum({ dom: { tag: 'div', classes: ['horizontal-slider-test-spectrum'], styles: {
                        height: '150px',
                        background: 'green'
                    } } }),
            Slider.parts['right-edge']({ dom: { tag: 'div', classes: ['horizontal-slider-test-right-edge'], styles: {
                        width: '40px',
                        height: '20px',
                        background: 'white'
                    } } }),
            Slider.parts.thumb({ dom: { tag: 'div', classes: ['horizontal-slider-test-thumb'], styles: {
                        width: '20px',
                        height: '20px',
                        background: 'gray'
                    } } })
        ]
    })), (doc, _body, _gui, component, _store) => {
        const cGetBounds = Chain.mapper((elem) => elem.dom.getBoundingClientRect());
        const cGetComponent = Chain.binder((elem) => component.getSystem().getByDom(elem));
        const cGetParts = NamedChain.asChain([
            NamedChain.writeValue('slider', component.element),
            NamedChain.direct('slider', UiFinder.cFindIn('.horizontal-slider-test-thumb'), 'thumb'),
            NamedChain.direct('slider', UiFinder.cFindIn('.horizontal-slider-test-left-edge'), 'ledge'),
            NamedChain.direct('slider', UiFinder.cFindIn('.horizontal-slider-test-right-edge'), 'redge'),
            NamedChain.direct('slider', UiFinder.cFindIn('.horizontal-slider-test-spectrum'), 'spectrum'),
            NamedChain.direct('thumb', cGetComponent, 'thumbComp'),
            NamedChain.direct('ledge', cGetComponent, 'ledgeComp'),
            NamedChain.direct('redge', cGetComponent, 'redgeComp'),
            NamedChain.direct('slider', cGetComponent, 'sliderComp'),
            NamedChain.direct('spectrum', cGetComponent, 'spectrumComp'),
            NamedChain.direct('thumb', cGetBounds, 'thumbRect'),
            NamedChain.direct('ledge', cGetBounds, 'ledgeRect'),
            NamedChain.direct('redge', cGetBounds, 'redgeRect'),
            NamedChain.direct('slider', cGetBounds, 'sliderRect'),
            NamedChain.direct('spectrum', cGetBounds, 'spectrumRect'),
            NamedChain.bundle(Result.value)
        ]);
        const cCheckThumbAtLeft = Chain.op((parts) => {
            Assert.eq('Thumb (' + parts.thumbRect.left + '->' + parts.thumbRect.right +
                '), Left-Edge: (' + parts.ledgeRect.left + '->' + parts.ledgeRect.right + ')', true, parts.ledgeRect.right > parts.thumbRect.left && parts.ledgeRect.left < parts.thumbRect.left);
        });
        const cCheckThumbAtRight = Chain.op((parts) => {
            Assert.eq('Thumb (' + parts.thumbRect.left + '->' + parts.thumbRect.right +
                '), Right-Edge: (' + parts.redgeRect.left + '->' + parts.redgeRect.right + ')', true, parts.redgeRect.left < parts.thumbRect.right && parts.ledgeRect.left < parts.redgeRect.left);
        });
        const cCheckThumbPastRight = Chain.op((parts) => {
            Assert.eq('Checking thumb past end of spectrum', true, parts.thumbRect.left > parts.spectrumRect.right);
        });
        const cCheckThumbBeforeLeft = Chain.op((parts) => {
            Assert.eq('Checking thumb before start of spectrum', true, parts.thumbRect.right < parts.spectrumRect.left);
        });
        const cCheckValue = (expected) => Chain.op((parts) => {
            const v = Representing.getValue(parts.sliderComp);
            Assert.eq('Checking slider value', expected, v);
        });
        return [
            Logger.t('Initial-Value: Checking that the thumb now overlaps the right edge at max', Waiter.sTryUntil('Initial load can take a while', Chain.asStep({}, [
                cGetParts,
                cCheckThumbAtRight,
                cCheckValue(200)
            ]))),
            Step.sync(() => {
                Slider.resetToMin(component);
            }),
            Logger.t('Checking that the thumb now overlaps the left edge at min', Chain.asStep({}, [
                cGetParts,
                cCheckThumbAtLeft,
                cCheckValue(50)
            ])),
            Step.sync(() => {
                Slider.resetToMax(component);
            }),
            Logger.t('Checking that the thumb now overlaps the right edge at max', Chain.asStep({}, [
                cGetParts,
                cCheckThumbAtRight,
                cCheckValue(200)
            ])),
            Logger.t('Focus the gradient', Chain.asStep({}, [
                cGetParts,
                Chain.op((parts) => {
                    Keying.focusIn(parts.sliderComp);
                })
            ])),
            FocusTools.sTryOnSelector('Focus should be on spectrum', doc, '.horizontal-slider-test-spectrum'),
            Keyboard.sKeydown(doc, Keys.right(), {}),
            Logger.t('Checking that the thumb is past the max', Chain.asStep({}, [
                cGetParts,
                cCheckThumbPastRight,
                cCheckValue(201)
            ])),
            Keyboard.sKeydown(doc, Keys.right(), {}),
            Logger.t('Pressed right at right edge. Checking that the thumb is still past the max and value has not changed', Chain.asStep({}, [
                cGetParts,
                cCheckThumbPastRight,
                cCheckValue(201)
            ])),
            Keyboard.sKeydown(doc, Keys.left(), {}),
            Logger.t('Pressed left at the right edge. Thumb should be at max', Chain.asStep({}, [
                cGetParts,
                cCheckThumbAtRight,
                cCheckValue(200)
            ])),
            Keyboard.sKeydown(doc, Keys.left(), {}),
            RepresentPipes.sAssertValue('200 -> 190 (step size)', 190, component),
            Keyboard.sKeydown(doc, Keys.left(), {}),
            RepresentPipes.sAssertValue('200 -> 180 (step size)', 180, component),
            Step.sync(() => {
                Slider.resetToMin(component);
            }),
            RepresentPipes.sAssertValue('min: 50', 50, component),
            Keyboard.sKeydown(doc, Keys.left(), {}),
            Logger.t('Checking that the thumb is before the min', Chain.asStep({}, [
                cGetParts,
                cCheckThumbBeforeLeft,
                cCheckValue(49)
            ])),
            Keyboard.sKeydown(doc, Keys.left(), {}),
            Logger.t('Checking that the thumb is *still* before the min', Chain.asStep({}, [
                cGetParts,
                cCheckThumbBeforeLeft,
                cCheckValue(49)
            ])),
            Keyboard.sKeydown(doc, Keys.right(), {}),
            Logger.t('Checking that the thumb is at the left edge', Chain.asStep({}, [
                cGetParts, cCheckThumbAtLeft, cCheckValue(50)
            ])),
            Keyboard.sKeydown(doc, Keys.right(), {}),
            RepresentPipes.sAssertValue('Checking that the thumb is now one step further right', 60, component),
            Keyboard.sKeydown(doc, Keys.right(), {}),
            RepresentPipes.sAssertValue('Checking that the thumb is now one step further right', 70, component),
            RepresentPipes.sSetValue(component, 99),
            RepresentPipes.sAssertValue('Check that Representing.setValue does something', 99, component),
        ];
    }, success, failure);
});
//# sourceMappingURL=HorizontalSliderTest.js.map