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

define('FUSSZEILE_STANDARD_GROESSE', 8);


class TNListe
{
  
  public $settings;
  
  public $kurstage;

  
  public $knr;
  
  public $kurs;
  
  public $dtop;
  
  public $pdf;

  public $footerHeight;

  public $sprachSettings;

  
  public $seitennummerManipulation = 0;

  
  protected $toolId;

  
  protected $druckTnListeSettingsAry;

  
  public function __construct($pKnr, $pToolId)
  {
    $toolSettings = ToolSettingsAPI::getToolSettings($pToolId);
    $this->druckTnListeSettingsAry = \SerializeOperations::unserialize($toolSettings->druckTnListeSettings);

    $this->settings = new \webtools\lists\TNSettings();

    

    $this->dtop = new DateTimeOperations();
    $this->sprachSettings = SettingsFactory::getSettings('SprachSettingsObject');
    $this->knr = $pKnr;
    $this->toolId = $pToolId;
  }

  public function getDruckTnListeSetting(string $settingName)
  {
    return $this->druckTnListeSettingsAry[$settingName . $this->getListID()] ?? null;
  }

  
  public function getListID()
  {
    return false;
  }

  
  public function getListTyp()
  {
    return false;
  }

  
  public function getTNDarstellungText($optionName)
  {
  }

  
  public function getTNDarstellungEnabled($optionName)
  {
    switch ($optionName) {
    case 'option9':
      return false;
    default:
      return true;
    }
  }

  
  public function getSpaltenanordnungTextEnabled($optionName): bool
  {
    return false;
  }

  
  public function getSpaltenanordnungText($optionName)
  {
  }

  
  public function getSpaltenanordnungEnabled($optionName)
  {
    switch ($optionName) {
    case 'option7':
      return false;
    case 'option8':
      return false;
    case 'option9':
      return false;
    default:
      return true;
    }
  }

  
  public function getKopfbereichText($optionName)
  {
    $sprachsettings = new SprachSettingsObject();
    switch ($optionName) {
      case 'mitKursgebuehren':
        return 'mit ' . $sprachsettings->KursZusammengesetzt['Singular']['Nominativ'] . 'gebühren';
      case 'mitDozentenTelNr':
        return 'mit ' . $sprachsettings->Dozent['Plural']['Nominativ'] . ' Tel.Nr.';
      case 'ohneMinMaxTN':
        return 'ohne min/max ' . $sprachsettings->Teilnehmer['Plural']['Nominativ'];
      case 'mitDauerdetails':
        return 'mit Dauerdetails';
      case 'ohneDauer':
        return 'ohne Dauer / UE';
      case 'ohneKursOrt':
        return 'ohne Kursort';
    }
  }

  
  public function getKopfbereichEnabled($optionName)
  {
    return true;
  }

  
  public function getFusszeileEnabled($optionName)
  {
    return true;
  }

  
  public function getBemerkungOptions()
  {
    return array('I' => 'nur interne', 'E' => 'nur externe', 'IE' => 'interne und externe',
      'EI' => 'externe und interne');
  }

  
  public function getBemerkungEnabled($optionValue)
  {
    return true;
  }

  
  public function getSortierungOptions()
  {
    return array(
      \webtools\lists\TNSettings::SORT_NAME => 'Alphabetisch',
      \webtools\lists\TNSettings::SORT_ANMELDEDATUM => 'Anmeldedatum',
      \webtools\lists\TNSettings::SORT_FIRMENNAME => 'Firmenname'
    );
  }

  
  public function getDruckbereichEnabled($optionName)
  {
    switch ($optionName) {
    case 'namegross':
      return false;
    default:
      return true;
    }
  }

  
  public function showFusszeilen()
  {
    return true;
  }

  
  public function getAnzahlAntwortboxen()
  {
    return 0;
  }

  public function getAntwortboxenBezeichnungMehrzahl()
  {
    return 'Antwortboxen';
  }

