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

namespace Kufer\KuferTools\Mitarbeiter\RaumUebersicht\QuartalsUebersicht;

class QuartalsUebersichtPdfUseCase extends \Kufer\KuferTools\Basis\UseCase\ToolUseCase
{
  public const HAUPT_ZELLEN_LAENGE_1_KURSTAG = 72.2;
  public const HAUPT_ZELLEN_LAENGE_MEHRERE_KURSTAGE = 69.5;

  public function __construct($request)
  {
    parent::__construct($request, new QuartalsUebersichtPdfResponse());
  }

  public static function getToolId()
  {
    return \ToolsAPI::TOOL_RAUMBELEGUNG_MA;
  }

  public static function getToolSectionId()
  {
    return 415;
  }

  public function hasAccess($pToolSectionId = null)
  {
    if (!parent::hasAccess()) {
      return false;
    }
    if (!$this->isRechtAllowed('415.0.6') && !$this->isRechtAllowed('417.0.3')) {
      return false;
    }

    return true;
  }

  public function action()
  {
    $pdf = $this->getPdf();

    return $this->getResponse($pdf);
  }

  protected function getKurstage($pRaumId)
  {
    $dbwKurstage = \DBWorkKurseTage::getDefaultInstance();
    $dbwKurstage->newSearch();
    $dbwKurstage->fromobject->datum = $this->getFirstDatumOfCurrentQuartal();

    $kurstage = $dbwKurstage->getKurstagebyRaum($pRaumId);

    if (\DBWorkBASysSettings::isGarchingVhs()) {
      $kurstageFromKursplanungen = $this->getKurstageFromKursplanungen($pRaumId);
      $kurstage = array_merge($kurstage, $kurstageFromKursplanungen);
    }

    $kurstageAssoc = array();
    foreach ($kurstage as $kurstag) {
      if (!isset($kurstageAssoc[$kurstag->datum])) {
        $kurstageAssoc[$kurstag->datum] = array();
      }
      $kurstageAssoc[$kurstag->datum][] = $kurstag;
    }

    return $kurstageAssoc;
  }

  protected function getResponse($pPdf)
  {
    $this->response->pdf = $pPdf;

    return $this->response;
  }

  protected function getPdf()
  {
    $pdf = new \ExtPDF(5, true, 'L'); 

    foreach ($this->request->raumIds as $raumId) {
      $this->createHeaderAndContent($pdf, $raumId);
    }

    return $pdf;
  }

