import { Fun, Optional } from '@ephox/katamari';
import { Css, Width } from '@ephox/sugar';
import * as AlloyTriggers from '../../api/events/AlloyTriggers';
import * as EdgeActions from './EdgeActions';
import * as ModelCommon from './ModelCommon';
import * as SliderModel from './SliderModel';
import { getMaxXBounds, getMinXBounds, getXCenterOffSetOf, getXScreenRange } from './SliderOffsets';
import { currentValue, hasLEdge, hasREdge, maxX, minX, rounded, snap, snapStart, step, xRange } from './SliderValues';
// fire slider change event with x value
const fireSliderChange = (spectrum, value) => {
    AlloyTriggers.emitWith(spectrum, ModelCommon.sliderChangeEvent(), { value });
};
// find the value of the x offset of where the mouse was clicked from the model.
const findValueOfOffset = (spectrum, detail, left) => {
    const args = {
        min: minX(detail),
        max: maxX(detail),
        range: xRange(detail),
        value: left,
        step: step(detail),
        snap: snap(detail),
        snapStart: snapStart(detail),
        rounded: rounded(detail),
        hasMinEdge: hasLEdge(detail),
        hasMaxEdge: hasREdge(detail),
        minBound: getMinXBounds(spectrum),
        maxBound: getMaxXBounds(spectrum),
        screenRange: getXScreenRange(spectrum)
    };
    return SliderModel.findValueOf(args);
};
// find the value and fire a slider change event, returning the value
const setValueFrom = (spectrum, detail, value) => {
    const xValue = findValueOfOffset(spectrum, detail, value);
    const sliderVal = xValue;
    fireSliderChange(spectrum, sliderVal);
    return xValue;
};
// fire a slider change event with the minimum value
const setToMin = (spectrum, detail) => {
    const min = minX(detail);
    fireSliderChange(spectrum, min);
};
// fire a slider change event with the maximum value
const setToMax = (spectrum, detail) => {
    const max = maxX(detail);
    fireSliderChange(spectrum, max);
};
// move in a direction by step size. Fire change at the end
const moveBy = (direction, spectrum, detail) => {
    const f = (direction > 0) ? SliderModel.increaseBy : SliderModel.reduceBy;
    const xValue = f(currentValue(detail), minX(detail), maxX(detail), step(detail));
    fireSliderChange(spectrum, xValue);
    return Optional.some(xValue);
};
const handleMovement = (direction) => (spectrum, detail) => moveBy(direction, spectrum, detail).map(Fun.always);
// get x offset from event
const getValueFromEvent = (simulatedEvent) => {
    const pos = ModelCommon.getEventSource(simulatedEvent);
    return pos.map((p) => p.left);
};
// find the x offset of a given value from the model
const findOffsetOfValue = (spectrum, detail, value, minEdge, maxEdge) => {
    const minOffset = 0;
    const maxOffset = getXScreenRange(spectrum);
    const centerMinEdge = minEdge.bind((edge) => Optional.some(getXCenterOffSetOf(edge, spectrum))).getOr(minOffset);
    const centerMaxEdge = maxEdge.bind((edge) => Optional.some(getXCenterOffSetOf(edge, spectrum))).getOr(maxOffset);
    const args = {
        min: minX(detail),
        max: maxX(detail),
        range: xRange(detail),
        value,
        hasMinEdge: hasLEdge(detail),
        hasMaxEdge: hasREdge(detail),
        minBound: getMinXBounds(spectrum),
        minOffset,
        maxBound: getMaxXBounds(spectrum),
        maxOffset,
        centerMinEdge,
        centerMaxEdge
    };
    return SliderModel.findOffsetOfValue(args);
};
// find left offset for absolute positioning from a given value
const findPositionOfValue = (slider, spectrum, value, minEdge, maxEdge, detail) => {
    const offset = findOffsetOfValue(spectrum, detail, value, minEdge, maxEdge);
    return (getMinXBounds(spectrum) - getMinXBounds(slider)) + offset;
};
// update the position of the thumb from the slider's current value
const setPositionFromValue = (slider, thumb, detail, edges) => {
    const value = currentValue(detail);
    const pos = findPositionOfValue(slider, edges.getSpectrum(slider), value, edges.getLeftEdge(slider), edges.getRightEdge(slider), detail);
    const thumbRadius = Width.get(thumb.element) / 2;
    Css.set(thumb.element, 'left', (pos - thumbRadius) + 'px');
};
// Key Events
const onLeft = handleMovement(-1);
const onRight = handleMovement(1);
const onUp = Optional.none;
const onDown = Optional.none;
// Edge Click Actions
const edgeActions = {
    'top-left': Optional.none(),
    'top': Optional.none(),
    'top-right': Optional.none(),
    'right': Optional.some(EdgeActions.setToREdge),
    'bottom-right': Optional.none(),
    'bottom': Optional.none(),
    'bottom-left': Optional.none(),
    'left': Optional.some(EdgeActions.setToLEdge)
};
export { setValueFrom, setToMin, setToMax, findValueOfOffset, getValueFromEvent, findPositionOfValue, setPositionFromValue, onLeft, onRight, onUp, onDown, edgeActions };
//# sourceMappingURL=HorizontalModel.js.map