  public function getAntwortboxenBezeichnungEinzahl()
  {
    return 'Antwortbox';
  }

  
  public function showTextUntenOben()
  {
    return false;
  }

  
  public function getAuffuellOptions()
  {
    return array('M' => 'bis max. TN', 'S' => 'bis Seitenende');
  }

  
  public function loadSettings()
  {
    

    $dbwkurstage = new DBWorkKurseTage(1, true);
    if (preg_match('/:/', $this->knr)) {
      $tage = array();
      $knrAry = explode(':', $this->knr);
      foreach ($knrAry as $knr) {
        $tage = array_merge($tage, $dbwkurstage->getKurstagebyKursNR($knr));
      }
    } else {
      $tage = $dbwkurstage->getKurstagebyKursNR($this->knr);
    }

    if (count($tage) > 0) {
      $this->kurstage = new webtools\lists\Kurstage();
      $this->kurstage->von = $tage[0]->datum;
      $this->kurstage->bis = $tage[count($tage) - 1]->datum;
    }

    
    $dbw = new DBWorkTNListSettings();
    $listID = $this->getListID();

    if ($listID === false) {
      die('Liste kann nicht geladen werden, weil keine gültige ID von getListID() zurückgeliefert wurde.');
    }

    $settings = $dbw->getSettings($listID, $this->toolId);
    if ($settings) {
      $this->settings->fromTNListSettings($settings);
    } else {
      $this->loadFactoryDefaults();
    }

    
    foreach (get_object_vars($this->settings->spaltenanordnung) as $var => $value) {
      if (\StringOperations::endsWith($var, '_text')) {
        $value = $this->getDruckTnListeSetting($var);
        if (!empty($value)) {
          $this->settings->spaltenanordnung->{$var} = $value;
        }
      }
    }
  }

  
  public function loadFactoryDefaults()
  {
    $this->settings->bemerkung = 'I'; 
    if (!isset($this->settings->umfang)) {
      $this->settings->umfang = new webtools\lists\Umfang();
    }
    $this->settings->umfang->filter = 'A'; 
    $this->settings->sortierung = \webtools\lists\TNSettings::SORT_NAME; 
    if (!isset($this->settings->druckbereich)) {
      $this->settings->druckbereich = new \webtools\lists\Druckbereich();
    }
    $this->settings->druckbereich->auffuellArt = 'M'; 
  }

  
  public function loadSettingsFromReqObj($pPostSettings)
  {
    $this->settings->loadFromReqObj($pPostSettings);
  }

  
  public function create($pOutputAsString = false)
  {
    if ($this->knr) {
      $dbwkurse = new DBWorkKurse(1, true);
      $knrAry = explode(':', $this->knr);

      $this->pdf = $this->__initPDF();
      $i = 0;
      $knrCnt = count($knrAry);
      foreach ($knrAry as $knr) {
        $this->knr = $knr;
        $this->kurs = $dbwkurse->getKurs($this->knr);
        if (!$this->_doShowList($this->kurs)) {
          continue;
        }

        $this->_prepare();
        $this->__computeFooterHeight();
        $this->pdf->SetFooterHeight($this->footerHeight);
        
        
        $this->seitennummerManipulation = $this->pdf->PageNo();
        $this->pdf->AddPage();
        $this->_createContent();
        
        if ($i == $knrCnt - 1) {
          $this->_createFusszeilen4LetzteSeite();
        }
        $i++;
      }

      $this->createAdditionalContent();

      if ($pOutputAsString) {
        return $this->pdf->Output('', 'S');
      }

      $this->pdf->Output('', $this->getOutputName());
    }
  }

  protected function getOutputName(): string
  {
    return 'doc.pdf';
  }

  
  protected function _createFusszeilen4LetzteSeite()
  {
    if ($this->settings->fusszeile == LISTEN_FUSSZEILE_LETZTE) {
      $bMargin = $this->pdf->getBottomMargin();
      $this->pdf->SetAutoPageBreak(false, $bMargin);
      $this->__createFusszeilen();
      $this->pdf->SetAutoPageBreak(true, $bMargin);
    }
  }

