export function initializeCropBox({ imageRect, naturalWidth, naturalHeight, targetWidth, targetHeight, aspectRatio, metadata, }) {
    const scale = Math.min(imageRect.width / naturalWidth, imageRect.height / naturalHeight);
    const initialWidth = Math.min(targetWidth * scale, imageRect.width * 0.8);
    const initialHeight = initialWidth / aspectRatio;
    return {
        x: metadata?.x !== undefined
            ? metadata.x * scale
            : (imageRect.width - initialWidth) / 2,
        y: metadata?.y !== undefined
            ? metadata.y * scale
            : (imageRect.height - initialHeight) / 2,
        width: metadata?.width ? metadata.width * scale : initialWidth,
        height: metadata?.height ? metadata.height * scale : initialHeight,
    };
}
export function resizeCropBoxToViewport({ cropBox, previousImageRect, nextImageRect, naturalWidth, naturalHeight, }) {
    const oldScaleX = previousImageRect.width / naturalWidth;
    const oldScaleY = previousImageRect.height / naturalHeight;
    const naturalCropBox = {
        x: cropBox.x / oldScaleX,
        y: cropBox.y / oldScaleY,
        width: cropBox.width / oldScaleX,
        height: cropBox.height / oldScaleY,
    };
    const newScaleX = nextImageRect.width / naturalWidth;
    const newScaleY = nextImageRect.height / naturalHeight;
    const nextCropBox = {
        x: naturalCropBox.x * newScaleX,
        y: naturalCropBox.y * newScaleY,
        width: naturalCropBox.width * newScaleX,
        height: naturalCropBox.height * newScaleY,
    };
    nextCropBox.x = Math.max(0, Math.min(nextCropBox.x, nextImageRect.width - nextCropBox.width));
    nextCropBox.y = Math.max(0, Math.min(nextCropBox.y, nextImageRect.height - nextCropBox.height));
    return nextCropBox;
}
export function dragCropBox({ cropBox, imageRect, startX, startY, clientX, clientY, }) {
    const nextCropBox = { ...cropBox };
    const newX = clientX - startX;
    const newY = clientY - startY;
    nextCropBox.x = Math.max(0, Math.min(newX, imageRect.width - cropBox.width));
    nextCropBox.y = Math.max(0, Math.min(newY, imageRect.height - cropBox.height));
    return nextCropBox;
}
export function resizeCropBoxFromHandle({ startCropBox, resizeHandle, startX, clientX, imageRect, naturalWidth, naturalHeight, targetWidth, targetHeight, aspectRatio, }) {
    const deltaX = clientX - startX;
    const scaleX = imageRect.width / naturalWidth;
    const scaleY = imageRect.height / naturalHeight;
    const minWidth = Math.max(50, targetWidth * scaleX);
    const minHeight = Math.max(50, targetHeight * scaleY);
    let newBox = { ...startCropBox };
    switch (resizeHandle) {
        case "nw":
            newBox.width = Math.max(minWidth, startCropBox.width - deltaX);
            newBox.height = newBox.width / aspectRatio;
            newBox.x = startCropBox.x + (startCropBox.width - newBox.width);
            newBox.y = startCropBox.y + (startCropBox.height - newBox.height);
            break;
        case "ne":
            newBox.width = Math.max(minWidth, startCropBox.width + deltaX);
            newBox.height = newBox.width / aspectRatio;
            newBox.y = startCropBox.y + (startCropBox.height - newBox.height);
            break;
        case "sw":
            newBox.width = Math.max(minWidth, startCropBox.width - deltaX);
            newBox.height = newBox.width / aspectRatio;
            newBox.x = startCropBox.x + (startCropBox.width - newBox.width);
            break;
        case "se":
            newBox.width = Math.max(minWidth, startCropBox.width + deltaX);
            newBox.height = newBox.width / aspectRatio;
            break;
        default:
            break;
    }
    if (newBox.height < minHeight) {
        newBox.height = minHeight;
        newBox.width = newBox.height * aspectRatio;
        if (resizeHandle === "nw" || resizeHandle === "sw") {
            newBox.x = startCropBox.x + (startCropBox.width - newBox.width);
        }
        if (resizeHandle === "nw" || resizeHandle === "ne") {
            newBox.y = startCropBox.y + (startCropBox.height - newBox.height);
        }
    }
    if (newBox.x < 0) {
        newBox.x = 0;
    }
    if (newBox.y < 0) {
        newBox.y = 0;
    }
    if (newBox.x + newBox.width > imageRect.width) {
        newBox.x = imageRect.width - newBox.width;
        if (newBox.x < 0) {
            newBox.x = 0;
            newBox.width = imageRect.width;
            newBox.height = newBox.width / aspectRatio;
        }
    }
    if (newBox.y + newBox.height > imageRect.height) {
        newBox.y = imageRect.height - newBox.height;
        if (newBox.y < 0) {
            newBox.y = 0;
            newBox.height = imageRect.height;
            newBox.width = newBox.height * aspectRatio;
        }
    }
    return newBox;
}
export function toNaturalCropData({ cropBox, imageRect, naturalWidth, naturalHeight, }) {
    const scaleX = naturalWidth / imageRect.width;
    const scaleY = naturalHeight / imageRect.height;
    return {
        x: Math.round(cropBox.x * scaleX),
        y: Math.round(cropBox.y * scaleY),
        width: Math.round(cropBox.width * scaleX),
        height: Math.round(cropBox.height * scaleY),
    };
}
