<?php
/**
 * @copyright (c) Kufer Software GmbH, Oderstraße 7, D-84453 Mühldorf
 */

namespace Kufer\Web\Classes\Pdf\Helper;

use Kufer\Web\Classes\Pdf\ExtFPDITcPDF;

class Margin extends RenderObject
{
  
  private $lm;

  
  private $rm;

  
  private $tm;

  
  private $bm;

  
  private $innerElement;

  
  public function __construct($fpdf, $lm, $rm, $tm, $bm, ?RenderObject $innerElement)
  {
    parent::__construct($fpdf);
    $this->lm = $lm;
    $this->rm = $rm;
    $this->tm = $tm;
    $this->bm = $bm;
    if (!is_null($innerElement)) {
      $innerElement->setParent($this);
      $this->innerElement = $innerElement;
    }
  }

  public function setMargin(float $margin): void
  {
    $this->lm = $margin;
    $this->rm = $margin;
    $this->tm = $margin;
    $this->bm = $margin;
  }

  public function getAutoWidth(): ?float
  {
    return $this->context(function() {
      if (is_null($this->innerElement)) {
        return $this->fpdf->getWidthAbsolute($this->lm) + $this->fpdf->getWidthAbsolute($this->rm);
      }

      $width = $this->innerElement->getComputedWidth();
      if (is_null($width)) {
        return null;
      }

      return $this->fpdf->getWidthAbsolute($this->rm) + $this->fpdf->getWidthAbsolute($this->lm) + $width;
    });
  }

  public function setWidth($width): void
  {
    parent::setWidth($width);

    $this->context(function() use ($width) {
      if (!is_null($this->innerElement)) {
        $this->innerElement->setWidth($this->fpdf->getWidthAbsolute($width)
          - $this->fpdf->getWidthAbsolute($this->rm)
          - $this->fpdf->getWidthAbsolute($this->lm));
      }
    });
  }

  public function getAutoHeight(): ?float
  {
    if (is_null($this->innerElement)) {
      return $this->fpdf->getHeightAbsolute($this->tm) + $this->fpdf->getHeightAbsolute($this->bm);
    }

    $height = $this->innerElement->getComputedHeight();
    if (is_null($height)) {
      return null;
    }

    return $this->fpdf->getHeightAbsolute($this->tm) + $this->fpdf->getHeightAbsolute($this->bm) + $height;
  }

  public function setHeight($height): void
  {
    parent::setHeight($height);

    $this->context(function() use ($height) {
      if (!is_null($this->innerElement)) {
        $this->innerElement->setHeight($this->fpdf->getHeightAbsolute($height)
          - $this->fpdf->getHeightAbsolute($this->tm)
          - $this->fpdf->getHeightAbsolute($this->bm));
      }
    });
  }

  public function render(): void
  {
    $this->context(function() {
      $width = $this->getComputedWidth();
      $height = $this->getComputedHeight();
      assert(!is_null($width));
      assert(!is_null($height));

      $x = $this->fpdf->GetX();
      $y = $this->fpdf->GetY();
      if (!is_null($this->innerElement)) {
        $lm = $this->fpdf->getWidthAbsolute($this->lm);
        $rm = $this->fpdf->getWidthAbsolute($this->rm);
        $tm = $this->fpdf->getHeightAbsolute($this->tm);
        $bm = $this->fpdf->getHeightAbsolute($this->bm);

        $this->fpdf->SetX($this->fpdf->GetX() + $lm);
        $this->fpdf->SetY($this->fpdf->GetY() + $tm, false);
        $this->innerElement->setWidth($width - ($lm + $rm));
        $this->innerElement->setHeight($height - ($tm + $bm));
        $this->innerElement->render();
      }

      $this->fpdf->SetX($x + $width);
      $this->fpdf->SetY($y + $height, false);
    });
  }

  public function __clone()
  {
    if (!is_null($this->innerElement)) {
      $this->innerElement = clone $this->innerElement;
      $this->innerElement->setParent($this);
    }
  }
}