  public function stringLineBreakKeepLineBreaks($str, $width, $eol = 0, $pTrennzeichen = ' ')
  {
    $str = str_replace("\r", '', $str);
    $strArray = explode("\n", $str);

    $result = array();
    foreach ($strArray as $partStr) {
      $result = array_merge(
        $result,
        $this->stringLineBreak($partStr, $width, $eol, $pTrennzeichen)
      );
    }

    return $result;
  }

  
  public function stringLineBreak($str, $width, $eol = 0, $pTrennzeichen = ' ')
  {

    
    if (StringOperations::substr($width, -1, 1) == '%') { 
      
      $width = StringOperations::substr($width, 0, -1) / 100 * $this->pdf->GetPageWidth();
    } 

    $str = str_replace("\r", '', $str);
    if ($eol == 0) {
      $str = str_replace("\n", $pTrennzeichen, $str);
    }
    $sw = $this->pdf->GetStringWidth($str);


    
    
    if ($sw <= $width) {
      if ($eol == 1) {
        $retour = explode("\n", $str);
      } else {
        $retour = array($str);
      }

      return $retour;
    } else {
      
      if (StringOperations::strstr($str, $pTrennzeichen) === false) {
        return array($str);
      }

      $wordsInArgument = array();
      $star = explode($pTrennzeichen, $str);
      
      
      while ($sw > $width) {
        if ($eol == 1 && \StringOperations::substr_count($star[0], '\\n') != 0) {
          $star[0] = str_replace("\n", $pTrennzeichen, $star[0]);
          
          
          
          if (count($star) > 1) {
            $lastStr = array_pop($star);
            array_unshift($wordsInArgument, $lastStr);
          }
          break;
        }
        
        if (count($star) > 1) {
          $lastStr = array_pop($star);
          
          array_unshift($wordsInArgument, $lastStr);
        } else {
          break;
        }
        $sw = $this->pdf->GetStringWidth(implode($pTrennzeichen, $star));
      }
      
      $retour = array(implode($pTrennzeichen, $star));
      $wordsInArgstr = implode($pTrennzeichen, $wordsInArgument);

      foreach ($this->stringLineBreak($wordsInArgstr, $width) as $st) {
        $retour[] = $st;
      }

      return $retour;
    }
  }

  
  protected function checkBox($pCellWidth, $pCellHeight, $pBorder, $pCheckboxSize = 4, $checked = false)
  {
    if (is_numeric($pCellWidth)) {
      $cellWidthInPixel = $pCellWidth;
    } else {
      $cellWidthInProzent = StringOperations::substr($pCellWidth, 0, -1);
      $cellWidthInPixel = (int)(($cellWidthInProzent / 100) * $this->pdf->GetPageWidth());
    }

    if (is_numeric($pCellHeight)) {
      $cellHeightInPixel = $pCellHeight;
    } else {
      $cellHeightInProzent = StringOperations::substr($pCellHeight, 0, -1);
      $cellHeightInPixel = (int)(($cellHeightInProzent / 100) * $this->pdf->GetPageHeight());
    }


    $x0 = $this->pdf->GetX();
    $y0 = $this->pdf->GetY();

    
    $this->pdf->CellExt($cellWidthInPixel, '', $pBorder, $cellHeightInPixel, 'B');
    $this->pdf->SetXY($x0, $y0); 

    $checkboxSize = $pCheckboxSize;

    $deltaX = (int)(($cellWidthInPixel - $checkboxSize) / 2);
    $deltaY = (int)(($cellHeightInPixel - $checkboxSize) / 2);

    $x0Checkbox = $x0 + $deltaX;
    $y0Checkbox = $y0 + $deltaY;
    $this->pdf->SetXY($x0Checkbox, $y0Checkbox);

    if ($checked) {
      $this->pdf->Line($x0Checkbox, $y0Checkbox, $x0Checkbox + $checkboxSize, $y0Checkbox + $checkboxSize);
      $this->pdf->Line($x0Checkbox + $checkboxSize, $y0Checkbox, $x0Checkbox, $y0Checkbox + $checkboxSize);
    }

    
    $this->pdf->CellExt($checkboxSize, '', '1', $checkboxSize, 'B');

    $this->pdf->SetXY($x0 + $cellWidthInPixel, $y0);
  }

  
  protected function multiLineCell($pCellWidth, $pLineHeight, $pLines, $pMinDisplayLines, $pBorder, $pStyle, $pSize = '', $pPaddingBottom = 0)
  {
    $cellWidthInPixel = $this->pdf->getWidthAbsolute($pCellWidth);

    if (is_int($pLineHeight)) {
      $lineHeightInPixel = $pLineHeight;
    } else {
      $lineHeightInProzent = StringOperations::substr($pLineHeight, 0, -1);
      $lineHeightInPixel = (int)(($lineHeightInProzent / 100) * $this->pdf->GetPageHeight());
    }

    $x0 = $this->pdf->GetX();
    $y0 = $this->pdf->GetY();

    $countLines = count($pLines);
    $linesToRender = $countLines > $pMinDisplayLines ? $countLines : $pMinDisplayLines;

    for ($i = 0; $i < $linesToRender; ++$i) {
      if ($i < $countLines) {
        $this->pdf->CellExt($cellWidthInPixel, $pLines[$i], '', $lineHeightInPixel, $pStyle, $pSize);
      } else {
        
        $this->pdf->CellExt($cellWidthInPixel, ' ', '', $lineHeightInPixel, $pStyle, $pSize);
      }

      
      $this->pdf->SetXY($x0, $y0 + (($i + 1) * $lineHeightInPixel));
    }

    
    $this->pdf->SetXY($x0, $y0);
    $this->pdf->CellExt($cellWidthInPixel, '', $pBorder, $lineHeightInPixel * $linesToRender + $pPaddingBottom, 'B');

    
    $this->pdf->SetXY($x0 + $cellWidthInPixel, $y0);
  }

  protected function convertDontShowBelegungenErrorToString(int $reason, \Kurs $pKurs): string
  {
    switch ($reason) {
      case \BelegungAPI::USER_ALLOWED_TO_SEE_BELEGUNGEN_WENIGER_ALS_MINIMALANZAHL:
        return 'Diese Liste kann für den Kurs ' . $pKurs->kurzbez . ' (' . $pKurs->nr_anzeige . ') nicht erzeugt werden, ' . "\n"
          . 'da die minimale Teilnehmeranzahl noch nicht erreicht wurde.';
      case \BelegungAPI::USER_ALLOWED_TO_SEE_BELEGUNGEN_KURSENDE_ERREICHT:
        return 'Diese Liste kann für den Kurs ' . $pKurs->kurzbez . ' (' . $pKurs->nr_anzeige . ') nicht erzeugt werden, ' . "\n"
          . 'da das Kursende erreicht wurde.';
      case \BelegungAPI::USER_ALLOWED_TO_SEE_BELEGUNGEN_KURSAUSFALL:
        return 'Diese Liste kann für den Kurs ' . $pKurs->kurzbez . ' (' . $pKurs->nr_anzeige . ') nicht erzeugt werden, ' . "\n"
          . 'da der Kurs ausgefallen ist.';
      case \BelegungAPI::USER_ALLOWED_TO_SEE_BELEGUNGEN_ZEITBEREICH:
        return 'Diese Liste kann für den Kurs ' . $pKurs->kurzbez . ' (' . $pKurs->nr_anzeige . ') nicht erzeugt werden, ' . "\n"
          . 'da das Beginn- oder Enddatum außerhalb des erlaubten Zeitbereichs ist.';
      default:
        return 'Diese Liste kann für den Kurs ' . $pKurs->kurzbez . ' (' . $pKurs->nr_anzeige . ') aus unbekannten Gründen nicht erzeugt werden.';
    }
  }

