import { Fun, Optional } from '@ephox/katamari';
import { Css, Height } 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 { getMaxYBounds, getMinYBounds, getYCenterOffSetOf, getYScreenRange } from './SliderOffsets';
import { currentValue, hasBEdge, hasTEdge, maxY, minY, rounded, snap, snapStart, step, yRange } from './SliderValues';
// fire slider change event with y value
const fireSliderChange = (spectrum, value) => {
    AlloyTriggers.emitWith(spectrum, ModelCommon.sliderChangeEvent(), { value });
};
// find the value of the y offset of where the mouse was clicked from the model.
const findValueOfOffset = (spectrum, detail, top) => {
    const args = {
        min: minY(detail),
        max: maxY(detail),
        range: yRange(detail),
        value: top,
        step: step(detail),
        snap: snap(detail),
        snapStart: snapStart(detail),
        rounded: rounded(detail),
        hasMinEdge: hasTEdge(detail),
        hasMaxEdge: hasBEdge(detail),
        minBound: getMinYBounds(spectrum),
        maxBound: getMaxYBounds(spectrum),
        screenRange: getYScreenRange(spectrum)
    };
    return SliderModel.findValueOf(args);
};
// find the value and fire a slider change event, returning the value
const setValueFrom = (spectrum, detail, value) => {
    const yValue = findValueOfOffset(spectrum, detail, value);
    const sliderVal = yValue;
    fireSliderChange(spectrum, sliderVal);
    return yValue;
};
// fire a slider change event with the minimum value
const setToMin = (spectrum, detail) => {
    const min = minY(detail);
    fireSliderChange(spectrum, min);
};
// fire a slider change event with the maximum value
const setToMax = (spectrum, detail) => {
    const max = maxY(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 yValue = f(currentValue(detail), minY(detail), maxY(detail), step(detail));
    fireSliderChange(spectrum, yValue);
    return Optional.some(yValue);
};
const handleMovement = (direction) => (spectrum, detail) => moveBy(direction, spectrum, detail).map(Fun.always);
// get y offset from event
const getValueFromEvent = (simulatedEvent) => {
    const pos = ModelCommon.getEventSource(simulatedEvent);
    return pos.map((p) => {
        return p.top;
    });
};
// find the y offset of a given value from the model
const findOffsetOfValue = (spectrum, detail, value, minEdge, maxEdge) => {
    const minOffset = 0;
    const maxOffset = getYScreenRange(spectrum);
    const centerMinEdge = minEdge.bind((edge) => Optional.some(getYCenterOffSetOf(edge, spectrum))).getOr(minOffset);
    const centerMaxEdge = maxEdge.bind((edge) => Optional.some(getYCenterOffSetOf(edge, spectrum))).getOr(maxOffset);
    const args = {
        min: minY(detail),
        max: maxY(detail),
        range: yRange(detail),
        value,
        hasMinEdge: hasTEdge(detail),
        hasMaxEdge: hasBEdge(detail),
        minBound: getMinYBounds(spectrum),
        minOffset,
        maxBound: getMaxYBounds(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 (getMinYBounds(spectrum) - getMinYBounds(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.getTopEdge(slider), edges.getBottomEdge(slider), detail);
    const thumbRadius = Height.get(thumb.element) / 2;
    Css.set(thumb.element, 'top', (pos - thumbRadius) + 'px');
};
// Key Events
const onLeft = Optional.none;
const onRight = Optional.none;
const onUp = handleMovement(-1);
const onDown = handleMovement(1);
// Edge Click Actions
const edgeActions = {
    'top-left': Optional.none(),
    'top': Optional.some(EdgeActions.setToTEdge),
    'top-right': Optional.none(),
    'right': Optional.none(),
    'bottom-right': Optional.none(),
    'bottom': Optional.some(EdgeActions.setToBEdge),
    'bottom-left': Optional.none(),
    'left': Optional.none()
};
export { setValueFrom, setToMin, setToMax, findValueOfOffset, getValueFromEvent, findPositionOfValue, setPositionFromValue, onLeft, onRight, onUp, onDown, edgeActions };
//# sourceMappingURL=VerticalModel.js.map