<?php
namespace nur\v\bs3;

use nur\A;
use nur\b\IllegalAccessException;
use nur\data\types\md_utils;
use nur\v\bs3\fo\Form;
use nur\v\bs3\fo\FormManager;
use nur\v\model\IFormManager;
use nur\v\v;

class Bs3FormManager implements IFormManager {
  function __construct($options=null, ?array $schema=null) {
    $this->fm = new FormManager();
    $this->resetManager($options, $schema);
  }

  /** @var FormManager */
  protected $fm;

  const MANAGER_OPTIONS_SCHEMA = [
    "type" => [null, FormManager::TYPE_BASIC, "type de formulaire par défaut"],
  ];
  private static $manager_options_md;

  function resetManager($options=null, ?array $schema=null): void {
    md_utils::ensure_md(self::$manager_options_md
      , self::MANAGER_OPTIONS_SCHEMA)->ensureSchema($options);
    $this->fm->setInNavbar(false);
    $type = A::getdel($options, "type");
    $this->inForm = false;
    $this->type = $type;
    $this->form = null;
  }

  function push($options=null, ?array $schema=null): void {
    throw IllegalAccessException::not_implemented();
  }

  function pop(): void {
    throw IllegalAccessException::not_implemented();
  }

  /** @var bool */
  protected $inForm;

  /** @var ?string */
  protected $type;

  /** @var Form */
  protected $form;

  function started(): bool {
    return $this->inForm;
  }

  function start($options=null, ?array $schema=null): array {
    $vs = [];
    if ($this->inForm) $vs[] = $this->form->getEnd();
    md_utils::ensure_md(self::$manager_options_md
      , self::MANAGER_OPTIONS_SCHEMA)->ensureSchema($options);
    $type = A::getdel($options, "type");
    if ($type === null) $type = $this->type;
    $this->form = $this->fm->get($type, $options);
    $vs[] = $this->form->getStart();
    $this->inForm = true;
    return $vs;
  }

  function end(): array {
    if (!$this->inForm) return [];
    $vs = [];
    $vs[] = $this->form->getEnd();
    $this->inForm = false;
    return $vs;
  }

  function section($options=null): array {
    return v::h2($options); #XXX
  }

  function endSection(): array {
    return []; #XXX
  }

  function group($options=null): array {
    return []; #XXX
  }

  function endGroup(): array {
    return []; #XXX
  }

  function fixed($label, string $name, $value, ?array $options=null): array {
    return [$this->form->fixed($label, $name, $value, $options)];
  }

  function hidden(string $name, $value, ?array $options=null): array {
    return [$this->form->hidden($name, $value, $options)];
  }

  function hiddens(array $values, string ...$names): array {
    if (!$names) $names = null;
    return $this->form->hiddens($values, $names);
  }

  function text($label, string $name, $value, ?array $options=null): array {
    return [$this->form->text($label, $name, $value, $options)];
  }

  function texts($label, array $values, string ...$names): array {
    $vs = [];
    if (!$names) $names = array_keys($values);
    foreach ($names as $name) {
      $vs[] = $this->form->text($label, $name, $values[$name]);
    }
    return $vs;
  }

  function password($label, string $name, $value, ?array $options=null): array {
    return [$this->form->password($label, $name, $value, $options)];
  }

  function select($label, string $name, $value, ?array $options=null): array {
    return [$this->form->select($label, $name, $value, $options)];
  }

  function checkbox($text, string $name, $value, ?bool $checked=null, ?array $options=null): array {
    return [$this->form->checkbox($text, $name, $value, $checked, $options)];
  }

  function checkboxes($label, string $name, $values, ?array $options=null): array {
    throw IllegalAccessException::not_implemented();
  }

  function radiobutton($text, string $name, $value, ?bool $checked=null, ?array $options=null): array {
    return [$this->form->radiobutton($text, $name, $value, $checked, $options)];
  }

  function radiobuttons($label, string $name, $value, ?array $options): array {
    throw IllegalAccessException::not_implemented();
  }

  function textarea($label, string $name, $value, ?array $options=null): array {
    return [$this->form->textarea($label, $name, $value, $options)];
  }

  function file($label, string $name, ?array $options=null): array {
    return [$this->form->file($label, $name, $options)];
  }

  function submit($options=null): array {
    if (is_array($options)) {
      $submit = null;
    } else {
      $submit = $options;
      $options = null;
    }
    return [$this->form->submit($submit, $options)];
  }

  function reset($options=null): array {
    if (is_array($options)) {
      $submit = null;
    } else {
      $submit = $options;
      $options = null;
    }
    return [$this->form->reset($submit, $options)];
  }
}