  protected function getNoBelegungenError(\Kurs $pKurs): string
  {
    return 'Diese Liste kann für den Kurs ' . $pKurs->kurzbez . ' (' . $pKurs->nr_anzeige . ') nicht erzeugt werden, '
      . 'da keine Belegungen für diesen Kurs angezeigt werden können.';
  }

  
  private function _doShowList($pKurs, bool $printText = true)
  {
    if (!self::isPrintAllowed($pKurs, $this->toolId, $this->getListID())) {
      if ($printText) {
        $this->printNotAllowed('Diese Liste kann für den Kurs ' . $pKurs->kurzbez . ' (' . $pKurs->nr_anzeige . ') nicht erzeugt werden, ' . "\n"
          . 'da die Liste nicht für den Druck freigegeben ist.');
      }

      return false;
    }

    $isAllowedReason = \BelegungAPI::getUserAllowedToTnReason($pKurs, $this->toolId);

    if ($isAllowedReason !== \BelegungAPI::USER_ALLOWED_TO_SEE_BELEGUNGEN_NO_ERROR) {
      if ($printText) {
        $this->printNotAllowed($this->convertDontShowBelegungenErrorToString($isAllowedReason, $pKurs));
      }

      return false;
    } elseif (empty($this->_getBelegungen($pKurs->id))
        && !(($this->settings->druckbereich->auffuellen ?? false)
          && (($this->settings->druckbereich->auffuellArt ?? '') == 'S'
             || (($this->settings->druckbereich->auffuellArt ?? '') == 'M' && $pKurs->getVarValue('teil_max') > 0))
             && $this->getDruckbereichEnabled('auffuellen'))) {
      if ($printText) {
        $this->printNotAllowed($this->getNoBelegungenError($pKurs));
      }

      return false;
    }

    return true;
  }

  private function printNotAllowed(string $text): void
  {
    $this->_prepare();
    $this->pdf->AddPage();
    $this->pdf->ln();

    $strAry = $this->stringLineBreak($text, '93%');
    foreach ($strAry as $str) {
      $this->pdf->CellAtX('3%', $str, '', '', 10, '100%', 0, 15, '', '');
      $this->pdf->ln();
    }
  }

  
  public function _createContent($pKurs = '')
  {
  }

  
  public function _prepare($pKnr = '')
  {
  }

  
  public function header()
  {
    $this->_createHeader($this->kurs);
  }

  
  public function footer()
  {
    if ($this->settings->fusszeile == LISTEN_FUSSZEILE_ALLE) {
      $this->__createFusszeilen();
    }
  }

  protected function getFusszeilen(): array
  {
    return $this->settings->fusszeilen;
  }

  
  public function __createFusszeilen()
  {
    if (!$this->_doShowList($this->kurs, false)) {
      return;
    }

    $this->pdf->SetY(-($this->footerHeight + $this->pdf->getBMargin()));

    foreach ($this->getFusszeilen() as $fusszeile) {
      $zeilenHoehe = $fusszeile->size == 0 ? FUSSZEILE_STANDARD_GROESSE : $fusszeile->size;
      $this->pdf->CellExt(0, $fusszeile->text, 0, 0, $fusszeile->bold ? 'B' : '', $zeilenHoehe);
      $this->pdf->Ln();
    }
  }

