<?php

namespace Snaju\Inception\Event;

abstract class Event
{

    private $hooks = [];

    protected $isCancelled = false;

    public abstract function run(Event $event): Event;

    public function onEnd(Event $event)
    {
        return $event;
    }

    public static function getName()
    {
        return get_called_class();
    }

    public static function hook(callable $func)
    {
        EventManager::addHook(self::getName(), $func,);
    }

    /**
     * @return bool
     */
    public function isCancelled(): bool
    {
        return $this->isCancelled;
    }

    /**
     * @param bool $isCancelled
     */
    public function setIsCancelled(bool $isCancelled)
    {
        $this->isCancelled = $isCancelled;
    }

    public function call()
    {
        $this->buildHooks();

        $e = $this->run($this);
        foreach ($this->hooks as $hook) {
            if ($hook instanceof EventHookObject) {
                if (is_callable($hook->getRunnable())) {
                    $e1 = call_user_func($hook->getRunnable(), $e);
                    if ($e1 instanceof Event) {
                        $e = $e1;
                        if ($e->isCancelled()) {
                            break;
                        }
                    }
                }
            }
        }

        if (!$e->isCancelled()) {
            $e = $this->onEnd($e);
        }

        return $e;
    }

    private function buildHooks()
    {
        $this->hooks = EventManager::getHooks(self::getName());
    }


}

?>