"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WindowModal = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const re_resizable_1 = require("re-resizable");
const useDraggable_1 = tslib_1.__importDefault(require("../utils/useDraggable"));
const UIHelper_1 = require("../../View/UIHelper");
const react_dom_1 = require("react-dom");
const useStacking_1 = require("./useStacking");
let portalElement;
const ensurePortalElement = () => {
    if (!(0, UIHelper_1.isBrowserDocumentAvailable)()) {
        return;
    }
    if (portalElement) {
        return;
    }
    portalElement = document.createElement('div');
    portalElement.classList.add('ab-cmp-modal-window');
    document.body.appendChild(portalElement);
};
const normalizeTopLeft = (position) => (position < 0 ? 0 : position);
const getResizePositionDelta = (direction, delta) => {
    const positionDelta = { x: 0, y: 0 };
    const left = -delta.width;
    const top = -delta.height;
    const directions = ['top', 'left', 'topLeft', 'bottomLeft', 'topRight'];
    if (directions.indexOf(direction) !== -1) {
        if (direction === 'bottomLeft') {
            positionDelta.x += left;
        }
        else if (direction === 'topRight') {
            positionDelta.y += top;
        }
        else {
            positionDelta.x += left;
            positionDelta.y += top;
        }
        return positionDelta;
    }
    return null;
};
const WindowModal = (props) => {
    ensurePortalElement();
    const positionDeltaRef = React.useRef(null);
    const normalizedPosition = {
        x: normalizeTopLeft(props.position?.x),
        y: normalizeTopLeft(props.position?.y),
    };
    const positionRef = React.useRef(normalizedPosition);
    const stacking = (0, useStacking_1.useStacking)();
    /**
     * This is needed because the function called in onDrop is saved when
     * it gets attached to the DOM element event handler.
     * This handler changes only when the underlying node changes.
     */
    positionRef.current = normalizedPosition;
    const style = {
        zIndex: stacking.zIndex,
        position: 'absolute',
        left: normalizedPosition.x,
        top: normalizedPosition.y,
    };
    const handleDrop = (dx, dy) => {
        const newPosition = {
            x: positionRef.current.x + dx,
            y: positionRef.current.y + dy,
        };
        props.onChange({
            position: newPosition,
            size: props.size,
        });
    };
    const { targetRef, applyTransform } = (0, useDraggable_1.default)({
        handleSelector: props.handleSelector,
        onDrop: handleDrop,
    });
    const handleResizeStop = (event, direction, elementRef, delta) => {
        let newPosition = normalizedPosition;
        if (positionDeltaRef.current) {
            newPosition = {
                x: normalizedPosition.x + positionDeltaRef.current.x,
                y: normalizedPosition.y + positionDeltaRef.current.y,
            };
            positionDeltaRef.current = null;
            applyTransform(0, 0);
        }
        const newSize = {
            width: props.size.width + delta.width,
            height: props.size.height + delta.height,
        };
        props.onChange({
            position: newPosition,
            size: newSize,
        });
    };
    const handleResize = React.useCallback((event, direction, elementRef, delta) => {
        const positionDelta = getResizePositionDelta(direction, delta);
        if (positionDelta) {
            positionDeltaRef.current = positionDelta;
            applyTransform(positionDelta.x, positionDelta.y);
        }
    }, []);
    const ResizableCmp = re_resizable_1.Resizable;
    return (0, react_dom_1.createPortal)(React.createElement("div", { style: style, 
        //@ts-ignore
        ref: targetRef, onMouseDown: stacking.bringInFront },
        React.createElement(ResizableCmp, { minWidth: props.minWidth, minHeight: props.minHeight, onResizeStop: handleResizeStop, onResize: handleResize, bounds: "window", defaultSize: {
                width: props.size.width,
                height: props.size.height,
            } }, props.children)), portalElement);
};
exports.WindowModal = WindowModal;
