<?php

/**
 * Part of the Joomla Framework Event Package
 *
 * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved.
 * @license    GNU General Public License version 2 or later; see LICENSE
 */

namespace Joomla\Event;

/**
 * Interface for event dispatchers.
 *
 * @since  1.0
 */
interface DispatcherInterface
{
    /**
     * Dispatches an event to all registered listeners.
     *
     * @param   string           $name   The name of the event to dispatch.
     * @param   ?EventInterface  $event  The event to pass to the event handlers/listeners.
     *                                   If not supplied, an empty EventInterface instance is created.
     *                                   Note, not passing an event is deprecated and will be required as of 3.0.
     *
     * @return  EventInterface
     *
     * @since   2.0.0
     */
    public function dispatch(string $name, ?EventInterface $event = null): EventInterface;

    /**
     * Attaches a listener to an event
     *
     * @param   string    $eventName  The event to listen to.
     * @param   callable  $callback   A callable function.
     * @param   integer   $priority   The priority at which the $callback executed.
     *
     * @return  boolean
     *
     * @since   2.0.0
     */
    public function addListener(string $eventName, callable $callback, int $priority = 0): bool;

    /**
     * Clear the listeners in this dispatcher.
     *
     * If an event is specified, the listeners will be cleared only for that event.
     *
     * @param   string  $event  The event name.
     *
     * @return  $this
     *
     * @since   2.0.0
     */
    public function clearListeners($event = null);

    /**
     * Count the number of registered listeners for the given event.
     *
     * @param   string  $event  The event name.
     *
     * @return  integer
     *
     * @since   2.0.0
     */
    public function countListeners($event);

    /**
     * Get the listeners registered to the given event.
     *
     * @param   string|null  $event  The event to fetch listeners for or null to fetch all listeners
     *
     * @return  callable[]  An array of registered listeners sorted according to their priorities.
     *
     * @since   2.0.0
     */
    public function getListeners(?string $event = null);

    /**
     * Tell if the given listener has been added.
     *
     * If an event is specified, it will tell if the listener is registered for that event.
     *
     * @param   callable     $callback   The callable to check is listening to the event.
     * @param   string|null  $eventName  An optional event name to check a listener is subscribed to.
     *
     * @return  boolean  True if the listener is registered, false otherwise.
     *
     * @since   2.0.0
     */
    public function hasListener(callable $callback, ?string $eventName = null);

    /**
     * Removes an event listener from the specified event.
     *
     * @param   string    $eventName  The event to remove a listener from.
     * @param   callable  $listener   The listener to remove.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    public function removeListener(string $eventName, callable $listener): void;

    /**
     * Adds an event subscriber.
     *
     * @param   SubscriberInterface  $subscriber  The subscriber.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    public function addSubscriber(SubscriberInterface $subscriber): void;

    /**
     * Removes an event subscriber.
     *
     * @param   SubscriberInterface  $subscriber  The subscriber.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    public function removeSubscriber(SubscriberInterface $subscriber): void;
}
