"""Sets one paragraph in a column too narrow for a word in it, twice: above as it
comes, below cut to the column.

The Python twin of the `write_flow_break` example in Rust.

The paragraph and the two headings are held in `Words`, once per language, and
`HQF_PDF_LANG` picks which set is drawn. Each heading opens with the name the library
gives its setting, which is the same in every language.

Usage: python examples/write_flow_break.py [out.pdf] [font.ttf]
       HQF_PDF_LANG=fr python examples/write_flow_break.py
"""

from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path

import _language
import _licence
import _out

import hqf_pdf

# The payment reference the paragraph carries: one word to a line breaker, longer than
# the column it is put in, and the same in every language.
REFERENCE = "GB29NWBK60161331926819-2026-07-DEPOSIT"


@dataclass(frozen=True)
class Words:
    """Every word the page draws, in one language.

    What is not language stays out of it: the payment reference reads the same wherever
    the page is read, and each heading opens with the name the library gives the setting
    it stands over.
    """

    # The heading over the setting that leaves the long word whole.
    overflow: str
    # The heading over the setting that cuts it.
    breaking: str
    # The paragraph, cut where the reference goes into it.
    paragraph_before: str
    paragraph_after: str

    def paragraph(self) -> str:
        """Return the paragraph both settings are given, with the reference in it."""
        return f"{self.paragraph_before}{REFERENCE}{self.paragraph_after}"


# The page in English.
ENGLISH = Words(
    overflow="Overflow: the word is left whole, and runs past the edge.",
    breaking="Break: the word is cut after its last glyph that fits.",
    paragraph_before="Paid by bank transfer, reference ",
    paragraph_after=(
        ", to be matched against the purchase order before the accounts are closed."
    ),
)

# The page in French.
FRENCH = Words(
    overflow="Overflow : le mot reste entier et déborde du bord.",
    breaking="Break : le mot est coupé après son dernier glyphe qui tient.",
    paragraph_before="Réglé par virement, référence ",
    paragraph_after=", à rapprocher du bon de commande avant la clôture des comptes.",
)


# Every language the example is written in. A language is added by writing its own set
# of words and naming it here.
WORDS = {_language.ENGLISH: ENGLISH, _language.FRENCH: FRENCH}

COLUMN = 150.0

# The left edge of both columns. They are stacked rather than set side by side, so that
# the overflowing line runs out into the margin and not through the text of the other
# setting.
X = 80.0


def main() -> None:
    language = _language.from_environment()
    words = _language.words_of(WORDS, language)
    paragraph = words.paragraph()

    # A named file is written as named; the default one carries the language, so the two
    # languages do not overwrite each other in `tmp/`.
    out = _out.output_path(Path(_language.file_name("flow_break.pdf", language)).stem)

    document = hqf_pdf.Document()
    document.set_license(_licence.licensed())
    handle = document.add_font(hqf_pdf.Font.from_path(_out.font_path()))

    content = hqf_pdf.Content()

    for top, label, overlong in (
        (760.0, words.overflow, hqf_pdf.Overlong.Overflow),
        (620.0, words.breaking, hqf_pdf.Overlong.Break),
    ):
        heading = hqf_pdf.TextFlow(handle, 8.0)
        heading_lines = heading.break_lines(label, 400.0)
        heading.draw(content, heading_lines, X, top, 400.0)

        text_top = top - 20.0
        flow = hqf_pdf.TextFlow(handle, 11.0, leading=15.0, overlong=overlong)
        lines = flow.break_lines(paragraph, COLUMN)
        flow.draw(content, lines, X, text_top, COLUMN)

        # The column's edge, to show what each setting does about it.
        height = flow.height(lines)
        content.save_state()
        content.set_stroke(hqf_pdf.Rgb.gray(0.8))
        content.set_line_width(0.5)
        content.rect(X, text_top - height, COLUMN, height)
        content.stroke()
        content.restore_state()

    page = hqf_pdf.Page.a4()
    page.set_content(content)
    document.add_page(page)

    written = document.write(out)
    print(f"wrote {out}: {written} bytes")


if __name__ == "__main__":
    main()
