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


class ExpandPersonData
{
  private $_dataModulFields;
  private $personObj;
  private $dbwObj;
  public $select;

  public function __construct($pTableName, $pPersonObj, $pDbwObj, $pAdditionalDataModulFields = array())
  {
    $this->_dataModulFields = array('id', 'dse_unterschrieben_datum', 'dse_unterschrieben_bearbeiter',
        'dse_unterschrieben_weg', 'dse_widerrufen_datum', 'dse_widerrufen_bearbeiter', 'dse_widerrufen_weg');
    $this->_dataModulFields = array_merge($this->_dataModulFields, $pAdditionalDataModulFields);

    $this->dbwObj = $pDbwObj;
    $tmp = '';
    foreach ($this->_dataModulFields as $field) {
      $tmp .= ', ' . $this->dbwObj->translateVarName($field);
    }
    $this->select = StringOperations::substr($tmp, 2);
    
    $this->tableName = $pTableName;
    $this->personObj = $pPersonObj;
  }

  public function getDataModulFields()
  {
    return $this->_dataModulFields;
  }

  public function addField($field)
  {
    $this->select .= ', ' . $field;
    $this->_dataModulFields[] = $field;
  }

  
  public function getById($pId, $pPerson = null)
  {
    $person2 = $this->dbwObj->getOne($pId, 'nr', '', false);
    if (is_null($pPerson)) {
      $person2->id = $pId;

      return $person2;
    } else {
      if (!($pPerson instanceof Dozent)) {
        throw new InvalidArgumentException('Bei $pPerson handelt es sich nicht um ein Objekt vom Typ Dozent sondern ' . get_class($pPerson));
      }

      return $this->mergePerson2ToPerson($pPerson, $person2);
    }
  }

  
  public function getByIds($pIdAry, $pPersonAry = null, $pRefreshCache = false)
  {
    $ids = array_filter($pIdAry, function($id) {return is_numeric($id);});
    if (empty($ids)) {
      return array();
    }

    $person2s = $this->dbwObj->getSome($ids, 'nr', '', $pRefreshCache);
    if (empty($person2s)) { 
      if (is_null($pPersonAry) || empty($pPersonAry)) {
        $result = array();
        foreach ($pIdAry as $personId) {
          $result[] = $this->getNewObjectWithId($personId);
        }

        return $result;
      } else {
        return $pPersonAry;
      }
    } else {
      $person2sByKey = ArrayOperations::setAttributAsKey($person2s, 'id');
      if (is_null($pPersonAry) || empty($pPersonAry)) {
        return $this->getByIds_mapPerson2sToPersons($pIdAry, $person2sByKey, array());
      } else {
        $personAryByKey = ArrayOperations::setAttributAsKey($pPersonAry, 'id');

        return $this->getByIds_mapPerson2sToPersons($pIdAry, $person2sByKey, $personAryByKey);
      }
    }

    return $person2s;
  }

  
  public function mergePerson2ToPerson($pPerson, $pPerson2)
  {
    if (is_null($pPerson)) {
      throw new InvalidArgumentException('$pPerson is null');
    }
    if (is_null($pPerson2)) {
      throw new InvalidArgumentException('$pPerson2 is null');
    }
    foreach ($this->_dataModulFields as $field) {
      $pPerson->setValue2Var($field, $pPerson2->getVarValue($field));
    }

    return $pPerson;
  }

  private function getByIds_mapPerson2sToPersons($pIdAry, $person2sByKey, $personAryByKey)
  {
    $result = array();
    foreach ($pIdAry as $personId) {
      $result[] = $this->getByIds_mapPerson2ToPerson($personId, $person2sByKey, $personAryByKey);
    }

    return $result;
  }

  private function getByIds_mapPerson2ToPerson($personId, $person2sByKey, $personAryByKey)
  {
    if (isset($person2sByKey[$personId], $personAryByKey[$personId])) {
      $result = $this->mergePerson2ToPerson($personAryByKey[$personId], $person2sByKey[$personId]);
    } else {
      if (isset($person2sByKey[$personId])) {
        $result = $person2sByKey[$personId];
      } elseif (isset($personAryByKey[$personId])) {
        $result = $personAryByKey[$personId];
      } else {
        $result = $this->getNewObjectWithId($personId);
      }
    }

    return $result;
  }

  private function getNewObjectWithId($pPersonId)
  {
    $persObj = $this->personObj;
    $persObj->id = $pPersonId;

    return $persObj;
  }
}