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

class KursplanungAPI
{
  public function __construct()
  {
  }

  
  public function planKurs($kursplanung)
  {
    $abgleichAPI = new AbgleichAPI();

    if (!$abgleichAPI->isAktiviert()) {
      return 'nichtAktiviert';
    }

    
    self::_insertKursplanungReplikat($kursplanung);

    $message = new XMLNode('kurse');
    $kursNode = XMLNode::getXMLNode($kursplanung, 'kurs', array(), true);

    if (is_array($kursplanung->dokumente) && count($kursplanung->dokumente) > 0) {
      $dokumenteNode = new XMLNode('dokumente');
      foreach ($kursplanung->dokumente as $dokument) {
        $dokumenteNode->addChild(XMLNode::getXMLNode($dokument, 'dokument', array(), true));
      }
      $kursNode->addChild($dokumenteNode);
    }


    
    if (is_array($kursplanung->dozenten) && count($kursplanung->dozenten) > 0) {
      $dozentenNode = new XMLNode('dozenten');
      foreach ($kursplanung->dozenten as $dozent) {
        $dozNode = XMLNode::getXMLNode($dozent, 'dozent', array(), true);

        if (is_array($dozent->kommunikation)) {
          $kommNode = new XMLNode('kommunikationen');
          foreach ($dozent->kommunikation as $komm) {
            $kommNode->addChild(XMLNode::getXMLNode($komm, 'kommunikation', array(), true));
          }
          $dozNode->addChild($kommNode);
        }
        $dozentenNode->addChild($dozNode);
      }
      $kursNode->addChild($dozentenNode);
    }

    if (is_array($kursplanung->werbemittel) && count($kursplanung->werbemittel) > 0) {
      $werbemittelNode = new XMLNode('werbemittel_list');
      foreach ($kursplanung->werbemittel as $werbemittel) {
        $werbemittelNode->addChild(XMLNode::getXMLNode($werbemittel, 'werbemittel', array(), true));
      }
      $kursNode->addChild($werbemittelNode);
    }


    if (!is_null($kursplanung->kursortObj)) {
      $kursortNode = new XMLNode('kursort_objekte');
      $kursortNode->addChild(XMLNode::getXMLNode($kursplanung->kursortObj, 'kursort', array(), true));
      $kursNode->addChild($kursortNode);
    }


    $message->addChild($kursNode);

    
    try {
      $abgleichAPI->sendeNachricht(
        AbgleichAPI::ABGLEICH_KURSPLANUNG,
        new Nutzlast($message)
      );
    } catch (\Exception $e) {
      self::_deleteKursplanungReplikat($kursplanung->id);
      throw $e;
    }
  }

  
  protected static function _insertKursplanungReplikat($pKursplanung)
  {
    $dbwKursplanung = new DBWorkKursplanung(1, true);
    $dbwKursplanung->insert($pKursplanung);

    return true;
  }

  
  public static function deleteKursplanung($pKursplanungId)
  {
    $allgsettings = AllgSettingsAPI::getAllgSettings();
    if (SessionOperations::isReplikat()) {
      if ($allgsettings->dmzEnabled) {
        return static::_deleteKursplanungDmz($pKursplanungId);
      } else {
        return static::_deleteKursplanungReplikat($pKursplanungId);
      }
    } else {
      return static::_deleteKursplanungDirekt($pKursplanungId);
    }
  }

  
  protected static function _deleteKursplanungDirekt($pKursplanungId)
  {
    $dbwKursplanung = new DBWorkKursplanung(1, true);
    $dbwKursplanung->deleteKursplanung($pKursplanungId);

    return true;
  }

  
  protected static function _deleteKursplanungReplikat($pKursplanungId)
  {
    $dbwKursplanung = new DBWorkKursplanung(1, true);
    $dbwKursplanung->deleteKursplanung($pKursplanungId);

    return true;
  }

  
  private static function _deleteKursplanungDmz($pKursplanungId)
  {
    try {
      $idNode = new XMLNode('id', $pKursplanungId);
      $kursplanungNode = new XMLNode('kursplanung');
      $kursplanungNode->addChild($idNode);
      $message = new XMLNode('kursplanungen');
      $message->addChild($kursplanungNode);

      $abgleichAPI = new AbgleichAPI();
      $abgleichAPI->sendeNachricht(
        AbgleichAPI::ABGLEICH_KURSPLANUNG_DELETE,
        new Nutzlast($message)
      );
      static::_deleteKursplanungDirekt($pKursplanungId);

      return true;
    } catch (AbgleichApiException $aae) {
      Logger::logg('Kursplanung löschen - folgende Exception ist aufgetreten: ' . $aae->getMessage() . "\n" . ' [' . $aae->getTraceAsString() . ']', 200);

      return false;
    }
  }

  
  public static function updateKursplanung($pKursplanung, $pOrigKursplanung)
  {
    $allgsettings = AllgSettingsAPI::getAllgSettings();
    if (SessionOperations::isReplikat()) {
      if ($allgsettings->dmzEnabled) {
        return static::_updateKursplanungDmz($pKursplanung, $pOrigKursplanung);
      } else {
        return static::_updateKursplanungReplikat($pKursplanung);
      }
    } else {
      return static::_updateKursplanungDirekt($pKursplanung);
    }
  }

  
  protected static function _updateKursplanungDirekt($pKursplanung)
  {
    $dbwKursplanung = new DBWorkKursplanung(1, true);
    $dbwKursplanung->updateKursplanung($pKursplanung, true);

    return true;
  }

  
  protected static function _updateKursplanungReplikat($pKursplanung)
  {
    $dbwKursplanung = new DBWorkKursplanung(1, true);
    $dbwKursplanung->updateKursplanung($pKursplanung, false);

    return true;
  }

  
  private static function _updateKursplanungDmz($pKursplanung, $pOrigKursplanung)
  {
    try {
      $zuUebertragendeFelder = $pOrigKursplanung->getDiffFields($pKursplanung, true);

      
      if ($pKursplanung->kursortObj != $pOrigKursplanung->kursortObj) {
        $zuUebertragendeFelder[] = 'kursortObj';
      }

      $zuUebertragendeFelder[] = 'id';

      
      if (in_array('dokumente', $zuUebertragendeFelder)) {
        $zuUebertragendeFelder = array_filter($zuUebertragendeFelder, function($feld) {return $feld != 'dokumente';});

        if (is_array($pKursplanung->dokumente) && count($pKursplanung->dokumente) > 0) {
          $dokumenteNode = new XMLNode('dokumente');
          foreach ($pKursplanung->dokumente as $dokument) {
            $dokumenteNode->addChild(XMLNode::getXMLNode($dokument, 'dokument', array(), true));
          }
        } else {
          
          $dokumenteNode = new XMLNode('dokumenteLeeren', 'W');
        }
      }

      
      if (in_array('dozenten', $zuUebertragendeFelder)) {
        $zuUebertragendeFelder = array_filter($zuUebertragendeFelder, function($feld) {return $feld != 'dozenten';});

        if (is_array($pKursplanung->dozenten) && count($pKursplanung->dozenten) > 0) {
          $doozentenNode = new XMLNode('dozenten');
          foreach ($pKursplanung->dozenten as $dozent) {
            $dozNode = XMLNode::getXMLNode($dozent, 'dozent', array(), true);

            if (is_array($dozent->kommunikation)) {
              $kommNode = new XMLNode('kommunikationen');
              foreach ($dozent->kommunikation as $komm) {
                $kommNode->addChild(XMLNode::getXMLNode($komm, 'kommunikation', array(), true));
              }
              $dozNode->addChild($kommNode);
            }

            $doozentenNode->addChild($dozNode);
          }
        } else {
          
          $doozentenNode = new XMLNode('dozentenLeeren', 'W');
        }
      }


      
      if (in_array('werbemittel', $zuUebertragendeFelder)) {
        $zuUebertragendeFelder = array_filter($zuUebertragendeFelder, function($feld) {return $feld != 'werbemittel';});

        if (is_array($pKursplanung->werbemittel) && count($pKursplanung->werbemittel) > 0) {
          $werbemittelNode = new XMLNode('werbemittel_list');
          foreach ($pKursplanung->werbemittel as $werbemittel) {
            $werbemittelNode->addChild(XMLNode::getXMLNode($werbemittel, 'werbemittel', array(), true));
          }
        } else {
          
          $werbemittelNode = new XMLNode('werbemittelLeeren', 'W');
        }
      }

      
      if (in_array('kursortObj', $zuUebertragendeFelder)) {
        $zuUebertragendeFelder = array_filter($zuUebertragendeFelder, function($feld) {return $feld != 'kursortObj';});

        if (!is_null($pKursplanung->kursortObj)) {
          $kursortNode = new XMLNode('kursort_objekte');
          $kursortNode->addChild(XMLNode::getXMLNode($pKursplanung->kursortObj, 'kursort', array(), true));
        } else {
          
          $kursortNode = new XMLNode('werbemittelLeeren', 'W');
        }
      }

      $kursplanungNode = XMLNode::getXmlNodeOnlySpecificFields($pKursplanung, 'kursplanung', $zuUebertragendeFelder, true);
      $origKursplanungNode = XMLNode::getXmlNodeOnlySpecificFields($pOrigKursplanung, 'oldobject', $zuUebertragendeFelder, true);

      if (isset($dokumenteNode)) {
        $kursplanungNode->addChild($dokumenteNode);
      }

      if (isset($doozentenNode)) {
        $kursplanungNode->addChild($doozentenNode);
      }

      if (isset($werbemittelNode)) {
        $kursplanungNode->addChild($werbemittelNode);
      }

      if (isset($kursortNode)) {
        $kursplanungNode->addChild($kursortNode);
      }

      $kursplanungNode->addChild($origKursplanungNode);
      $message = new XMLNode('kursplanungen');
      $message->addChild($kursplanungNode);
      $abgleichApi = new AbgleichAPI();
      $abgleichApi->sendeNachricht(
        AbgleichAPI::ABGLEICH_KURSPLANUNG_UPDATE,
        new Nutzlast($message)
      );
      static::_updateKursplanungDirekt($pKursplanung);

      return true;
    } catch (AbgleichApiException $aae) {
      Logger::logg('Kursplanung bearbeiten - folgende Exception ist aufgetreten: ' . $aae->getMessage() . "\n" . ' [' . $aae->getTraceAsString() . ']', 200);

      return false;
    }
  }

  
  public static function saveKurs($builder)
  {
    $statusMessage = '';

    $kurs = $builder->getData();
    $dbwKurse = new DBWorkKurse(1, true);
    $origKurs = $dbwKurse->getKurs($kurs->id, true);

    $allgsettings = AllgSettingsAPI::getAllgSettings();

    
    $changedFields = $builder->getFieldNamesOfChangedFields($origKurs);

    
    
    
    if (count($changedFields) == 0) {
      $statusMessage .= HTMLOperations::getInfoBox('<div class="infobox_text">' . CleanOperations::cleanStringForHtml($allgsettings->failNoChangesMsgKursplanung) . '</div>', 'Hinweis', 'in_background');

      return array('statusMessage' => $statusMessage, 'kursId' => -1);
    } 

    $insertedKursId = -1;
    try {
      if (SessionOperations::isDmzBetrieb()) {
        if (count($changedFields) > 0) {
          
          $kursTuple = new Tuple($kurs, $changedFields, $origKurs);
          self::correctKurs($kursTuple, 'update');
        }

        
        
        
        $dbwKurse->updateKurs($kurs, true);
      } else { 
        $dbwKurse->updateKurs($kurs);
      }
      $statusMessage .= HTMLOperations::getSuccessBox('<div class="successbox_text">' . CleanOperations::cleanStringForHtml($allgsettings->successMsgChangeKurs) . '</div>' . "\n", 'Übermittlung erfolgreich', 'in_background');
    } catch (AbgleichApiException $aae) {
      Logger::logg('Kurskorrektur - folgende Exception ist aufgetreten: ' . $aae->getMessage() . "\n" . ' [' . $aae->getTraceAsString() . ']', 200);
      if ($aae->errorType == AbgleichApiResult::CONFLICT) {
        $statusMessage .= HTMLOperations::getAlertBox('<div class="alertbox_text">' . CleanOperations::cleanStringForHtml($allgsettings->failSubmitMsgConflict) . '</div>', 'Fehler', 'in_background');
      } else {
        $statusMessage .= HTMLOperations::getAlertBox('<div class="alertbox_text">' . CleanOperations::cleanStringForHtml($allgsettings->failSubmitMsgKursplanung) . '</div>', 'Fehler', 'in_background');
      }
    } catch (Exception $e) {
      $statusMessage .= HTMLOperations::getInfoBox('<div class="infobox_text">' . CleanOperations::cleanStringForHtml($allgsettings->failNoChangesMsgKursplanung) . '</div>', 'Hinweis', 'in_background');
      Logger::logg('Kurskorrektur - folgende Exception ist aufgetreten: ' . $e->getMessage() . "\n" . ' [' . $e->getTraceAsString() . ']', 200);
    }

    return array('statusMessage' => $statusMessage, 'kursId' => $insertedKursId);
  }

  
  public static function correctKurs($pKursTuple, $pCorrectMode = 'update')
  {
    return AbgleichAPI::correctDatamodul(
      new DBWorkKurse(),
      $pKursTuple,
      $pCorrectMode,
      'kurs',
      'kurse',
      'kurse',
      AbgleichAPI::ABGLEICH_NOTHING,
      AbgleichAPI::ABGLEICH_NOTHING,
      AbgleichAPI::ABGLEICH_KURSKORREKTUR_NEU
    );
  }

  
  public static function correctKursZusatz($pKurszusatzTuple, $pCorrectMode = 'update')
  {
    return AbgleichAPI::correctDatamodul(
      new  DBWorkKurszusatz(),
      $pKurszusatzTuple,
      $pCorrectMode,
      'kurszusatztext',
      'kurszusatztexte',
      'kurszusatz',
      AbgleichAPI::ABGLEICH_NOTHING,
      AbgleichAPI::ABGLEICH_NOTHING,
      AbgleichAPI::ABGLEICH_KURSZUSATZKORREKTUR
    );
  }
}