<?php declare(strict_types=1);

// Holds the profile specific QR bill configuration.
final class QrbProfileConfiguration
{
    // allowed values for currency
    public const CHF               = "CHF";
    public const EUR               = "EUR";
    
    // allowed values for printAmount
    public const NO_AMOUNT         = "noAmount";
    public const GLOBAL_AMOUNT     = "globalAmount";
    public const INDIVIDUAL_AMOUNT = "individualAmount";
    
    // keys for form
    private const KEY_CURRENCY             = "currency";
    private const KEY_PRINT_AMOUNT         = "printAmount";
    private const KEY_AMOUNT               = "amount";
    private const KEY_ADD_DEBTOR           = "addDebtor";
    private const KEY_ADD_REF_TO_INFO      = "addRefToAddInfo";
    private const KEY_CREATE_PDF           = "createPdf";
    private const KEY_PRINT_PAYMENT_SLIP   = "printPaymentSlip";
    private const KEY_SEND_MAIL            = "sendMail";
    private const KEY_SLEEP_AFTER_SEND     = "sleepAfterSend";
    private const KEY_PRESET_MAIL          = "presetMail";
    private const KEY_DEFAULT_LANGUAGE     = "defaultLanguage";
    private const KEY_MULTI_LANGUAGE       = "multiLanguage";
    private const KEY_ADDITIONAL_LANGUAGES = "additionalLanguages";

    // currency, CHF or EUR, defaults to "CHF"
    private string $currency = "CHF";
    
    // controls whether and which amount is printed, 
    // NO_AMOUNT         = no amount is printed
    // GLOBAL_AMOUNT     = amount from global configuration is printed
    // INDIVIDUAL_AMOUNT = individual amount found in the recipient is printed
    // default to "noAmount"
    private string $printAmount = "noAmount";
    
    // amount taken if 'printAmount' is 'GLOBAL_AMOUNT'
    // defaults to 0.00
    private float $amount = 0.00;

    // controls whether the field 'UltimateDebtor' ('Zahlbar durch') is set in the QR bill
    // (from the data found in the recipient, see Recipients.csv).
    // defaults to false
    private bool $addDebtor = false;
    
    // controls whether the reference (see Recipients.csv) is not only written to the field 
    // 'PaymentReference' ('Referenz') but appended as well after a line break to the field 
    // 'AdditionalInformation' ('Zusätzliche Informationen').
    // defaults to false
    private bool $addRefToAddInfo = false;

    // controls whether PDFs are created
    // defaults to true
    private bool $createPdf = true;
    
    // controls whether the payment slip is printed
    // defaults to true
    private bool $printPaymentSlip = true;

    // controls whether e-mails are sent
    // defaults to true
    private bool $sendMail = true;

    // presets a test e-mail
    // defaults to empty string
    private string $presetMail = "";

    // time to sleep in microseconds after a mail has been sent ("1000000" == 1 second)
    // defaults to 1'000'000 (1 second)
    private int $sleepAfterSend = 1000000;
    
    // contains the default language: MANDATORY!
    // defaults to "en"
    private string $defaultLanguage = "en";
    
    // controls whether multi-language is activated
    // defaults to false
    private bool $multiLanguage = false;

    // contains additional languages if multiLanguage is true
    // defaults to empty array
    private array $additionalLanguages = array();

    // Creates a new configuration filled with the data provided by the array.
    public static function fromJson(array $cfgJson) : QrbProfileConfiguration
    {
        $qrbCfg = new QrbProfileConfiguration();
        $qrbCfg->setCurrency($cfgJson[self::KEY_CURRENCY]);
        $qrbCfg->setPrintAmount($cfgJson[self::KEY_PRINT_AMOUNT]);
        $qrbCfg->setAmount(floatval($cfgJson[self::KEY_AMOUNT]));
        $qrbCfg->setAddDebtor(boolval($cfgJson[self::KEY_ADD_DEBTOR]));
        $qrbCfg->setAddRefToAddInfo(boolval($cfgJson[self::KEY_ADD_REF_TO_INFO]));
        $qrbCfg->setCreatePdf(boolval($cfgJson[self::KEY_CREATE_PDF]));
        $qrbCfg->setPrintPaymentSlip(boolval($cfgJson[self::KEY_PRINT_PAYMENT_SLIP]));
        $qrbCfg->setSendMail(boolval($cfgJson[self::KEY_SEND_MAIL]));
        $qrbCfg->setSleepAfterSend(intval($cfgJson[self::KEY_SLEEP_AFTER_SEND]));
        $qrbCfg->setPresetMail($cfgJson[self::KEY_PRESET_MAIL]);
        $qrbCfg->setDefaultLanguage($cfgJson[self::KEY_DEFAULT_LANGUAGE]);
        $qrbCfg->setMultiLanguage(boolval($cfgJson[self::KEY_MULTI_LANGUAGE]));
        $qrbCfg->setAdditionalLanguages($cfgJson[self::KEY_ADDITIONAL_LANGUAGES]);
        return $qrbCfg;
    }

