// SPDX-FileCopyrightText: 2026 Brent Daignault
// SPDX-License-Identifier: GPL-3.0-or-later

import Foundation

/// The pair of logical pages placed on one side of one physical sheet.
struct SheetSlot {
    var leftPage: Int
    var rightPage: Int
}

/// Saddle-stitch imposition, short-edge flip.
///
/// N (padded logical page count) must be a multiple of 4.  For sheet `s`
/// (0-based):
///   Front: LEFT = N - 2s      RIGHT = 2s + 1
///   Back:  LEFT = 2s + 2      RIGHT = N - 2s - 1
///
/// Short-edge flip means the back side needs no rotation — left stays left,
/// right stays right, on both sides of the sheet.
///
/// Unlike the original C version (which mapped logical → physical, suited to
/// libharu's retained-page model), this is expressed physical → logical,
/// which is what a streaming PDF writer like Core Graphics needs: you must
/// know everything that belongs on a physical page before you open it,
/// because once a page is closed its content stream is finalised.
enum Imposition {
    static func slot(sheet s: Int, side: Int, N: Int) -> SheetSlot {
        if side == 0 {
            return SheetSlot(leftPage: N - 2 * s, rightPage: 2 * s + 1)
        } else {
            return SheetSlot(leftPage: 2 * s + 2, rightPage: N - 2 * s - 1)
        }
    }

    /// Rounds `contentPages` up to the next multiple of 4.
    static func paddedPageCount(contentPages: Int) -> Int {
        var n = contentPages
        while n % 4 != 0 { n += 1 }
        return n
    }
}
