<?php

/**
 * Questo file è parte di Pongho.
 *
 * @author    Daniele De Nobili
 * @copyright Web Agency Meta Line S.r.l.
 * @package   Application\Admin
 */

namespace Application\Admin\Widget;

/**
 * Rappresenta una collezione di widget.
 */
class WidgetsCollection implements \IteratorAggregate
{
    /**
     * Elenco di widget.
     *
     * @var WidgetInterface[]
     */
    protected $collection = [];

    /**
     * Permette di aggiungere un nuovo widget alla collezione.
     *
     * @return WidgetsCollection La classe stessa.
     * @throws \InvalidArgumentException Quando la chiave del widget passato è già occupata.
     */
    public function add(WidgetInterface $widget)
    {
        if (array_key_exists($widget->getKey(), $this->collection)) {
            throw new \InvalidArgumentException(sprintf('A widget with key "%s" is already added!', $widget->getKey()));
        }

        $this->collection[$widget->getKey()] = $widget;

        return $this;
    }

    /**
     * Restituisce un widget in base alla chiave passata.
     *
     * @param string $widget_key
     * @return WidgetInterface
     * @throws \InvalidArgumentException Se il widget richiesto non esiste.
     */
    public function get($widget_key)
    {
        if (!array_key_exists($widget_key, $this->collection)) {
            throw new \InvalidArgumentException(sprintf('Widget "%s" not exists!', $widget_key));
        }

        return $this->collection[$widget_key];
    }

    /**
     * Indica se esiste un widget con la chiave passata.
     *
     * @param string $widget_key
     * @return boolean
     */
    public function has($widget_key)
    {
        return array_key_exists($widget_key, $this->collection);
    }

    /**
     * Rimuove un widget dalla collezione.
     *
     * @param string $widget_key
     * @throws \InvalidArgumentException
     */
    public function remove($widget_key)
    {
        if (!array_key_exists($widget_key, $this->collection)) {
            throw new \InvalidArgumentException(sprintf('Widget "%s" not exists!', $widget_key));
        }

        unset($this->collection[$widget_key]);
    }

    /**
     * Rimuove tutti i widget dalla collezione.
     *
     * @return $this
     */
    public function removeAll()
    {
        $this->collection = [];

        return $this;
    }

    /**
     * Imposta le intestazioni dei widget.
     *
     * @deprecated CSS e JS vanno gestiti nel metodo Widget::render()
     */
    public function setHeaders()
    {
        foreach ($this->collection as $widget) {
            if ($widget instanceof Widget) {
                $widget->setHeaders();
            }
        }
    }

    /**
     * Implementa l’interfaccia IteratorAggregate.
     *
     * @return \ArrayIterator
     */
    public function getIterator(): \Traversable
    {
        return new \ArrayIterator($this->collection);
    }
}
