<?php
namespace nur\v;

use nur\co;
use nur\str;
use nur\v\base\MenuManager;
use nur\v\html5\Html5NavbarManager;
use nur\v\model\IMenuManager;
use nur\v\model\INavbarManager;

/**
 * Class navbar: gestion globale de la barre de navigation
 */
class navbar {
  const MANAGER_CLASS = Html5NavbarManager::class;

  protected static $manager_class;

  /**
   * spécifier la classe à utiliser pour instancier le gestionnaire de
   * barre de navigation
   *
   * cette méthode *doit* être appelée avant d'appeler la méthode
   * {@link manager()}
   */
  static final function set_manager_class(string $manager_class) {
    self::$manager_class = $manager_class;
  }

  /** @var INavbarManager */
  protected static $manager;

  static final function set_manager(INavbarManager $manager) {
    self::$manager = $manager;
  }

  /** obtenir l'instance globale de gestionnaire de navbar */
  static final function manager(): INavbarManager {
    if (self::$manager === null) {
      $manager_class = self::$manager_class;
      if ($manager_class === null) $manager_class = static::MANAGER_CLASS;
      self::$manager = new $manager_class();
    }
    return self::$manager;
  }

  static final function __callStatic($name, $args) {
    $name = str::us2camel($name);
    return call_user_func_array([self::manager(), $name], $args);
  }

  #############################################################################

  const MENU_MANAGER_CLASS = MenuManager::class;

  protected static $menu_manager_class;

  /**
   * spécifier la classe à utiliser pour instancier le gestionnaire de
   * menu
   *
   * cette méthode *doit* être appelée avant d'appeler la méthode
   * {@link menu_manager()}
   */
  static final function set_menu_manager_class(string $menu_manager_class) {
    self::$menu_manager_class = $menu_manager_class;
  }

  /** @var MenuManager */
  protected static $menu_manager;

  static final function set_menu_manager(IMenuManager $menu_manager) {
    self::$menu_manager = $menu_manager;
  }

  /** obtenir l'instance globale de gestionnaire de menu */
  static final function menu_manager(): IMenuManager {
    if (self::$menu_manager === null) {
      $menu_manager_class = self::$menu_manager_class;
      if ($menu_manager_class === null) $menu_manager_class = static::MENU_MANAGER_CLASS;
      self::$menu_manager = new $menu_manager_class();
    }
    return self::$menu_manager;
  }

  #############################################################################

  static final function push($mark, ?array $start=null, ?array $end=null): void {
    co::_write(self::manager()->push($mark, $start, $end));
  }
  static final function pop($mark): void {
    co::_write(self::manager()->pop($mark));
  }

  static final function started(): bool { return self::manager()->started(); }
  static final function start($options=null): void {
    co::_write(self::manager()->start($options));
  }
  static final function end(): void {
    co::_print(self::manager()->end());
  }

  static final function nav($options=null, ?array $items=null): void {
    $navbar = self::manager();
    co::_write($navbar->startNav($options));
    if ($items !== null) {
      foreach ($items as $item) {
        co::_write($navbar->navItem($item));
      }
    }
  }
  static final function item($item): void {
    co::_write(self::manager()->navItem($item));
  }
  static final function brand($brand, ?array $options=null): void { self::item(nb::brand($brand, $options)); }
  static final function text($text, ?array $options=null): void { self::item(nb::text($text, $options)); }
  static final function link($url, $link=null, ?array $options=null): void { self::item(nb::link($url, $link, $options)); }
  static final function button($url, $button=null, ?array $options=null): void { self::item(nb::button($url, $button, $options)); }
  static final function menu($text, ?array $links=null, ?array $options=null): void { self::item(nb::menu($text, $links, $options)); }
  static final function literal($literal, ?array $options=null): void { self::item(nb::literal($literal, $options)); }
  static final function endnav(): void {
    co::_print(self::manager()->endNav());
  }
}