    // Creates an array filled with the data of the given configuration.    
    public static function toJson(QrbProfileConfiguration $qrbCfg) : array
    {
        $cfgJson = array();
        $cfgJson[self::KEY_CURRENCY]             = $qrbCfg->getCurrency();
        $cfgJson[self::KEY_PRINT_AMOUNT]         = $qrbCfg->getPrintAmount();
        $cfgJson[self::KEY_AMOUNT]               = number_format($qrbCfg->getAmount(), 2, '.', '');    // float rounded to two decimals
        $cfgJson[self::KEY_ADD_DEBTOR]           = $qrbCfg->getAddDebtor()        ? "1" : "0";
        $cfgJson[self::KEY_ADD_REF_TO_INFO]      = $qrbCfg->getAddRefToAddInfo()  ? "1" : "0";
        $cfgJson[self::KEY_CREATE_PDF]           = $qrbCfg->getCreatePdf()        ? "1" : "0";
        $cfgJson[self::KEY_PRINT_PAYMENT_SLIP]   = $qrbCfg->getPrintPaymentSlip() ? "1" : "0";
        $cfgJson[self::KEY_SEND_MAIL]            = $qrbCfg->getSendMail()         ? "1" : "0";
        $cfgJson[self::KEY_SLEEP_AFTER_SEND]     = $qrbCfg->getSleepAfterSend();    // int
        $cfgJson[self::KEY_PRESET_MAIL]          = $qrbCfg->getPresetMail();
        $cfgJson[self::KEY_DEFAULT_LANGUAGE]     = $qrbCfg->getDefaultLanguage();
        $cfgJson[self::KEY_MULTI_LANGUAGE]       = $qrbCfg->getMultiLanguage()    ? "1" : "0";
        $cfgJson[self::KEY_ADDITIONAL_LANGUAGES] = $qrbCfg->getAdditionalLanguages();        
        return $cfgJson;
    }

    // Constructor.
    public function __construct()
    {
    }
    
    // sets the currency, must be self::CHF or self::EUR (NOT CHECKED!!!)
    public function setCurrency(string $currency)
    {
        $this->currency = $currency;
    }
    
    // returns the currency, self::CHF or self::EUR
    public function getCurrency() : string
    {
        return $this->currency;
    }
    
    // sets whether and which amount is printed, 
    // must be self::NO_AMOUNT, self::GLOBAL_AMOUNT or self::INDIVIDUAL_AMOUNT (NOT CHECKED!!!)
    public function setPrintAmount(string $printAmount)
    {
        $this->printAmount = $printAmount;
    }

    // returns whether and which amount is printed,
    // one of self::NO_AMOUNT, self::GLOBAL_AMOUNT, self::INDIVIDUAL_AMOUNT
    public function getPrintAmount() : string
    {
        return $this->printAmount;
    }

    // sets the global amount, used only if printAmount is self::GLOBAL_AMOUNT
    public function setAmount(float $amount)
    {
        $this->amount = $amount;
    }
    
    // returns the global amount, to be used only if printAmount is self::GLOBAL_AMOUNT
    public function getAmount() : float
    {
        return $this->amount;
    }
    
    // sets whether the field 'UltimateDebtor' ('Zahlbar durch') should be set in the QR bill
    public function setAddDebtor(bool $addDebtor)
    {
        $this->addDebtor = $addDebtor;
    }
    
