import * as React from 'react';
import { useRef } from 'react';
function clamp(value, min, max) {
    return Math.min(Math.max(value, min), max);
}
const Direction = {
    east: 1 << 0,
    north: 1 << 3,
    south: 1 << 1,
    west: 1 << 2,
};
export default function ImageResizer({ editor, imageRef, maxWidth, onResizeEnd, onResizeStart, }) {
    const controlWrapperRef = useRef(null);
    const userSelect = useRef({
        priority: '',
        value: 'default',
    });
    const positioningRef = useRef({
        currentHeight: 0,
        currentWidth: 0,
        direction: 0,
        isResizing: false,
        ratio: 0,
        startHeight: 0,
        startWidth: 0,
        startX: 0,
        startY: 0,
    });
    const editorRootElement = editor.getRootElement();
    // Find max width, accounting for editor padding.
    const maxWidthContainer = maxWidth
        ? maxWidth
        : editorRootElement !== null
            ? editorRootElement.getBoundingClientRect().width - 20
            : 100;
    const maxHeightContainer = editorRootElement !== null ? editorRootElement.getBoundingClientRect().height - 20 : 100;
    const minWidth = 100;
    const minHeight = 100;
    const setStartCursor = (direction) => {
        const ew = direction === Direction.east || direction === Direction.west;
        const ns = direction === Direction.north || direction === Direction.south;
        const nwse = (direction & Direction.north && direction & Direction.west) ||
            (direction & Direction.south && direction & Direction.east);
        const cursorDir = ew ? 'ew' : ns ? 'ns' : nwse ? 'nwse' : 'nesw';
        if (editorRootElement !== null) {
            editorRootElement.style.setProperty('cursor', `${cursorDir}-resize`, 'important');
        }
        if (document.body !== null) {
            document.body.style.setProperty('cursor', `${cursorDir}-resize`, 'important');
            userSelect.current.value = document.body.style.getPropertyValue('-webkit-user-select');
            userSelect.current.priority = document.body.style.getPropertyPriority('-webkit-user-select');
            document.body.style.setProperty('-webkit-user-select', `none`, 'important');
        }
    };
    const setEndCursor = () => {
        if (editorRootElement !== null) {
            editorRootElement.style.setProperty('cursor', 'text');
        }
        if (document.body !== null) {
            document.body.style.setProperty('cursor', 'default');
            document.body.style.setProperty('-webkit-user-select', userSelect.current.value, userSelect.current.priority);
        }
    };
    const handlePointerMove = (event) => {
        const image = imageRef.current;
        const positioning = positioningRef.current;
        const isHorizontal = positioning.direction & (Direction.east | Direction.west);
        const isVertical = positioning.direction & (Direction.south | Direction.north);
        if (image !== null && positioning.isResizing) {
            // Corner cursor
            if (isHorizontal && isVertical) {
                let diff = Math.floor(positioning.startX - event.clientX);
                diff = positioning.direction & Direction.east ? -diff : diff;
                const width = clamp(positioning.startWidth + diff, minWidth, maxWidthContainer);
                const height = width / positioning.ratio;
                image.style.width = `${width}px`;
                image.style.height = `${height}px`;
                positioning.currentHeight = height;
                positioning.currentWidth = width;
            }
            else if (isVertical) {
                let diff = Math.floor(positioning.startY - event.clientY);
                diff = positioning.direction & Direction.south ? -diff : diff;
                const height = clamp(positioning.startHeight + diff, minHeight, maxHeightContainer);
                image.style.height = `${height}px`;
                positioning.currentHeight = height;
            }
            else {
                let diff = Math.floor(positioning.startX - event.clientX);
                diff = positioning.direction & Direction.east ? -diff : diff;
                const width = clamp(positioning.startWidth + diff, minWidth, maxWidthContainer);
                image.style.width = `${width}px`;
                positioning.currentWidth = width;
            }
        }
    };
    const handlePointerUp = () => {
        const image = imageRef.current;
        const positioning = positioningRef.current;
        const controlWrapper = controlWrapperRef.current;
        if (image !== null && controlWrapper !== null && positioning.isResizing) {
            const width = positioning.currentWidth;
            const height = positioning.currentHeight;
            positioning.startWidth = 0;
            positioning.startHeight = 0;
            positioning.ratio = 0;
            positioning.startX = 0;
            positioning.startY = 0;
            positioning.currentWidth = 0;
            positioning.currentHeight = 0;
            positioning.isResizing = false;
            controlWrapper.classList.remove('image-control-wrapper--resizing');
            setEndCursor();
            onResizeEnd(width, height);
            document.removeEventListener('pointermove', handlePointerMove);
            document.removeEventListener('pointerup', handlePointerUp);
        }
    };
    const handlePointerDown = (event, direction) => {
        if (!editor.isEditable()) {
            return;
        }
        const image = imageRef.current;
        const controlWrapper = controlWrapperRef.current;
        if (image !== null && controlWrapper !== null) {
            event.preventDefault();
            const { height, width } = image.getBoundingClientRect();
            const positioning = positioningRef.current;
            positioning.startWidth = width;
            positioning.startHeight = height;
            positioning.ratio = width / height;
            positioning.currentWidth = width;
            positioning.currentHeight = height;
            positioning.startX = event.clientX;
            positioning.startY = event.clientY;
            positioning.isResizing = true;
            positioning.direction = direction;
            setStartCursor(direction);
            onResizeStart();
            controlWrapper.classList.add('image-control-wrapper--resizing');
            image.style.height = `${height}px`;
            image.style.width = `${width}px`;
            document.addEventListener('pointermove', handlePointerMove);
            document.addEventListener('pointerup', handlePointerUp);
        }
    };
    return (React.createElement("div", { className: 'image-resizer-wrapper', ref: controlWrapperRef },
        React.createElement("div", { className: 'image-resizer image-resizer-n', onPointerDown: (event) => {
                handlePointerDown(event, Direction.north);
            } }),
        React.createElement("div", { className: 'image-resizer image-resizer-ne', onPointerDown: (event) => {
                handlePointerDown(event, Direction.north | Direction.east);
            } }),
        React.createElement("div", { className: 'image-resizer image-resizer-e', onPointerDown: (event) => {
                handlePointerDown(event, Direction.east);
            } }),
        React.createElement("div", { className: 'image-resizer image-resizer-se', onPointerDown: (event) => {
                handlePointerDown(event, Direction.south | Direction.east);
            } }),
        React.createElement("div", { className: 'image-resizer image-resizer-s', onPointerDown: (event) => {
                handlePointerDown(event, Direction.south);
            } }),
        React.createElement("div", { className: 'image-resizer image-resizer-sw', onPointerDown: (event) => {
                handlePointerDown(event, Direction.south | Direction.west);
            } }),
        React.createElement("div", { className: 'image-resizer image-resizer-w', onPointerDown: (event) => {
                handlePointerDown(event, Direction.west);
            } }),
        React.createElement("div", { className: 'image-resizer image-resizer-nw', onPointerDown: (event) => {
                handlePointerDown(event, Direction.north | Direction.west);
            } })));
}
//# sourceMappingURL=ImageResizer.js.map