  protected function createHeaderAndContent($pdf, $pRaumId)
  {
    $kurstage = $this->getKurstage($pRaumId);

    if (empty($kurstage)) {
      $pdf->AddPage();
      $this->createHeader($pdf, $pRaumId);
      $pdf->CellAtX('6.8%', 'Es wurden keine Termine gefunden!', 'B', '', 11, '78.4%');

      return $pdf;
    }

    $firstLastDatum = \DateTimeOperations::getFirstAndLastDatum(array_keys($kurstage));
    $firstQuartal = \DateTimeOperations::getQuartal($firstLastDatum['first']);
    $firstYear = (int)\DateTimeOperations::getYear($firstLastDatum['first']);
    $lastQuartal = \DateTimeOperations::getQuartal($firstLastDatum['last']);
    $lastYear = (int)\DateTimeOperations::getYear($firstLastDatum['last']);

    $currentQuartal = $firstQuartal;
    $currentYear = $firstYear;
    while ($currentYear <= $lastYear) {
      $lastQuartalOfYear = $currentYear == $lastYear ? $lastQuartal : 4;
      while ($currentQuartal <= $lastQuartalOfYear) {
        $pdf->AddPage();
        $this->createHeader($pdf, $pRaumId);
        $this->createContent($pdf, $kurstage, $currentQuartal, $currentYear);
        $currentQuartal++;
      }
      $currentQuartal = 1;
      $currentYear++;
    }
  }

  
  protected function createHeader($pPdf, $pRaumId)
  {
    $kursort = $this->getKursort($pRaumId);

    $pPdf->SetFont('OpenSans', '', 8);
    
    
    $pPdf->CellAtX('6.8%', \StringOperations::html_entity_decode($this->getVhsName()), 'B', '', 14);
    $pPdf->CellAtX('85.2%', 'Stand: ' . \DateTimeOperations::getDateNow());
    $pPdf->Ln(6);
    
    $pPdf->CellAtX('6.8%', 'Quartalsübersicht für ' . $kursort->mktext, 'B', '', 12, '78.4%');
    $pPdf->CellAtX('85.2%', 'Seite:         ' . $pPdf->PageNo());
    $pPdf->Ln(10);
  }

  
  protected function createContent($pPdf, $pKurstage, $pQuartal, $pJahr)
  {
    $height = 5;
    $border = 1;
    $width = 30;

    $pPdf->SetFillColor(175, 175, 175); 
    for ($i = 0; $i < 3; $i++) {
      $pPdf->SetFont('OpenSans', '', 8);
      $x = $i * ($width + 0.5) + 4.5;
      $monat = $pQuartal * 3 - 2 + $i;
      $monatBezeichnung = \DateTimeObj::$_monthMap[$monat];
      $pPdf->CellAtX($x . '%', '', 'B', '', 0, $width . '%', $border, 5);
      $pPdf->Ln(0.2);
      $pPdf->CellAtX($x . '%', $monatBezeichnung . ' ' . $pJahr, 'B', '', 0, $width . '%', 0, 5);
      $pPdf->Ln($height - 0.2);

      $anzTage = \DateTimeOperations::getAnzTageImMonat($monat, $pJahr);
      for ($j = 1; $j <= $anzTage; $j++) {
        $pPdf->SetFont('OpenSans', '', 6);
        $tagMonat = \StringOperations::pad($j, 2, '0', STR_PAD_LEFT) . '.' . \StringOperations::pad($monat, 2, '0', STR_PAD_LEFT) . '.';
        $datum = $tagMonat . $pJahr;
        $wotagKurz = \DateTimeOperations::getWeekDayShort($datum);
        $fill = in_array($wotagKurz, array('Sa.', 'So.'));
        $pPdf->CellAtX($x . '%', '', '', '', 0, '5%', $border, $height, $fill);
        $pPdf->Ln(0.2);
        $pPdf->CellAtX($x . '%', $wotagKurz . ', ', '', '', 0, '5%', 0, $height);
        $pPdf->CellAtX(($x + 2) . '%', $tagMonat, '', '', 0, '3%', 0, $height);
        $pPdf->Ln(-0.2);

        if (isset($pKurstage[$datum])) {
          $this->fillHauptZellenInhalt($pPdf, $pKurstage[$datum], $border, $height, $x + 5);
        } else {
          $pPdf->CellAtX(($x + 5) . '%', '', '', '', 0, '25%', $border, $height); 
        }

        $pPdf->Ln($height);
      }

      $pPdf->Ln(-$height * ($anzTage + 1));
    }
  }

  
  protected function fillHauptZellenInhalt($pPdf, $pKurstage, $pBorder, $pHeight, $pX)
  {
    $anzKurstage = count($pKurstage);
    $width = 25 / $anzKurstage;
    for ($i = 0; $i < $anzKurstage; $i++) {
      $x = ($i * $width + $pX) . '%';
      $uhrzeit = $pKurstage[$i]->zeit_beg . ' - ' . $pKurstage[$i]->zeit_ende;
      $textAusfall = ($pKurstage[$i]->ausfall == 'A' ? 'Ausfall! ' : '');

      if ($anzKurstage === 1) {
        $maxLaengeZelle = self::HAUPT_ZELLEN_LAENGE_1_KURSTAG;
      } else {
        $maxLaengeZelle = self::HAUPT_ZELLEN_LAENGE_MEHRERE_KURSTAGE / $anzKurstage;
      }

      $titel = $this->getKursTitel($pKurstage[$i]);
      $titel = $this->kuerzeText($pPdf, $titel, $maxLaengeZelle);

      $maxLaengeZweiteZeile = $maxLaengeZelle - $pPdf->GetStringWidth($textAusfall);
      $textZweiteZeile = $uhrzeit;
      $textZweiteZeile = $this->kuerzeText($pPdf, $textZweiteZeile, $maxLaengeZweiteZeile);

      $xZweiteZeile = ((float)$x + ($textAusfall != '' ? 3 : 0)) . '%';

      $pPdf->CellAtX($x, '', '', '', 0, $width . '%', $pBorder, $pHeight); 
      $pPdf->Ln(-1);
      $pPdf->CellAtX($x, $titel, '', '', 0, $width . '%', 0, $pHeight / 2);
      $pPdf->Ln(2.25);
      $pPdf->CellAtX($x, $textAusfall, 'B', '', 0, $width . '%', 0, $pHeight / 2);
      $pPdf->CellAtX($xZweiteZeile, $textZweiteZeile, '', '', 0, $width . '%', 0, $pHeight / 2);
      $pPdf->Ln(-1.25);
    }
  }

  
  protected function kuerzeText($pPdf, $pText, $pMaxLaenge)
  {
    if ($pMaxLaenge <= 0) {
      return '';
    }

    $laengeText = $pPdf->GetStringWidth($pText);
    if ($laengeText > $pMaxLaenge) {
      $maxLaengeNeuerText = $pMaxLaenge - $pPdf->GetStringWidth('...');
      while ($laengeText > $maxLaengeNeuerText) {
        $pText = \StringOperations::substr($pText, 0, -1);
        $laengeText = $pPdf->GetStringWidth($pText);
      }
      $pText .= '...';
    }

    return $pText;
  }

  
  protected function getFirstDatumOfCurrentQuartal()
  {
    $datum = \DateTimeOperations::getDateNow();
    $monat = \DateTimeOperations::getMonth($datum);
    $jahr = \DateTimeOperations::getYear($datum);
    $quartal = ceil((int)$monat / 3);
    $ersterMonatVomQuartal = $quartal * 3 - 2;

    return '01.' . \StringOperations::lpad($ersterMonatVomQuartal, 2, '0') . '.' . $jahr;
  }

  
  protected function getKursort($pRaumId)
  {
    $dbwKursorte = \DBWorkKursorte::getDefaultInstance();

    return $dbwKursorte->getKursort($pRaumId);
  }

  
  private function getKursplanungen($pRaumId)
  {
    $dbwKursplanung = \DBWorkKursplanung::getDefaultInstance();

    $kursort = $this->getKursort($pRaumId);
    $raumBezeichnung = $kursort->mktext;
    $datumVon = $this->getFirstDatumOfCurrentQuartal();

    return $dbwKursplanung->getKursplanungen4Grafiken(array($raumBezeichnung), $datumVon);
  }

  
  protected function getKurstageFromKursplanungen($pRaumId)
  {
    $kurstage = array();
    $kursplanungen = $this->getKursplanungen($pRaumId);

    foreach ($kursplanungen as $kursplanung) {
      $addDays = 1;
      
      if ($kursplanung->kurstage_anlegen) {
        $addDays = 7;
      }

      $datum = $kursplanung->beginn_dat;
      while (\DateTimeOperations::isDateBetween($kursplanung->beginn_dat, $kursplanung->ende_dat, $datum)) {
        $kurstag = new \Kurstag();
        $kurstag->isKursplanung = true;
        $kurstag->kursplanungTitel = $kursplanung->titel;
        $kurstag->kursplanungKurzbez = $kursplanung->kurzbez;
        $kurstag->knr = $kursplanung->knr;
        $kurstag->datum = $datum;
        $kurstag->zeit_beg = $kursplanung->beginn;
        $kurstag->zeit_ende = $kursplanung->ende;

        $kurstage[] = $kurstag;
        $datum = \DateTimeOperations::addDays($datum, $addDays);
      }
    }

    return $kurstage;
  }

  protected function getKursTitel($pKurstag)
  {
    if (isset($pKurstag->isKursplanung) && $pKurstag->isKursplanung) {
      $titel = $pKurstag->kursplanungTitel;
      $kurzbez = $pKurstag->kursplanungKurzbez;
    } else {
      $dbwKurse = \DBWorkKurseWT::getDefaultInstance();
      $kurs = $dbwKurse->getKurs($pKurstag->knr);
      $titel = $kurs->titel;
      $kurzbez = $kurs->kurzbez;
    }

    return $titel != '' ? str_replace(array("\n\r", "\r\n"), array(' ', ' '), $titel) : $kurzbez;
  }

  private function getVhsName()
  {
    if (\DBWorkBASysSettings::isGarchingVhs()) {
      $result = 'Kulturzentrum';
    } else {
      $allgsettings = \AllgSettingsAPI::getAllgSettings();
      $result = $allgsettings->vhsname;
    }

    return $result;
  }
}

class QuartalsUebersichtPdfRequest
{
  public $raumIds;
}

class QuartalsUebersichtPdfResponse extends \Kufer\KuferTools\Basis\UseCase\ToolResponse
{
  public $pdf;
}