    // returns whether the field 'UltimateDebtor' ('Zahlbar durch') should be set in the QR bill
    public function getAddDebtor() : bool
    {
        return $this->addDebtor;
    }

    // sets whether the reference is appended to the field 'AdditionalInformation'
    public function setAddRefToAddInfo(bool $addRefToAddInfo)
    {
        $this->addRefToAddInfo = $addRefToAddInfo;
    }
    
    // returns whether the reference is appended to the field 'AdditionalInformation'
    public function getAddRefToAddInfo() : bool
    {
        return $this->addRefToAddInfo;
    }
    
    // sets whether PDFs are created
    public function setCreatePdf(bool $createPdf)
    {
        $this->createPdf = $createPdf;
    }
    
    // returns whether PDFs are created
    public function getCreatePdf() : bool
    {
        return $this->createPdf;
    }
    
    // sets whether payment slip is printed
    public function setPrintPaymentSlip(bool $printPaymentSlip)
    {
        $this->printPaymentSlip = $printPaymentSlip;
    }
    
    // returns whether payment slip is printed
    public function getPrintPaymentSlip() : bool
    {
        return $this->printPaymentSlip;
    }
    
    // sets whether e-mails are sent
    public function setSendMail(bool $sendMail)
    {
        $this->sendMail = $sendMail;
    }

    // returns whether e-mails are sent
    public function getSendMail() : bool
    {
        return $this->sendMail;
    }

    // sets the time to sleep in microseconds after a mail has been sent ("1000000" == 1 second)
    public function setSleepAfterSend(int $sleepAfterSend)
    {
        $this->sleepAfterSend = $sleepAfterSend;
    }

    // returns the time to sleep in microseconds after a mail has been sent ("1000000" == 1 second)
    public function getSleepAfterSend() : int
    {
        return $this->sleepAfterSend;
    }

    // sets preset mail
    public function setPresetMail(string $presetMail)
    {
        $this->presetMail = $presetMail;
    }

    // returns preset mail
    public function getPresetMail() : string
    {
        return $this->presetMail;
    }

    // sets the default language
    public function setDefaultLanguage(string $defaultLanguage)
    {
        $this->defaultLanguage = $defaultLanguage;
    }

    // returns the default language
    public function getDefaultLanguage() : string
    {
        return $this->defaultLanguage;
    }
    
    // sets whether optional multi-language us used
    public function setMultiLanguage(bool $multiLanguage)
    {
        $this->multiLanguage = $multiLanguage;
    }

    // returns whether optional multi-language us used
    public function getMultiLanguage() : bool
    {
        return $this->multiLanguage;
    }

    // sets the additional languages if optional multi-language us used
    public function setAdditionalLanguages(array $additionalLanguages)
    {
        $this->additionalLanguages = $additionalLanguages;
    }
    
    // returns the additional languages if optional multi-language us used
    public function getAdditionalLanguages() : array
    {
        return $this->additionalLanguages;
    }

    public function __toString()
    {
        $ret = "\n\tcurrency            = '{$this->currency}'"
             . "\n\tprintAmount         = '{$this->printAmount}'"
             . "\n\tamount              = {$this->amount}"
             . "\n\taddDebtor           = " . ($this->addDebtor         ? "true" : "false")
             . "\n\taddRefToAddInfo     = " . ($this->addRefToAddInfo   ? "true" : "false")
             . "\n\tcreatePdf           = " . ($this->createPdf         ? "true" : "false")
             . "\n\tprintPaymentSlip    = " . ($this->printPaymentSlip  ? "true" : "false")
             . "\n\tsendMail            = " . ($this->sendMail          ? "true" : "false")
             . "\n\tpresetMail          = '{$this->presetMail}'"
             . "\n\tsleepAfterSend      = {$this->sleepAfterSend}"
             . "\n\tdefaultLanguage     = '{$this->defaultLanguage}'"
             . "\n\tmultiLanguage       = " . ($this->multiLanguage     ? "true" : "false")
             . "\n\tadditionalLanguages = "
             ;
        
        if (empty($this->additionalLanguages))
        {
            $ret .= "None";
        }
        else
        {
            foreach ($this->additionalLanguages as $key => $value)
            {
                $ret .= "'{$value}' ";
            }
        }
        
        return $ret;
    }
}

?>
