"""Sets one justified paragraph in a narrow column twice: above without its soft
hyphens, below with them, so the breaks and the hyphens they draw can be seen
against the loose lines above.

The Python twin of the `write_soft_hyphen` example in Rust. The text carries soft
hyphens (U+00AD) inside its long words and a no-break space (U+00A0) inside the
figure "1 200 EUR". The upper setting is the same text with the soft hyphens taken
out, so only the breaking differs between the two; the no-break space holds the
figure together in both.

The paragraph and the two headings are held in `Words`, once per language, and
`HQF_PDF_LANG` picks which set is drawn. Every language has to carry its own soft
hyphens, in words its own spelling allows to break: a paragraph translated without
them would show nothing.

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

from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path

import _language
import _licence
import _out

import hqf_pdf


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

    # What stands over the setting whose soft hyphens have been taken out.
    without: str
    # What stands over the setting that keeps them.
    with_: str
    # The paragraph, with soft hyphens marking where its long words may break and a
    # no-break space inside the figure so it never falls across two lines. Each language
    # marks the breaks its own spelling allows.
    hyphenated: str


# The page in English.
ENGLISH = Words(
    without="Without soft hyphens: justify opens the lines to fill the column.",
    with_="With soft hyphens: the long words break, each break drawing a hyphen.",
    hyphenated=(
        "Our inter­national sub­scription, billed at "
        "1 200 EUR, covers unlimited docu­ments, prior­ity "
        "support and quarterly state­ments."
    ),
)

# The page in French.
FRENCH = Words(
    without=(
        ("Sans césures conditionnelles : la justification écarte les mots pour remplir"
         " la colonne.")
    ),
    with_=(
        ("Avec césures conditionnelles : les mots longs se coupent, chaque coupure "
         "ajoutant un trait d’union.")
    ),
    hyphenated=(
        ("Notre abonne­ment inter­national, factu­ré 1 200 EUR, comprend un nombre "
         "illi­mité de docu­ments, une assis­tance prio­ritaire et des rele­vés "
         "trimes­triels.")
    ),
)

# The page in Dutch.
DUTCH = Words(
    without="Zonder zachte afbreekstreepjes: uitvullen trekt de regels open om de kolom te vullen.",
    with_="Met zachte afbreekstreepjes: de lange woorden breken, en elke breuk tekent een streepje.",
    hyphenated=(
        "Ons inter­nationale abonne­ment, gefac­tureerd tegen EUR 1.200, omvat "
        "onbe­perkte docu­menten, voorrangs­ondersteuning en driemaan­delijkse "
        "overzichten."
    ),
)

# The page in Portuguese.
PORTUGUESE = Words(
    without="Sem hífenes condicionais: justificar abre as linhas para encher a coluna.",
    with_="Com hífenes condicionais: as palavras longas partem-se, e cada corte desenha um hífen.",
    hyphenated=(
        "A nossa assi­natura inter­nacional, faturada a 1 200 EUR, cobre docu­mentos "
        "ilimi­tados, assis­tência priori­tária e extratos trimes­trais."
    ),
)

# The page in Italian.
ITALIAN = Words(
    without="Senza trattini facoltativi: la giustificazione allarga le righe per riempire la colonna.",
    with_="Con trattini facoltativi: le parole lunghe si spezzano, e ogni taglio disegna un trattino.",
    hyphenated=(
        "Il nostro abbona­mento inter­nazionale, fatturato a 1.200 EUR, copre "
        "docu­menti illimi­tati, assi­stenza priori­taria ed estratti trime­strali."
    ),
)

# The page in Spanish.
SPANISH = Words(
    without="Sin guiones condicionales: justificar abre las líneas para llenar la columna.",
    with_="Con guiones condicionales: las palabras largas se cortan, y cada corte dibuja un guion.",
    hyphenated=(
        "Nuestra sus­crip­ción inter­nacional, factu­rada a 1 200 EUR, cubre "
        "docu­mentos ilimi­tados, asis­tencia prio­ritaria y extractos trimes­trales."
    ),
)

# The page in German.
GERMAN = Words(
    without="Ohne weiche Trennstriche: Der Blocksatz öffnet die Zeilen, um die Spalte zu füllen.",
    with_="Mit weichen Trennstrichen: Die langen Wörter brechen, jeder Bruch zeichnet einen Bindestrich.",
    hyphenated=(
        "Unser inter­nationales Abon­nement, abge­rechnet mit 1 200 EUR, umfasst "
        "unbe­grenzte Doku­mente, bevor­zugten Support und viertel­jährliche "
        "Konto­auszüge."
    ),
)


# 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, _language.GERMAN: GERMAN, _language.SPANISH: SPANISH, _language.ITALIAN: ITALIAN, _language.PORTUGUESE: PORTUGUESE, _language.DUTCH: DUTCH}

# The column both settings are broken to, narrow enough that the long words reach its
# edge.
COLUMN = 150.0

# The left edge of both settings, stacked one above the other.
X = 80.0


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

    # 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("soft_hyphen.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()

    # The upper setting is the same text with its soft hyphens removed, so the two
    # panels differ only in whether the words may break.
    plain = words.hyphenated.replace("­", "")

    for top, label, paragraph in (
        (760.0, words.without, plain),
        (600.0, words.with_, words.hyphenated),
    ):
        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, align=hqf_pdf.Align.Justify)
        lines = flow.break_lines(paragraph, COLUMN)
        flow.draw(content, lines, X, text_top, COLUMN)

        # The column's edge, so the lines can be read against 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()
