<?php declare(strict_types=1);

require_once __DIR__ . '/../common/QrbException.php';

// A position with X and Y coordinates (both in mm) in the PDF.
final class QrbPdfPosition
{
    // key constants (public for unit tests)
    public const KEY_PAGE  = "page";
    public const KEY_POS_X = "posX";
    public const KEY_POS_Y = "posY";
    
    private int $page = 1;  // backwards compatibility
    private int $posX;
    private int $posY;

    // Validates the given associative array.
    //
    // Checks:
    // - Entry with name "posX" must exist and be numeric.
    // - Entry with name "posY" must exist and be numeric.
    public static function validate(array $positions, string $section)
    {
        if (  array_key_exists(self::KEY_PAGE, $positions)
           && (! is_numeric($positions[self::KEY_PAGE])))
            throw new QrbException(static::class . " - ({$section}): Invalid page (not numeric), {self::KEY_PAGE} = '{$positions[self::KEY_PAGE]}'",
                                   "exception.position.pageNotNumeric",
                                   "{$section}, {self::KEY_PAGE}, {$positions[self::KEY_PAGE]}");

        if (! array_key_exists(self::KEY_POS_X, $positions))
            throw new QrbException(static::class . " - ({$section}): key '{self::KEY_POS_X}' does not exist",
                                   "exception.position.posXDoesNotExist",
                                   "{$section}, {self::KEY_POS_X}");
        if (! is_numeric($positions[self::KEY_POS_X]))
            throw new QrbException(static::class . " - ({$section}): Invalid pos X (not numeric), {self::KEY_POS_X} = '{$positions[self::KEY_POS_X]}'",
                                   "exception.position.posXNotNumeric",
                                   "{$section}, {self::KEY_POS_X}, {$positions[self::KEY_POS_X]}");
            
        if (! array_key_exists(self::KEY_POS_Y, $positions))
            throw new QrbException(static::class . " - ({$section}): key '{self::KEY_POS_Y}' does not exist",
                                   "exception.position.posYDoesNotExist",
                                   "{$section}, {self::KEY_POS_Y}");
        if (! is_numeric($positions[self::KEY_POS_Y]))
            throw new QrbException(static::class . " - ({$section}): Invalid pos Y (not numeric), {self::KEY_POS_Y} = '{$positions[self::KEY_POS_Y]}'",
                                   "exception.position.posYNotNumeric",
                                   "{$section}, {self::KEY_POS_Y}, {$positions[self::KEY_POS_Y]}");
    }

    // Creates an instance from the given associative array.
    // 
    // "page": page
    // "posX": X position
    // "posY": Y position
    public function __construct(array $positions, string $section)
    {
        self::validate($positions, $section);
        
        if (array_key_exists(self::KEY_PAGE, $positions))
            $this->page = intval($positions[self::KEY_PAGE]);
        $this->posX = intval($positions[self::KEY_POS_X]);
        $this->posY = intval($positions[self::KEY_POS_Y]);
    }
    
    public function getPage() : int { return $this->page; }
    public function getPosX() : int { return $this->posX; }
    public function getPosY() : int { return $this->posY; }
    
    public function __toString()
    {
        return  "[page = '" . $this->page . "'" . ", posX = '" . $this->posX . "'" . ", posY = '" . $this->posY . "']";
    }
}

?>