  public function __computeFooterHeight()
  {
    $height = 10;

    
    
    
    $fusszeileMitHoererNummerGefuellt = false;
    foreach (array_reverse($this->getFusszeilen()) as $fusszeile) {
      if ($fusszeile->text != '' || $fusszeileMitHoererNummerGefuellt) {
        $schriftgroesse = (empty($fusszeile->size) ? FUSSZEILE_STANDARD_GROESSE : $fusszeile->size);
        $height += 3 + $schriftgroesse / 10;
        $fusszeileMitHoererNummerGefuellt = true;
      }
    }
    $this->footerHeight = $height;
  }

  
  public function __initPDF()
  {
    
    $pdf = new ExtPDF(5, true, ($this->isHochformat()) ? 'P' : 'L');
    $pdf->SetFont('OpenSans', '', 10);

    
    $pdf->SetHeaderCallback(array($this, 'header'));
    $pdf->SetFooterCallback(array($this, 'footer'));

    return $pdf;
  }

  
  public function _auffuellenBisSeitenende()
  {
    return isset($this->settings->druckbereich->auffuellen) && $this->settings->druckbereich->auffuellen
            && isset($this->settings->druckbereich->auffuellArt) && $this->settings->druckbereich->auffuellArt == 'S'
            && $this->getDruckbereichEnabled('auffuellen');
  }

  
  public function _getBelegungInitDbWork()
  {
    $dbwbelegung = new DBWorkBelegung(1, true);
    $dbwbelegung->newSearch();
    if ($this->settings->sortierung === \webtools\lists\TNSettings::SORT_NAME) { 
      $dbwbelegung->orderby = 't.name, t.vorname';
    } elseif ($this->settings->sortierung === \webtools\lists\TNSettings::SORT_ANMELDEDATUM) { 
      $dbwbelegung->orderby = 'b.anm_datum';
    } elseif ($this->settings->sortierung === \webtools\lists\TNSettings::SORT_FIRMENNAME) { 
      $dbwbelegung->orderby = 'fa.name, fa.vorname, t.name, t.vorname';
    }

    
    
    switch ($this->settings->umfang->filter) {
      case 'C': 
        $dbwbelegung->fromobject->status = $this->settings->umfang->customStatus;
        break;
      case 'A': 
        
        $dbwbelegung->fromobject->status = 'AT-';
        break;
    }

    return $dbwbelegung;
  }

  
  public function _getBelegungen($knr)
  {
    $dbwbelegung = $this->_getBelegungInitDbWork();

    

    
    $belegungen = $dbwbelegung->getBelegungenbyKursNR($knr);

    
    if (($this->settings->druckbereich->auffuellen ?? false)
        && ($this->settings->druckbereich->auffuellArt ?? '') == 'M') {
      
      while (count($belegungen) < $this->kurs->getVarValue('teil_max')) {
        $belegungen[] = null;
      }
    }

    
    return $belegungen;
  }

  
  public function _getHeaderKursText($pKurs)
  {
    $text = $pKurs->nr_anzeige . ' ' . str_replace(array("\r\n"), array(' '), $pKurs->kurzbez);
    $font = 'OpenSans';
    $fontSize = 10;
    $fontStyle = 'B';

    if ($this->isHochformat()) {
      $maxLength = 145;
      $text = \ExtPDF::kuerzeText($text, $maxLength, $font, $fontSize, $fontStyle);
    } else {
      $maxLength = 150;
      $text = \ExtPDF::kuerzeText($text, $maxLength, $font, $fontSize, $fontStyle);
    }

    return $text;
  }

  
  public function isHochformat()
  {
    return isset($this->settings->druckbereich->hochformat) && $this->settings->druckbereich->hochformat;
  }

  
  private function _getPositionen4Header()
  {
    if ($this->isHochformat()) {
      return array(
        'label1' => '6%',
        'wert1' => '17%',
        'label2' => '34%',
        'wert2' => '40%',
        'label3' => '61%',
        'wert3' => '74%',
        'label4' => '78%',
        'wert4' => '90%'
      );
    } else {
      return array(
        'label1' => '4%',
        'wert1' => '12%',
        'label2' => '23%',
        'wert2' => '29%',
        'label3' => '67%',
        'wert3' => '79%',
        'label4' => '80%',
        'wert4' => '91%'
      );
    }
  }

  
  public function _createHeader(\Kurs $pKurs)
  {
    $logoFilePath = PDFLogo::getLogoFilePath();
    if (PDFLogo::printLogoImg($this->pdf, $logoFilePath)) {
      $this->pdf->ln(9);
    } else {
      $this->pdf->ln();
    }

    $position = $this->_getPositionen4Header();

    $this->_createVhsName4Header($position['label1']);
    $this->_createUeberschrift4Header();
    $this->_createDruckinfo4Header($pKurs);
    $this->pdf->Ln(6.5);

    
    $this->_createKurszeile4Header($pKurs, $position);

    if ($this->isHochformat()) {
      $this->pdf->CellAtX($position['label4'], 'Seite:', '', 'R', 0, '13%');
      $this->pdf->CellAtX($position['wert4'], $this->pdf->PageNo() - $this->seitennummerManipulation, '', 'R', 0, '5%');
    } else {
      if ($this->showAussenstelle() && $pKurs->aussenst != '') {
        $this->pdf->CellAtX($position['label3'], 'Außenstelle:', '', 'R', '', '12%');
        $this->pdf->CellAtX($position['wert3'], $pKurs->aussenst);
      }
    }
    $this->pdf->Ln(6);

    
    $this->showHinweisKeinFolgeKurs();

    if (!$this->settings->kopfbereich->ohneKursOrt) {
      
      $this->pdf->CellAtX($position['label1'], $this->sprachSettings->Kursort['Singular']['Nominativ'] . ':');
      $lengthKursOrtBez = StringOperations::strlen($this->sprachSettings->Kursort['Singular']['Nominativ']);
      if ($lengthKursOrtBez >= 12) {
        $faktor = $this->isHochformat() ? 8 : 10;
        $this->pdf->CellAtX(((int)$position['wert1'] + $lengthKursOrtBez - $faktor) . '%', $pKurs->ort);
      } else {
        $this->pdf->CellAtX($position['wert1'], $pKurs->ort);
      }
    }
    if ($this->settings->kopfbereich->mitKursgebuehren) {
      $this->pdf->CellAtX($position['label3'], $this->sprachSettings->Kursgebuehr['Singular']['Nominativ'] . ':', '', 'R', '', '12%');
      $this->pdf->CellAtX($position['wert3'], "$pKurs->gebuehr ", '', 'R', '', '8%');
    }

    $tnAnzahlCalc = $this->getTnAnzahlCalc($pKurs);
    $this->pdf->CellAtX($position['label4'], 'aktuell:', 'B', 'R', 0, '13%');
    $this->pdf->CellAtX($position['wert4'], (string)$tnAnzahlCalc, 'B', 'R', 0, '5%');
    $this->pdf->Ln();

    

    $wtUser = SessionOperations::getCurrentWebToolsUser();
    $tool0Settings = ToolSettingsAPI::getToolSettings(0);
    $dbwDozenten = new DBWorkDozenten(1, true);

    if ($tool0Settings->kurstageNurVonEingeloggtemDozent && $wtUser->dnr > 0 && $dbwDozenten->hasDozentKurs($wtUser->dnr, $pKurs->id)) {
      $dozentenAry = array($dbwDozenten->getDozent($wtUser->dnr));
    } else {
      $dozentenAry = $dbwDozenten->getDozenten4KursTnListen($pKurs->id);
    }

    $dozCount = count($dozentenAry);
    $this->pdf->CellAtX(
      $position['label1'],
      ($dozCount === 1 ? $this->sprachSettings->Dozent['Singular']['Nominativ'] : $this->sprachSettings->Dozent['Plural']['Nominativ']) . ':'
    );
    $dozent = '';
    for ($i = 0; $i < $dozCount; $i++) {
      $dozentenObj = $dozentenAry[$i];
      if ($dozentenObj->name_titel != '') {
        $dozent .= $dozentenObj->name . ', ' . $dozentenObj->name_titel . ' ' . $dozentenObj->vorname;
      } else {
        $dozent .= $dozentenObj->namevorname;
      }
      if ($this->settings->kopfbereich->mitDozentenTelNr) {
        $tel = $dozentenObj->getTelNrs();
        $tel = StringOperations::trimToLastSpace($tel, 40);
        
        if (StringOperations::substr($tel, -1) == ',') {
          $tel = StringOperations::substr($tel, 0, -1);
        }
        if (!empty($tel)) {
          $dozent .= ' (' . $tel . ')';
        }
      }
      if ($i < $dozCount - 1) {
        $dozent .= '; ';
      }
    }
    $this->pdf->CellAtX($position['wert1'], $dozent, '', '', '', '50%');

    if ($this->settings->kopfbereich->mitKursgebuehren && $pKurs->geb_erm != $pKurs->gebuehr && MathOperations::stringToFloat($pKurs->geb_erm) != 0) {
      $dbwBasysSettings = new DBWorkBASysSettings();
      $basysSetting = $dbwBasysSettings->getSettings();

      if (!$basysSetting->ohneErmaessigung) {
        $this->pdf->CellAtX($position['label3'], 'Ermäßigt:', '', 'R', '', '12%');
        $this->pdf->CellAtX($position['wert3'], "$pKurs->geb_erm ", '', 'R', '', '8%');
      }
    }

    
    
    $this->pdf->CellAtX($position['label4'], $this->_getWartelisteText(), '', 'R', 0, '13%');
    $this->pdf->CellAtX($position['wert4'], $this->_getWartelisteValue($pKurs), '', 'R', 0, '5%');
    $this->pdf->Ln();

    
    $beginn = $pKurs->getVarValue('beginn_dat_komplettkurz_mit_beginn');
    $this->pdf->CellAtX($position['label1'], $beginn !== '' ? 'Beginn:' : '');
    $this->pdf->CellAtX($position['wert1'], $beginn);
    $ende = $pKurs->getVarValue('ende_dat_komplettkurz_mit_ende');
    $this->pdf->CellAtX($position['label2'], $ende !== '' ? 'Ende:' : '', '', 'R', 0, '6%');
    $this->pdf->CellAtX($position['wert2'], $ende);
    if (!$this->settings->kopfbereich->ohneMinMaxTN) {
      $this->pdf->CellAtX($position['label4'], $this->getTextMinTn($pKurs), '', 'R', 0, '13%');
      $this->pdf->CellAtX($position['wert4'], $this->getValueMinTn($pKurs), '', 'R', 0, '5%');
    }
    $this->pdf->Ln();

    
    if (!$this->settings->kopfbereich->ohneDauer) {
      $this->pdf->CellAtX($position['label1'], 'Dauer:');
      $this->pdf->CellAtX($position['wert1'], $pKurs->dauer);
      $this->pdf->CellAtX($position['label2'], 'UE:', '', 'R', 0, '6%');
      $this->pdf->CellAtX($position['wert2'], MathOperations::floatToString($pKurs->stundenanz));
    }
    if ($this->settings->kopfbereich->mitDauerdetails) {
      $this->pdf->CellAtX('45%', 'Dauerdetails: ' . $pKurs->dauerdetai);
    }
    if (!$this->settings->kopfbereich->ohneMinMaxTN) {
      $this->pdf->CellAtX($position['label4'], $this->getTextMaxTn($pKurs), '', 'R', 0, '13%');
      $this->pdf->CellAtX($position['wert4'], $this->getValueMaxTn($pKurs), '', 'R', 0, '5%');
    }
    $this->pdf->Ln(8);
  }

