<?php
/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */

namespace Kufer\Utils\Pdf\Helper;


class Row extends InnerBorderContainer
{
  
  protected $widths = array();

  
  public function addColumn($child, $width = ''): int
  {
    if (\is_array($child)) {
      $area = new TextArea($this->fpdf, $child);

      return $this->addColumn($area, $width);
    }
    if (\is_string($child)) {
      $field = new TextField($this->fpdf, $child);

      return $this->addColumn($field, $width);
    }

    $idx = $this->addChild($child);
    if ($width !== '' && $width !== '%') {
      $this->widths[$idx] = $width;
      $child->setWidth($width);
    }

    return $idx;
  }

  public function addColumns($children): void
  {
    foreach ($children as $child) {
      $this->addColumn($child);
    }
  }

  public function setColumnWidth(int $i, $width = ''): void
  {
    if ($width !== '') {
      $this->widths[$i] = $width;
    } elseif (isset($this->widths[$i])) {
      unset($this->widths[$i]);
    }
  }

  public function getChildComputedWidth(int $idx): float
  {
    if (array_key_exists($idx, $this->widths)) {
      $this->children[$idx]->setWidth($this->widths[$idx]);
    }

    return $this->children[$idx]->getComputedWidth();
  }

  public function render(): void
  {
    $this->context(function() {
      if (static::DEBUG_ALL) {
        $this->drawOutline(255, 100);
      }

      $widths = $this->widths;

      $startX = $this->fpdf->GetX();
      $startY = $this->fpdf->GetY();

      $endX = $startX + $this->getComputedWidth();
      $height = $this->getComputedHeight();
      $endY = $startY + $height;

      
      $this->fillBackgroundColor($startX, $startY, $endX, $endY);

      foreach ($this->children as $idx => $child) {
        if (isset($widths[$idx])) {
          $child->setWidth($widths[$idx]);
        }
        $child->setHeight($height);
      }

      
      if ($startY + $height > $this->fpdf->getPageBreakTrigger()) {
        $this->fpdf->AddPage();
        $this->fpdf->SetX($startX);
        $startY = $this->fpdf->GetY();
      }

      $xOffset = 0;
      foreach ($this->children as $idx => $child) {
        $this->fpdf->SetX($startX + $xOffset);
        $child->render();
        $xOffset += $child->getComputedWidth();

        if (!$this->isLastChild($idx) && $this->hasInnerBorder($idx)) {
          $line = new Line($this->fpdf, $this->fpdf->GetX(), $startY, $this->fpdf->GetX(), $startY + $height);
          $line->setParent($this);
          $line->render();
        }

        $this->fpdf->SetY($startY, false);
      }

      $this->drawBorder($startX, $startY, $endX, $endY);

      $this->fpdf->Ln($height);
      $this->fpdf->setX($startX);
    });
  }

  private function fillBackgroundColor($startX, $startY, $endX, $endY)
  {
    if ($this->hasBackgroundColor()) {
      $this->fpdf->setX($startX);
      $this->fpdf->setY($startY, false);
      $this->fpdf->Cell($endX - $startX, $endY - $startY, '', 0, 0, '', $this->getBackgroundColor());
    }
  }

  private function isLastChild($idx): bool
  {
    return $idx === \count($this->children) - 1;
  }

  public function getMaxChildrenHeight()
  {
    return max(0, 0, ...array_filter(array_map(function(RenderObject $child) {
      return $child->getComputedHeight();
    }, $this->children)));
  }

  public function getAutoWidth(): ?float
  {
    return array_sum(array_map(function($idx) {
      return $this->getChildComputedWidth($idx);
    }, array_keys($this->children)));
  }

  public function getAutoHeight(): ?float
  {
    return $this->getMaxChildrenHeight();
  }
}