"""Build the two-column PDF fixtures used in BookTranslator's
"How to Translate a Multi-Column PDF" article.

Each paragraph starts with a marker (P1..P8) so the reading order of any
text extraction can be checked mechanically with check_reading_order.py.

The first two files share the same page image but write text in a
different order inside the PDF content stream. The third is a control
without the figure box at the top of the left column:

  two-column-stream-logical.pdf    left column, then right column
  two-column-stream-rowwise.pdf    left and right lines interleaved row by row
  two-column-no-figure-rowwise.pdf row-by-row storage, no figure box

Requires: reportlab (tested with 4.2.5).
Usage:    python make_two_column_fixture.py
"""
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.pdfbase.pdfmetrics import stringWidth

W, H = letter
MARGIN = 54
GUTTER = 22
COL_W = (W - 2 * MARGIN - GUTTER) / 2
FONT, SIZE, LEAD = "Times-Roman", 10.5, 13.5

LEFT = [
    "P1 The river authority opened its spring survey on the first dry morning of April, when the water had dropped far enough to expose the old stone weirs along the lower reach.",
    "P2 Survey teams measure each weir twice: once from the bank with a laser level, and once from a small boat that records depth every two meters across the channel.",
    "P3 Where the two measurements disagree by more than five centimeters, the team marks the weir for a diver inspection before the summer irrigation season begins.",
]
RIGHT = [
    "P4 This year the diver inspections found loose capstones on three weirs, which explains why the bank readings drifted while the boat readings stayed stable.",
    "P5 Repairs are scheduled in the order the water allows: the shallowest weirs first, then the two deep weirs near the mill once the flow falls below the summer threshold.",
    "P6 Farmers downstream can follow the repair calendar on the notice board at the lock house, which is updated each Friday after the engineers meet.",
]
SPAN = "P7 Note for all readers: the lower towpath stays closed until the final weir is repaired."
FOOT = "P8 Footnote: depth readings are rounded to the nearest centimeter in the published summary."
CAPTION = "Figure 1. Stone weir cross-section."


def wrap(text, width):
    lines, line = [], ""
    for word in text.split():
        trial = (line + " " + word).strip()
        if stringWidth(trial, FONT, SIZE) <= width:
            line = trial
        else:
            lines.append(line)
            line = word
    lines.append(line)
    return lines


def column_lines(paragraphs, x, top):
    out, y = [], top
    for para in paragraphs:
        for text in wrap(para, COL_W):
            out.append((x, y, text))
            y -= LEAD
        y -= LEAD * 0.6
    return out


def build(path, order, figure=True):
    c = canvas.Canvas(path, pagesize=letter, invariant=1)
    c.setTitle("Two-column reading-order fixture")
    c.setFont("Times-Bold", 18)
    c.drawString(MARGIN, H - 72, "Lower River Weir Survey: Spring Report")
    c.setFont("Times-Italic", 9)
    c.drawRightString(W - MARGIN, 36, "Page 1")

    top = H - 110
    if figure:
        fig_h = 70
        c.rect(MARGIN, top - fig_h, COL_W, fig_h)
        c.setFont("Times-Italic", 9)
        c.drawString(MARGIN, top - fig_h - 12, CAPTION)
        left = column_lines(LEFT, MARGIN, top - fig_h - 34)
    else:
        left = column_lines(LEFT, MARGIN, top)
    right = column_lines(RIGHT, MARGIN + COL_W + GUTTER, top)

    c.setFont(FONT, SIZE)
    if order == "logical":
        stream = left + right
    else:
        stream = []
        for i in range(max(len(left), len(right))):
            stream += left[i:i + 1] + right[i:i + 1]
    for x, y, text in stream:
        c.drawString(x, y, text)

    low = min(y for _, y, _ in left + right) - 30
    c.setFont("Times-Bold", SIZE)
    c.drawString(MARGIN, low, SPAN)
    c.setFont(FONT, 8.5)
    c.drawString(MARGIN, 60, FOOT)
    c.save()


if __name__ == "__main__":
    build("two-column-stream-logical.pdf", "logical")
    build("two-column-stream-rowwise.pdf", "rowwise")
    build("two-column-no-figure-rowwise.pdf", "rowwise", figure=False)