  protected function getTnAnzahlCalc(\Kurs $kurs): int
  {
    $result = \Kufer\Web\Classes\Ampel\AmpelStatus\Ampel4StatusBerechnungsInfos::fromKursTeilnehmer($kurs)->tnKiZahlen->anzahl;
    if ($kurs->isHybridkurs()) {
      $result += \Kufer\Web\Classes\Ampel\AmpelStatus\Ampel4StatusBerechnungsInfos::fromHybridkursOnlineTeilnehmer($kurs)->personenZahlen->anzahl;
    }

    return $result;
  }

  
  protected function showHinweisKeinFolgeKurs()
  {
  }

  
  private function _createVhsName4Header($pPosition)
  {
    $allgsettings = AllgSettingsAPI::getAllgSettings();
    $vhsName = StringOperations::html_entity_decode($allgsettings->vhsname);

    $onePercentWidth = $this->pdf->GetPageWidth() / 100;
    $vhsNameFieldWidth = $onePercentWidth * 30;

    $currentFontSize = $this->pdf->getFontSizePt();
    $currentFontStyle = $this->pdf->getFontStyle();

    for ($size = 11; $size > 0; $size--) {
      $this->pdf->SetFontSize($size);
      $this->pdf->SetFontStyle('B');
      if ($this->pdf->GetStringWidth($vhsName) <= $vhsNameFieldWidth) {
        $this->pdf->CellAtX($pPosition, $vhsName, 'B', '', $size, '31%');
        break;
      }
    }
    
    
    $this->pdf->SetFontSize($currentFontSize);
    $this->pdf->SetFontStyle($currentFontStyle);
  }

  
  private function _createUeberschrift4Header()
  {
    
    if ($this->isHochformat()) {
      $start = '40%';
      $schrifgroesse = 12;
    } else {
      $start = '30%';
      $schrifgroesse = 14;
    }
    $this->pdf->CellAtX($start, StringOperations::html_entity_decode($this->settings->caption), 'B', '', $schrifgroesse);
  }

  
  private function _createDruckinfo4Header($pKurs)
  {
    if ($this->isHochformat()) {
      $this->pdf->CellAtX('78%', 'Stand: ' . $this->dtop->getDateNow(), '', 'R', 0, '17%');
    } else {
      $this->pdf->CellAtX('65%', "Semester: $pKurs->semester");
      $this->pdf->CellAtX('77%', 'Stand: ' . $this->dtop->getDateNow());
      $this->pdf->CellAtX('89%', 'Seite:');
      $this->pdf->CellAtX('90%', $this->pdf->PageNo() - $this->seitennummerManipulation, '', 'R', 0, '6%');
    }
  }

  
  private function _createKurszeile4Header($pKurs, $pPosition)
  {
    $lengthKursSingularNominativ = StringOperations::strlen($this->sprachSettings->Kurs['Singular']['Nominativ']);
    if ($this->isHochformat()) {
      if ($lengthKursSingularNominativ > 6) {
        $startWert = ((float)$pPosition['wert1'] + $lengthKursSingularNominativ - 4) . '%';
      } else {
        $startWert = '16%';
      }
      $schriftgroesse = '';
    } else {
      if ($lengthKursSingularNominativ > 5) {
        $startWert = ((float)$pPosition['wert1'] + $lengthKursSingularNominativ - 4) . '%';
      } else {
        $startWert = $pPosition['wert1'];
      }
      $schriftgroesse = 12;
    }
    $this->pdf->CellAtX($pPosition['label1'], 'für ' . $this->sprachSettings->Kurs['Singular']['Nominativ'] . ':', 'B', '', $schriftgroesse);
    $this->pdf->CellAtX($startWert, $this->_getHeaderKursText($pKurs), 'B', '', $schriftgroesse);
  }

  
  public function _getWartelisteValue($pKurs)
  {
    return $pKurs->getVarValue('teil_wart');
  }

  
  public function _getWartelisteText()
  {
    return 'Warteliste:';
  }

  
  public function _getBemerkung($belegung)
  {
    if ($belegung == null) {
      return '';
    }

    switch ($this->settings->bemerkung) {
      case 'I': 
        return $belegung->bemerkung;
      case 'E': 
        return $belegung->bemerk_ext;
      case 'IE': 
        return $belegung->bemerkung . (trim($belegung->bemerk_ext) !== '' ? "; $belegung->bemerk_ext" : '');
        
      case 'EI': 
        return $belegung->bemerk_ext . (trim($belegung->bemerkung) !== '' ? "; $belegung->bemerkung" : '');
        
    }

    return '';
  }

  

  
  public static function ausgabeFault($pWarntext = '')
  {
    if ($pWarntext == '') {
      return;
    }
    echo
         "<center>\n"
         . "<p style='font-family: arial; color: #FF0000;'>" . CleanOperations::cleanStringForHtml($pWarntext) . "</p>\n"
         . "<p><a href='javascript:window.close();'><img boarder='0' src='layout/button_close.gif' alt='schliessen' title='Schliessen' /></a> <p>\n"
         . '</center>';
  }

  
  public static function getWarning()
  {
    return ' Sie haben keine Zugriffsberechtigung auf einen oder mehrere der angefragten Kurse. Bitte setzen Sie sich mit der Einrichtung'
           . ' in Verbindung, damit diese Ihnen die entsprechenden Rechte gibt.';
  }

  

  
  public function isAllowedToPrint4User()
  {
    
    
    if (in_array($this->toolId, array(\ToolsAPI::TOOL_DOZENTENINFO_MA, \ToolsAPI::TOOL_RAUMBELEGUNG_HM, 55))) {
      $allowedNrAry = explode(':', SessionOperations::getVarValueWTIntern('totalkursdatastr_' . $this->toolId));
    } else {
      
      $allowedNrAry = explode(':', SessionOperations::getVarValueWTIntern('totaldatastr_' . $this->toolId));
    }

    return $this->isKnrInArray($allowedNrAry);
  }

  
  protected function isKnrInArray($pArray)
  {
    
    
    $knrAry = explode(':', $this->knr);
    foreach ($knrAry as $knr) {
      if (!in_array($knr, $pArray)) {
        return false;
      }
    }

    return true;
  }

  
  public static function isPrintAllowed($pKurs, $pToolId, $pListeId)
  {
    if (!isset($pKurs)) {
      return true;
    }

    $toolSettings = ToolSettingsAPI::getToolSettings($pToolId);
    $druckTnListeSettingsAry = SerializeOperations::unserialize($toolSettings->druckTnListeSettings);

    $now = \DateTimeOperations::getDateNow();

    $earlierDates = array(
      self::getPrintAllowedEarlierDateKursende($druckTnListeSettingsAry, $pListeId, $pKurs),
      self::getPrintAllowedEarlierDateKursbeginn($druckTnListeSettingsAry, $pListeId, $pKurs)
    );

    foreach ($earlierDates as $earlierDate) {
      if (!is_null($earlierDate) && !\DateTimeOperations::isDateBefore($earlierDate, \DateTimeOperations::addDays($now, 1))) { 
        return false;
      }
    }

    $laterDates = array(
      self::getPrintAllowedLaterDateKursende($druckTnListeSettingsAry, $pListeId, $pKurs),
      self::getPrintAllowedLaterDateKursbeginn($druckTnListeSettingsAry, $pListeId, $pKurs)
    );

    foreach ($laterDates as $laterDate) {
      if (!is_null($laterDate) && !\DateTimeOperations::isDateAfter(\DateTimeOperations::addDays($laterDate, 1), $now)) { 
        return false;
      }
    }

    return true;
  }

