/**
 * DevExtreme (esm/exporter/jspdf/common/rows_splitting.js)
 * Version: 22.1.7 (build 23032-0308)
 * Build date: Wed Feb 01 2023
 *
 * Copyright (c) 2012 - 2023 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
import _extends from "@babel/runtime/helpers/esm/extends";
import {
    isDefined
} from "../../../core/utils/type";
import {
    getPageWidth,
    getPageHeight
} from "./pdf_utils";
import {
    roundToThreeDecimals
} from "./draw_utils";

function convertToCellsArray(rows) {
    return [].concat.apply([], rows.map(rowInfo => rowInfo.cells.filter(cell => !isDefined(cell.pdfCell.isMerged)).map(cellInfo => _extends({}, cellInfo.pdfCell._rect, {
        sourceCellInfo: _extends({}, cellInfo.pdfCell, {
            gridCell: cellInfo.gridCell
        })
    }))))
}

function splitByPages(doc, rowsInfo, options, onSeparateRectHorizontally, onSeparateRectVertically) {
    if (0 === rowsInfo.length) {
        return [
            []
        ]
    }
    var maxBottomRight = {
        x: getPageWidth(doc) - options.margin.right,
        y: getPageHeight(doc) - options.margin.bottom
    };
    var headerRows = rowsInfo.filter(r => "header" === r.rowType);
    var headerHeight = headerRows.reduce((accumulator, row) => accumulator + row.height, 0);
    var verticallyPages = splitRectsByPages(convertToCellsArray(rowsInfo), options.margin.top, "y", "h", (pagesLength, currentCoordinate) => {
        var additionalHeight = pagesLength > 0 && options.repeatHeaders ? headerHeight : 0;
        return roundToThreeDecimals(currentCoordinate + additionalHeight) <= roundToThreeDecimals(maxBottomRight.y)
    }, (rect, currentPageMaxRectCoordinate, currentPageRects, rectsToSplit) => {
        var args = {
            sourceRect: rect,
            topRect: {
                x: rect.x,
                y: rect.y,
                w: rect.w,
                h: currentPageMaxRectCoordinate - rect.y
            },
            bottomRect: {
                x: rect.x,
                y: currentPageMaxRectCoordinate,
                w: rect.w,
                h: rect.h - (currentPageMaxRectCoordinate - rect.y)
            }
        };
        onSeparateRectVertically(args);
        currentPageRects.push(args.topRect);
        rectsToSplit.push(args.bottomRect)
    });
    if (options.repeatHeaders) {
        for (var i = 1; i < verticallyPages.length; i++) {
            verticallyPages[i].forEach(rect => rect.y += headerHeight);
            var headerCells = convertToCellsArray(headerRows);
            headerCells.forEach(cell => {
                cell.y -= options.topLeft.y
            });
            verticallyPages[i] = [...headerCells, ...verticallyPages[i]]
        }
    }
    var pageIndex = 0;
    while (pageIndex < verticallyPages.length) {
        var horizontallyPages = splitRectsByPages(verticallyPages[pageIndex], options.margin.left, "x", "w", (pagesLength, currentCoordinate) => roundToThreeDecimals(currentCoordinate) <= roundToThreeDecimals(maxBottomRight.x), (rect, currentPageMaxRectCoordinate, currentPageRects, rectsToSplit) => {
            var args = {
                sourceRect: rect,
                leftRect: {
                    x: rect.x,
                    y: rect.y,
                    w: currentPageMaxRectCoordinate - rect.x,
                    h: rect.h
                },
                rightRect: {
                    x: currentPageMaxRectCoordinate,
                    y: rect.y,
                    w: rect.w - (currentPageMaxRectCoordinate - rect.x),
                    h: rect.h
                }
            };
            onSeparateRectHorizontally(args);
            currentPageRects.push(args.leftRect);
            rectsToSplit.push(args.rightRect)
        });
        if (horizontallyPages.length > 1) {
            verticallyPages.splice(pageIndex, 1, ...horizontallyPages);
            pageIndex += horizontallyPages.length
        } else {
            pageIndex += 1
        }
    }
    return verticallyPages.map(rects => rects.map(rect => _extends({}, rect.sourceCellInfo, {
        _rect: rect
    })))
}

function splitRectsByPages(rects, marginValue, coordinate, dimension, checkPredicate, onSeparateCallback) {
    var pages = [];
    var rectsToSplit = [...rects];
    var _loop = function() {
        var currentPageMaxRectCoordinate = 0;
        var currentPageRects = rectsToSplit.filter(rect => {
            var currentRectCoordinate = rect[coordinate] + rect[dimension];
            if (checkPredicate(pages.length, currentRectCoordinate)) {
                if (currentPageMaxRectCoordinate <= currentRectCoordinate) {
                    currentPageMaxRectCoordinate = currentRectCoordinate
                }
                return true
            } else {
                return false
            }
        });
        var rectsToSeparate = rectsToSplit.filter(rect => {
            var currentRectLeft = rect[coordinate];
            var currentRectRight = rect[coordinate] + rect[dimension];
            if (currentRectLeft < currentPageMaxRectCoordinate && currentPageMaxRectCoordinate < currentRectRight) {
                return true
            }
        });
        rectsToSeparate.forEach(rect => {
            onSeparateCallback(rect, currentPageMaxRectCoordinate, currentPageRects, rectsToSplit);
            var index = rectsToSplit.indexOf(rect);
            if (-1 !== index) {
                rectsToSplit.splice(index, 1)
            }
        });
        currentPageRects.forEach(rect => {
            var index = rectsToSplit.indexOf(rect);
            if (-1 !== index) {
                rectsToSplit.splice(index, 1)
            }
        });
        rectsToSplit.forEach(rect => {
            rect[coordinate] = isDefined(currentPageMaxRectCoordinate) ? rect[coordinate] - currentPageMaxRectCoordinate + marginValue : rect[coordinate]
        });
        if (currentPageRects.length > 0) {
            pages.push(currentPageRects)
        } else {
            pages.push(rectsToSplit);
            return "break"
        }
    };
    while (rectsToSplit.length > 0) {
        var _ret = _loop();
        if ("break" === _ret) {
            break
        }
    }
    return pages
}
export {
    splitByPages
};
