<?php
namespace nur\b\params;

/**
 * implémentation de {@link IParametrable} pour une classe dérivée, dont le
 * parent implémente {@link Tparametrable1}
 *
 * la classe qui utilise ce trait *doit* définir une constante
 * PARAMETRABLE_PARAMS_SCHEMA
 */
trait Tparametrable {
  use _Tparametrable0;

  static function get_parametrable_params_schema(): array {
    return array_merge(parent::get_parametrable_params_schema()
      , self::parametrable_params_md()->getSchema());
  }

  function setParametrableParams(?array $params): void {
    parent::setParametrableParams($params);
    $parametrables = $this->getParametrableParamsParametrables();
    $md = self::parametrable_params_md();
    $modifiedKeys = parametrable_utils::set_params($parametrables, $this, $params, $md);
    $this->afterSetParametrableParams($modifiedKeys, $md);
  }

  function initParametrableParams(?array $params, bool $setParametrableParams=true): void {
    parent::initParametrableParams(null, false);
    $parametrables = $this->getParametrableParamsParametrables();
    parametrable_utils::set_defaults($parametrables, $this, self::parametrable_params_md());
    if ($setParametrableParams) $this->setParametrableParams($params);
  }

  protected function splitParametrableParams(?array $params): array {
    [$pparams, $pothers] = parent::splitParametrableParams($params);
    [$cparams, $others] = self::split_parametrable_params($pothers);
    $params = array_merge($pparams, $cparams);
    return [$params, $others];
  }

  function parametrable__call(string $name, array $args, &$result): bool {
    $md = self::parametrable_params_md();
    $auto_getters = self::_AUTO_GETTERS;
    $auto_setters = self::_AUTO_SETTERS;
    if (parametrable_utils::should_call($name, $auto_getters, $auto_setters, $md)) {
      $result = parametrable_utils::call($this, $name, $args, $auto_getters, $auto_setters, $md);
      return true;
    }
    return parent::parametrable__call($name, $args, $result);
  }
}