  private static function getPrintAllowedEarlierDateKursende($pDruckTnListeSettingsAry, $pListeId, $pKurs): ?string
  {
    if (isset($pDruckTnListeSettingsAry['vorKursende' . $pListeId]) && trim($pDruckTnListeSettingsAry['vorKursende' . $pListeId]) != '') {
      $vorKursende = $pDruckTnListeSettingsAry['vorKursende' . $pListeId] ?? 0;

      return DateTimeOperations::addDays($pKurs->getVarValue('ende_dat'), -1 * $vorKursende);
    } else {
      return null;
    }
  }

  private static function getPrintAllowedEarlierDateKursbeginn($pDruckTnListeSettingsAry, $pListeId, $pKurs): ?string
  {
    if (isset($pDruckTnListeSettingsAry['vorKursbeginn' . $pListeId]) && trim($pDruckTnListeSettingsAry['vorKursbeginn' . $pListeId]) != '') {
      $vorKursbeginn = $pDruckTnListeSettingsAry['vorKursbeginn' . $pListeId] ?? 0;

      return DateTimeOperations::addDays($pKurs->getVarValue('beginn_dat'), -1 * $vorKursbeginn);
    } else {
      return null;
    }
  }

  private static function getPrintAllowedLaterDateKursende($pDruckTnListeSettingsAry, $pListeId, $pKurs): ?string
  {
    if (isset($pDruckTnListeSettingsAry['nachKursende' . $pListeId]) && trim($pDruckTnListeSettingsAry['nachKursende' . $pListeId]) != '') {
      $nachKursende = $pDruckTnListeSettingsAry['nachKursende' . $pListeId] ?? 0;

      return DateTimeOperations::addDays($pKurs->getVarValue('ende_dat'), $nachKursende);
    } else {
      return null;
    }
  }

