import { Adt, Arr, Optional } from '@ephox/katamari';
import { SugarPosition } from '@ephox/sugar';
/*
 * origin: the position (without scroll) of the offset parent
 * scroll: the scrolling position of the window
 *
 * fixed: the fixed coordinates to show for css
 * offset: the absolute coordinates to show for css when inside an offset parent
 * absolute: the absolute coordinates to show before considering the offset parent
 */
const adt = Adt.generate([
    { offset: ['x', 'y'] },
    { absolute: ['x', 'y'] },
    { fixed: ['x', 'y'] }
]);
const subtract = (change) => (point) => point.translate(-change.left, -change.top);
const add = (change) => (point) => point.translate(change.left, change.top);
const transform = (changes) => (x, y) => Arr.foldl(changes, (rest, f) => f(rest), SugarPosition(x, y));
const asFixed = (coord, scroll, origin) => coord.fold(
// offset to fixed
transform([add(origin), subtract(scroll)]), 
// absolute to fixed
transform([subtract(scroll)]), 
// fixed to fixed
transform([]));
const asAbsolute = (coord, scroll, origin) => coord.fold(
// offset to absolute
transform([add(origin)]), 
// absolute to absolute
transform([]), 
// fixed to absolute
transform([add(scroll)]));
const asOffset = (coord, scroll, origin) => coord.fold(
// offset to offset
transform([]), 
// absolute to offset
transform([subtract(origin)]), 
// fixed to offset
transform([add(scroll), subtract(origin)]));
const toString = (coord) => coord.fold((x, y) => 'offset(' + x + ', ' + y + ')', (x, y) => 'absolute(' + x + ', ' + y + ')', (x, y) => 'fixed(' + x + ', ' + y + ')');
const withinRange = (coord1, coord2, xRange, yRange, scroll, origin) => {
    const a1 = asAbsolute(coord1, scroll, origin);
    const a2 = asAbsolute(coord2, scroll, origin);
    // eslint-disable-next-line no-console
    // console.log(`a1.left: ${a1.left}, a2.left: ${a2.left}, leftDelta: ${a1.left - a2.left}, xRange: ${xRange}, lD <= xRange: ${Math.abs(a1.left - a2.left) <= xRange}`);
    // console.log(`a1.top: ${a1.top}, a2.top: ${a2.top}, topDelta: ${a1.top - a2.top}, yRange: ${yRange}, lD <= xRange: ${Math.abs(a1.top - a2.top) <= yRange}`);
    return Math.abs(a1.left - a2.left) <= xRange &&
        Math.abs(a1.top - a2.top) <= yRange;
};
const getDeltas = (coord1, coord2, xRange, yRange, scroll, origin) => {
    const a1 = asAbsolute(coord1, scroll, origin);
    const a2 = asAbsolute(coord2, scroll, origin);
    const left = Math.abs(a1.left - a2.left);
    const top = Math.abs(a1.top - a2.top);
    return SugarPosition(left, top);
};
const toStyles = (coord, scroll, origin) => {
    const stylesOpt = coord.fold((x, y) => ({ position: Optional.some('absolute'), left: Optional.some(x + 'px'), top: Optional.some(y + 'px') }), // offset
    (x, y) => ({ position: Optional.some('absolute'), left: Optional.some((x - origin.left) + 'px'), top: Optional.some((y - origin.top) + 'px') }), // absolute
    (x, y) => ({ position: Optional.some('fixed'), left: Optional.some(x + 'px'), top: Optional.some(y + 'px') }) // fixed
    );
    return { right: Optional.none(), bottom: Optional.none(), ...stylesOpt };
};
const translate = (coord, deltaX, deltaY) => coord.fold((x, y) => offset(x + deltaX, y + deltaY), (x, y) => absolute(x + deltaX, y + deltaY), (x, y) => fixed(x + deltaX, y + deltaY));
const absorb = (partialCoord, originalCoord, scroll, origin) => {
    const absorbOne = (stencil, nu) => (optX, optY) => {
        const original = stencil(originalCoord, scroll, origin);
        return nu(optX.getOr(original.left), optY.getOr(original.top));
    };
    return partialCoord.fold(absorbOne(asOffset, offset), absorbOne(asAbsolute, absolute), absorbOne(asFixed, fixed));
};
const offset = adt.offset;
const absolute = adt.absolute;
const fixed = adt.fixed;
export { offset, absolute, fixed, asFixed, asAbsolute, asOffset, withinRange, getDeltas, toStyles, translate, absorb, toString };
//# sourceMappingURL=DragCoord.js.map