"use strict";
var __spreadArrays = (this && this.__spreadArrays) || function () {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.usePages = void 0;
var react_1 = require("react");
var layout_1 = require("../../utils/layout");
var tiles_1 = require("../../utils/tiles");
var getRawStartPoints = function (tiles, targetWidth, targetOffset, maxPosition) {
    if (tiles.length < 1) {
        return [];
    }
    var unboundedNextStart = layout_1.leftEdgeOffset(tiles[0]) - targetOffset.left;
    var nextStart = Math.min(unboundedNextStart, maxPosition);
    var projectedTargetRightEdge = nextStart + targetOffset.left + targetWidth;
    var offPageTiles = tiles.slice(1).filter(function (tile) { return layout_1.rightEdgeOffset(tile) > projectedTargetRightEdge; });
    return __spreadArrays([nextStart], getRawStartPoints(offPageTiles, targetWidth, targetOffset, maxPosition));
};
var getRawEndPoints = function (tiles, targetWidth, targetOffset, minPosition) {
    if (tiles.length < 1) {
        return [];
    }
    var unboundedNextEnd = layout_1.rightEdgeOffset(tiles[tiles.length - 1]) - targetOffset.left;
    var nextEnd = Math.max(unboundedNextEnd, minPosition);
    var projectedTargetLeftEdge = nextEnd + targetOffset.left - targetWidth;
    var nextPagePoint = projectedTargetLeftEdge - targetOffset.left;
    var offPageTiles = tiles.slice(0, -1).filter(function (tile) { return layout_1.leftEdgeOffset(tile) < projectedTargetLeftEdge; });
    return __spreadArrays(getRawEndPoints(offPageTiles, targetWidth, targetOffset, minPosition), [nextPagePoint]);
};
var getScaledWeightedAverage = function (list1, list2, leftRatio, rightRatio) {
    if (list1.length === 0) {
        return [];
    }
    else if (list1.length === 1) {
        var ratio_1 = (leftRatio + rightRatio) / 2;
        return [list1[0] * (1 - ratio_1) + list2[0] * ratio_1];
    }
    var total = list1.length - 1;
    var progress = function (n) { return n / total; };
    var ratio = function (n) { return (1 - progress(n)) * leftRatio + progress(n) * rightRatio; };
    return list1.map(function (item1, i) { return (item1 * (1 - ratio(i)) + list2[i] * ratio(i)); });
};
var getCurrentPage = function (currentPosition, pageSplitPoints) {
    var pageIndex = pageSplitPoints.findIndex(function (splitPoint) { return currentPosition < splitPoint; });
    return pageIndex === -1 ? pageSplitPoints.length + 1 : pageIndex + 1;
};
var calculatePagePoints = function (container) {
    var tiles = tiles_1.getTiles(container);
    var targetOffset = layout_1.getTargetZoneOffsets(container, tiles);
    var targetZoneWidth = container.clientWidth - targetOffset.left - targetOffset.right;
    if (targetZoneWidth === 0) {
        return undefined;
    }
    var maxPosition = container.scrollWidth - container.clientWidth;
    var rawStartPoints = getRawStartPoints(tiles, targetZoneWidth, targetOffset, maxPosition);
    var minPosition = targetZoneWidth;
    var rawEndPoints = getRawEndPoints(tiles, targetZoneWidth, targetOffset, minPosition);
    var pagePoints = getScaledWeightedAverage(rawEndPoints.slice(1), rawStartPoints.slice(0, -1), 0, .5);
    return pagePoints;
};
var calculatePages = function (container, pagePoints) {
    if (pagePoints === undefined) {
        return { total: 0, current: 0 };
    }
    var numberOfPages = pagePoints.length + 1;
    var currentPosition = layout_1.scrollPosition(container);
    var currentPage = getCurrentPage(currentPosition, pagePoints);
    return {
        total: numberOfPages,
        current: currentPage,
    };
};
exports.usePages = function (containerRef) {
    var _a = react_1.useState(undefined), pagePoints = _a[0], setPagePoints = _a[1];
    var _b = react_1.useState({ current: 0, total: 0 }), pages = _b[0], setPages = _b[1];
    var updatePagePoints = function () {
        var newPagePoints = containerRef.current
            ? calculatePagePoints(containerRef.current)
            : undefined;
        setPagePoints(newPagePoints);
        return newPagePoints;
    };
    var updatePages = function (pagePnts) {
        if (!containerRef.current)
            return;
        var container = containerRef.current;
        var newPages = calculatePages(container, pagePnts);
        if (newPages.current !== pages.current || newPages.total !== pages.total) {
            setPages(newPages);
        }
    };
    var onLayoutChange = function () {
        var newPagePoints = updatePagePoints();
        updatePages(newPagePoints);
    };
    var onScroll = function () {
        updatePages(pagePoints);
    };
    return [pages, {
            onLayoutChange: onLayoutChange,
            onScroll: onScroll
        }];
};