  private static function getPrintAllowedLaterDateKursbeginn($pDruckTnListeSettingsAry, $pListeId, $pKurs): ?string
  {
    if (isset($pDruckTnListeSettingsAry['nachKursbeginn' . $pListeId]) && trim($pDruckTnListeSettingsAry['nachKursbeginn' . $pListeId]) != '') {
      $nachKursbeginn = $pDruckTnListeSettingsAry['nachKursbeginn' . $pListeId] ?? 0;

      return DateTimeOperations::addDays($pKurs->getVarValue('beginn_dat'), $nachKursbeginn);
    } else {
      return null;
    }
  }

  public function getListBezeichnungForHTML()
  {
    return '';
  }

  protected function showAussenstelle()
  {
    return true;
  }

  protected function createAdditionalContent()
  {
    if (DBWorkBASysSettings::isHeleneWeberHaus()) {
      $this->pdf = \Kufer\Webtools\Lists\HeleneWeberHaus\Datenschutzerklaerung::printDatenschutzerklaerung($this->pdf);
    }
  }

  
  protected function getTextMinTn($pKurs)
  {
    return 'min:';
  }

  
  protected function getTextMaxTn($pKurs)
  {
    return 'max:';
  }

  
  protected function getValueMinTn($pKurs)
  {
    return $pKurs->getVarValue('teil_min');
  }

  
  protected function getValueMaxTn($pKurs)
  {
    return $pKurs->getVarValue('teil_max');
  }
}