"""Draws one badge, and places it eight times.

The Python twin of the `write_drawing` example in Rust. The badge — its frame, its
coloured head, its mark — is built once as a drawing, and the file holds its
operators once however many times it is placed. Each placing costs a name and a
matrix. The names on the badges are drawn by the page, over the drawing, because
they are what differs.

What the page reads is held in `Words`, once per language, and `HQF_PDF_LANG` picks
which set is drawn. The guests' names are not language, and neither is the company's:
a name is written the way its owner writes it.

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

from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path

import _language
import _licence
import _out

import hqf_pdf

# The size of one badge, in points.
BADGE = (220.0, 96.0)

# The left edge of everything the page draws.
LEFT = 70.0

# Who the badges are for. A name is not language.
GUESTS = [
    "Amélie Roussel",
    "Bertrand Colin",
    "Chloé Marchand",
    "Damien Leclerc",
    "Élise Fontaine",
    "Fabien Deschamps",
    "Gabrielle Vidal",
    "Hugo Mercier",
]

# The company the badges are issued by, drawn in the badge itself. A company writes its
# name one way.
COMPANY = "HQF Development"


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

    # The line at the head of the page.
    title: str
    # The line under it, saying what a drawing costs.
    intro: str
    # What the badge itself says under the company's name, drawn once for all eight.
    occasion: str
    # What each guest does, in the order the badges are placed.
    roles: tuple[str, str, str, str, str, str, str, str]
    # The line under the badge placed at half size.
    half: str


# The page in English.
ENGLISH = Words(
    title="One badge, placed eight times",
    intro=(
        "The badge is drawn once; the file holds its operators once, whatever it "
        "costs to place."
    ),
    occasion="Open house — visitor",
    roles=(
        "Bindery",
        "Typesetting",
        "Prepress",
        "Colour",
        "Plates",
        "Press",
        "Finishing",
        "Despatch",
    ),
    half="The same drawing, placed at half size.",
)

# The page in French.
FRENCH = Words(
    title="Un badge, posé huit fois",
    intro=(
        "Dessiné une fois, le badge n'a qu'un jeu d'instructions dans le fichier, "
        "où qu'il soit posé."
    ),
    occasion="Portes ouvertes — visiteur",
    roles=(
        "Reliure",
        "Composition",
        "Prépresse",
        "Couleur",
        "Plaques",
        "Impression",
        "Façonnage",
        "Expédition",
    ),
    half="Le même dessin, posé à la moitié de sa taille.",
)


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


def badge(font: hqf_pdf.FontHandle, words: Words) -> hqf_pdf.Drawing:
    """The badge itself: everything every badge has, drawn from the origin."""
    width, height = BADGE
    content = hqf_pdf.Content()

    content.set_fill(hqf_pdf.Rgb(0.96, 0.97, 0.99))
    content.rect(0.0, 0.0, width, height)
    content.fill()

    content.set_fill(hqf_pdf.Rgb(0.12, 0.28, 0.52))
    content.rect(0.0, height - 24.0, width, 24.0)
    content.fill()

    content.set_stroke(hqf_pdf.Rgb(0.12, 0.28, 0.52))
    content.set_line_width(1.0)
    content.rect(0.0, 0.0, width, height)
    content.stroke()

    content.set_fill(hqf_pdf.Rgb(1.0, 1.0, 1.0))
    content.draw_text(font, 11.0, 12.0, height - 17.0, COMPANY)

    content.set_fill(hqf_pdf.Rgb.gray(0.45))
    content.draw_text(font, 8.0, 12.0, 12.0, words.occasion)

    return hqf_pdf.Drawing(content, hqf_pdf.Rect(0.0, 0.0, width, height))


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("drawing.pdf", language)).stem)

    document = hqf_pdf.Document()
    document.set_license(_licence.licensed())
    font = document.add_font(hqf_pdf.Font.from_path(_out.font_path()))
    handle = document.add_drawing(badge(font, words))

    width, height = BADGE
    content = hqf_pdf.Content()
    content.draw_text(font, 15.0, LEFT, 780.0, words.title)
    content.save_state()
    content.set_fill(hqf_pdf.Rgb.gray(0.35))
    content.draw_text(font, 10.0, LEFT, 762.0, words.intro)
    content.restore_state()

    y = 600.0
    for start in range(0, len(GUESTS), 2):
        x = LEFT
        for index in range(start, min(start + 2, len(GUESTS))):
            content.draw_form(handle, x, y, 1.0)
            content.draw_text(font, 14.0, x + 12.0, y + 48.0, GUESTS[index])
            content.save_state()
            content.set_fill(hqf_pdf.Rgb.gray(0.4))
            content.draw_text(font, 10.0, x + 12.0, y + 32.0, words.roles[index])
            content.restore_state()
            x += width + 20.0
        y -= height + 20.0

    # The same drawing again, at half size: a placing carries its own scale.
    content.draw_form(handle, LEFT, 150.0, 0.5)
    content.save_state()
    content.set_fill(hqf_pdf.Rgb.gray(0.35))
    content.draw_text(font, 10.0, LEFT, 134.0, words.half)
    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, {len(GUESTS) + 1} placings of one drawing")


if __name__ == "__main__":
    main()
