"""Places every picture a TIFF holds on a page of its own, and writes the result to
disk.

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

A TIFF holds any number of pictures, one directory apiece: a scanner puts every sheet
of a batch in one file, and a fax puts every page of a call there. Each of them gets a
page exactly its own size — at 72 dots to the inch one pixel is one point — so the page
that comes back out of a renderer is the picture that went in.

Named nothing, the example reads the two committed fixtures: one holding a photograph
in a single strip, whose bytes go into the document undecoded because PDF reads a
photograph itself, and one holding three pictures whose samples are read and written
again. It opens on a sheet laying all of them out the way a document would.

Usage: python examples/write_tiff.py [out.pdf] [file.tif...]
"""

from __future__ import annotations

import sys
from pathlib import Path

import _licence
import _out

import hqf_pdf

# The files the example reads when the caller names none: the ones committed for the
# tests, so that it runs on any machine.
IMAGES = Path(__file__).resolve().parents[2] / "hqf-pdf" / "tests" / "images"
DEFAULT_FILES = [IMAGES / "photograph.tif", IMAGES / "pages.tif"]

# How wide the sheet the showcase is laid out on is.
A4_WIDTH = 595.276

# The side of the box each picture of the showcase is fitted into, and how far apart the
# boxes stand.
BOX_SIDE = 120.0
BOX_STEP = 130.0


def sheet_of_all(handles: list) -> hqf_pdf.Page:
    """One sheet holding every picture the files gave, each fitted whole into a box of
    one size and standing on the same line as the rest."""
    content = hqf_pdf.Content()

    content.set_fill(hqf_pdf.Rgb(0.93, 0.94, 0.96))
    content.rect(0.0, 700.0, A4_WIDTH, 142.0)
    content.fill()

    left = 60.0
    for handle in handles:
        width, height = handle.fit_within(BOX_SIDE, BOX_SIDE)
        content.draw_image(handle, left, 600.0, width, height)
        left += BOX_STEP

    page = hqf_pdf.Page.a4()
    page.set_content(content)
    return page


def main() -> None:
    out = _out.output_path("tiff")

    named = [Path(argument) for argument in sys.argv[2:]]
    showcase = not named
    paths = DEFAULT_FILES if showcase else named

    doc = hqf_pdf.Document()
    doc.set_license(_licence.licensed())
    doc.set_info("Title", "hqf-pdf TIFF sample")

    handles = []
    for path in paths:
        data = path.read_bytes()
        held = hqf_pdf.Image.tiff_pages(data)
        print(f"{path}: {held} picture(s)")

        for page in range(held):
            image = hqf_pdf.Image.from_tiff_page(data, page)
            resolution = image.resolution
            declared = (
                f"{resolution.x} by {resolution.y} dots to the inch"
                if resolution is not None
                else "stating no resolution of its own"
            )
            print(
                f"  {page + 1}: {image.width}x{image.height} {image.color_space!r},"
                f" {image.bits_per_component} bits a component, {declared}"
            )
            handles.append(doc.add_image(image))

    if showcase:
        doc.add_page(sheet_of_all(handles))
    for handle in handles:
        # A page the size of the picture, with the picture filling it. The size is the
        # one the file itself asks for; a file asking for none is laid down one pixel to
        # the point.
        width, height = handle.size
        content = hqf_pdf.Content()
        content.draw_image(handle, 0.0, 0.0, width, height)

        sheet = hqf_pdf.Page(width, height)
        sheet.set_content(content)
        doc.add_page(sheet)

    pdf = doc.to_bytes()
    Path(out).parent.mkdir(parents=True, exist_ok=True)
    Path(out).write_bytes(pdf)

    print(f"wrote {out}: {len(pdf)} bytes, {doc.page_count} page(s)")


if __name__ == "__main__":
    main()
