"""Lays a paragraph out four ways, to see the alignment.

The Python twin of the `write_flow` example in Rust. The paragraph is held in `Words`,
once per language, and `HQF_PDF_LANG` picks which one is laid out.

Usage: python examples/write_flow.py [out.pdf] [font.ttf]
       HQF_PDF_LANG=fr python examples/write_flow.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 lays out, in one language."""

    # The paragraph the four alignments are shown on.
    paragraph: str


# The page in English.
ENGLISH = Words(
    paragraph=(
        "This library lays text out by breaking a paragraph into lines that fit a "
        "column, then placing each line according to an alignment. The same words are "
        "shown below flush left, flush right, centred, and justified, so the "
        "difference between them is plain to see at a glance."
    )
)

# The page in French.
FRENCH = Words(
    paragraph=(
        ("Cette bibliothèque met le texte en page en découpant un paragraphe en lignes"
         " qui tiennent dans une colonne, puis en plaçant chaque ligne selon un "
         "alignement. Les mêmes mots sont repris ci-dessous alignés à gauche, alignés "
         "à droite, centrés, puis justifiés, pour que la différence entre eux se voie "
         "d’un seul coup d’œil.")
    )
)

# The page in Dutch.
DUTCH = Words(
    paragraph=(
        "Deze bibliotheek zet tekst door een alinea te breken in regels die in een "
        "kolom passen en elke regel daarna volgens een uitlijning te plaatsen. "
        "Dezelfde woorden staan hieronder links uitgelijnd, rechts uitgelijnd, "
        "gecentreerd en uitgevuld, zodat het verschil in één oogopslag te zien is."
    )
)

# The page in Portuguese.
PORTUGUESE = Words(
    paragraph=(
        "Esta biblioteca compõe o texto partindo um parágrafo em linhas que cabem "
        "numa coluna e colocando depois cada linha segundo um alinhamento. As mesmas "
        "palavras aparecem abaixo alinhadas à esquerda, à direita, centradas e "
        "justificadas, para que a diferença se veja num relance."
    )
)

# The page in Italian.
ITALIAN = Words(
    paragraph=(
        "Questa libreria compone il testo spezzando un paragrafo in righe che stanno "
        "in una colonna, poi collocando ogni riga secondo un allineamento. Le stesse "
        "parole sono mostrate qui sotto allineate a sinistra, a destra, centrate e "
        "giustificate, così la differenza si vede a colpo d’occhio."
    )
)

# The page in Spanish.
SPANISH = Words(
    paragraph=(
        "Esta biblioteca compone el texto cortando un párrafo en líneas que caben en "
        "una columna y colocando luego cada línea según una alineación. Las mismas "
        "palabras se muestran abajo alineadas a la izquierda, a la derecha, centradas "
        "y justificadas, para que la diferencia se vea de un vistazo."
    )
)

# The page in German.
GERMAN = Words(
    paragraph=(
        "Diese Bibliothek setzt Text, indem sie einen Absatz in Zeilen umbricht, die "
        "in eine Spalte passen, und dann jede Zeile nach einer Ausrichtung platziert. "
        "Dieselben Wörter stehen unten linksbündig, rechtsbündig, zentriert und im "
        "Blocksatz, sodass der Unterschied zwischen ihnen auf einen Blick deutlich "
        "wird."
    )
)


# 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}


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("flow.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()
    box_width = 400.0
    x = 80.0
    top = 780.0

    for align in (
        hqf_pdf.Align.Left,
        hqf_pdf.Align.Right,
        hqf_pdf.Align.Center,
        hqf_pdf.Align.Justify,
    ):
        flow = hqf_pdf.TextFlow(handle, 11.0, align=align, leading=15.0)
        lines = flow.break_lines(words.paragraph, box_width)
        flow.draw(content, lines, x, top, box_width)

        # A frame around the text column, inset from the glyphs on every side.
        height = flow.height(lines)
        pad = 8.0
        content.save_state()
        content.set_stroke(hqf_pdf.Rgb.gray(0.8))
        content.set_line_width(0.5)
        content.rect(
            x - pad,
            top - height - pad,
            box_width + pad * 2.0,
            height + pad * 2.0,
        )
        content.stroke()
        content.restore_state()

        top -= height + 30.0

    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()
