<?php declare(strict_types=1);

require_once __DIR__ . '/../common/QrbException.php';
require_once __DIR__ . '/QrbPdfPosition.php';
require_once __DIR__ . '/QrbPdfTextAttribute.php';
require_once __DIR__ . '/QrbMultiLanguageText.php';

// Holds one entry of the QR bills PDF data.
final class QrbPdfDataEntry
{
    public const KEY_NAME_DEFAULT   = "default";
    
    // key constants (public for unit tests)
    public const KEY_NAME           = "name";
    public const KEY_POSITION       = "position";
    public const KEY_TEXT_ATTRIBUTE = "textAttribute";
    public const KEY_TEXT           = "text";
    
    private string                   $name;
    private ?QrbPdfPosition       $position      = NULL;
    private ?QrbPdfTextAttribute  $textAttribute = NULL;
    private ?QrbMultiLanguageText $mlText        = NULL;

    // Validates the PDF data entry in the given associative array.
    //
    // Checks:
    // - There must be an entry for "name".
    // - If the name is not "default", there must be an entry "position".
    // - If the name is "default", there must be an entry "textAttribute".
    // - Other checks done by QrbPdfPosition::validate(), 
    //   QrbPdfTextAttribute::validate() and QrbMultiLanguageText::validate().
    public static function validate(array $pdfDataEntry, array $additionalLanguages, string $parentName)
    {
        if (! array_key_exists(self::KEY_NAME, $pdfDataEntry))
            throw new QrbException(
                static::class . " - found entry without key " . self::KEY_NAME,
                "exception.pdfData.keyNameDoesNotExist", "{$parentName} " . self::KEY_NAME);
        $name = $pdfDataEntry[self::KEY_NAME];
    
        if (! array_key_exists(self::KEY_POSITION, $pdfDataEntry))
        {
            if ($name !== self::KEY_NAME_DEFAULT)
                throw new QrbException(
                    static::class . " - entry with name '{$name}' does not contain key " . self::KEY_POSITION,
                    "exception.pdfData.keyPositionDoesNotExist", "{$parentName} {$name}");
        }
        else
            QrbPdfPosition::validate(
                $pdfDataEntry[self::KEY_POSITION], 
                $parentName . "." . $name . "." . self::KEY_POSITION);

        if (! array_key_exists(self::KEY_TEXT_ATTRIBUTE, $pdfDataEntry))
        {
            if ($name === self::KEY_NAME_DEFAULT)
                throw new QrbException(
                    static::class . " - entry with name '{$name}' does not contain key " . self::KEY_TEXT_ATTRIBUTE,
                    "exception.pdfData.keyTextAttributeDoesNotExist", "{$parentName} {$name}");
        }
        else
            QrbPdfTextAttribute::validate(
                $pdfDataEntry[self::KEY_TEXT_ATTRIBUTE], 
                $parentName . "." . $name . "." . self::KEY_TEXT_ATTRIBUTE);

        if (array_key_exists(self::KEY_TEXT, $pdfDataEntry))
            QrbMultiLanguageText::validate(
                $parentName . "." . $name . "." . self::KEY_TEXT, 
                $pdfDataEntry[self::KEY_TEXT], 
                $additionalLanguages);
    }

    // Creates an instance from the given associative array.
    // 
    // "name":          Unique name of the entry, mandatory.
    // "position":      X/Y position, mandatory if "name" is not "default".
    // "textAttribute": Text attribute, mandatory if "name" is "default".
    // "text":          Multi-language text.
    public function __construct(array  $pdfDataEntry, 
                                array  $supportedLanguages,  
                                array  $additionalLanguages,
                                string $parentName)
    {
        self::validate($pdfDataEntry, $additionalLanguages, $parentName);
        
        $this->name = $pdfDataEntry[self::KEY_NAME];
        
        if (array_key_exists(self::KEY_POSITION, $pdfDataEntry))
            $this->position = 
                new QrbPdfPosition(
                    $pdfDataEntry[self::KEY_POSITION],
                    $parentName . "." . $this->name . "." . self::KEY_POSITION);
        
        if (array_key_exists(self::KEY_TEXT_ATTRIBUTE, $pdfDataEntry))
            $this->textAttribute = 
                new QrbPdfTextAttribute(
                    $pdfDataEntry[self::KEY_TEXT_ATTRIBUTE], 
                    $parentName . "." . $this->name . "." . self::KEY_TEXT_ATTRIBUTE);
        
        if (array_key_exists(self::KEY_TEXT, $pdfDataEntry))
            $this->mlText =
                QrbMultiLanguageText::fromJsonArray(
                    $parentName . "." . $this->name . "." . self::KEY_TEXT,
                    $pdfDataEntry[self::KEY_TEXT], 
                    $supportedLanguages,
                    $additionalLanguages);
    }
    
    public function getName()             : string                    {    return $this->name;          }
    // position is mandatory except for key "default" (default text attribute)
    public function getPosition()         : ?QrbPdfPosition        {    return $this->position;      }
    // text attribute is mandatory for key "default" (default text attribute)
    public function getTextAttribute()    : ?QrbPdfTextAttribute   {    return $this->textAttribute;	}
    public function getMlText()           : ?QrbMultiLanguageText  {    return $this->mlText;        }
    
    public function __toString()
    {
        return  "\n\tname = '{$this->name}'"
              . "\n\tposition: {$this->position}"
              . "\n\ttextAttribute: {$this->textAttribute}"
              . "\n\tmlText: {$this->mlText}"
              ;
    }
}

?>
