<?php

/**
 * Copyright © 2003-2025 The Galette Team
 *
 * This file is part of Galette (https://galette.eu).
 *
 * Galette is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Galette is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
 */

declare(strict_types=1);

namespace Galette\IO;

use Galette\Core\Preferences;
use Analog\Analog;
use Galette\Entity\Adherent;

/**
 * Member labels PDF
 *
 * @author Johan Cwiklinski <johan@x-tnd.be>
 */

class PdfMembersLabels extends Pdf
{
    private int $xorigin;
    private int $yorigin;
    private float $lw;
    private float $lh;
    private float $line_h;

    /**
     * Main constructor, set creator and author
     *
     * @param Preferences $prefs Preferences
     */
    public function __construct(Preferences $prefs)
    {
        $this->setRTL(false);
        $this->filename = __('labels_print_filename') . '.pdf';
        parent::__construct($prefs);
    }

    /**
     * Initialize PDF
     *
     * @return void
     */
    public function init(): void
    {
        // Set document information
        $this->SetTitle(_T("Member's Labels"));
        $this->SetSubject(_T("Generated by Galette"));
        $this->SetKeywords(_T("Labels"));

        // No headers and footers
        $this->setNoHeader();
        $this->setNoFooter();

        // Show full page
        $this->SetDisplayMode('fullpage');

        // Disable Auto Page breaks
        $this->SetAutoPageBreak(false, 0);

        // Set colors
        $this->SetDrawColor(160, 160, 160);
        $this->SetTextColor(0);

        // Set margins
        $this->SetMargins(
            $this->preferences->pref_etiq_marges_h,
            $this->preferences->pref_etiq_marges_v
        );

        // Set font
        //$this->SetFont(self::FONT);

        // Set origin
        // Top left corner
        $this->xorigin = $this->preferences->pref_etiq_marges_h;
        $this->yorigin = $this->preferences->pref_etiq_marges_v;

        // Label width
        $this->lw = round($this->preferences->pref_etiq_hsize);
        // Label heigth
        $this->lh = round($this->preferences->pref_etiq_vsize);
        // Line heigth
        $this->line_h = round($this->lh / 5);
    }

    /**
     * Draw members cards
     *
     * @param array<Adherent> $members Members
     *
     * @return void
     */
    public function drawLabels(array $members): void
    {
        $nb_etiq = 0;
        foreach ($members as $member) {
            // Detect page breaks
            $colsrows = $this->preferences->pref_etiq_cols
                * $this->preferences->pref_etiq_rows;
            if ($nb_etiq % $colsrows == 0) {
                $this->AddPage();
            }
            // Set font
            $this->SetFont(self::FONT, '', $this->preferences->pref_etiq_corps);
            // Set line height ratio
            $this->SetCellHeightRatio(1.35);

            // Compute label position
            $col = $nb_etiq % $this->preferences->pref_etiq_cols;
            $row = (int)($nb_etiq / $this->preferences->pref_etiq_cols)
                % $this->preferences->pref_etiq_rows;
            // Set label origin
            $x = $this->xorigin + $col * (
                round($this->preferences->pref_etiq_hsize) +
                round($this->preferences->pref_etiq_hspace)
            );
            $y = $this->yorigin + $row * (
                round($this->preferences->pref_etiq_vsize) +
                round($this->preferences->pref_etiq_vspace)
            );
            // Draw a frame around the label
            if ($this->preferences->pref_etiq_border) {
                $this->Rect($x, $y, $this->lw, $this->lh);
            }

            // Prepare full address
            $full_address_array = array();
            $full_address_array[] = $member->sfullname;
            // Transform member's address in array and merge it with $full_address_array
            $address_array = explode(PHP_EOL, $member->address);
            $full_address_array = array_merge($full_address_array, $address_array);
            $full_address_array[] = $member->zipcode . ' ' . $member->town;
            $full_address_array[] = $member->country;
            $full_address = implode(PHP_EOL, $full_address_array);
            // Find longest line in full address
            $address_lengths = array_map('strlen', $full_address_array);
            $address_longest = $full_address_array[array_search(max($address_lengths), $address_lengths)];
            // Calculate font size to always display full address inside the frame
            $max_text_size = $this->preferences->pref_etiq_hsize;
            $this->fixSize(
                $address_longest,
                $max_text_size,
                $this->preferences->pref_etiq_corps
            );
            // Print full address
            $this->writeHTMLCell($this->lw, $this->line_h, $x, $y, nl2br($full_address), 0, 0, false, true, 'L', true);

            // Next label
            $nb_etiq++;
        }
    }
}
