#ifndef EVENT_HANDLER_H
#define EVENT_HANDLER_H

#include <memory>

#include "EventHandlerBase.h"
#include "EventManager.h"

template <typename T>
class EventHandler: public EventHandlerBase
{
public:
	void registerForEvent()
	{
		EventManager::getInstance()->registerEventHandler(this);
	}

	void unregisterForEvent()
	{
		EventManager::getInstance()->unregisterEventHandler(this);
	}

	void handleBaseEvent(std::shared_ptr<const Event> event) override
	{
		std::shared_ptr<const T> specificEvent = std::dynamic_pointer_cast<const T>(event);
		if (specificEvent)
		{
			handleEvent(specificEvent);
		}
	}

private:
	virtual void handleEvent(std::shared_ptr<const T> event) = 0;
};


template <typename... Ts> class CombinedEventHandlerHelper 
{
protected:
	void registerForEventsHelper() {}
	void unregisterForEventsHelper() {}
};


template <typename T, typename... Ts>
class CombinedEventHandlerHelper<T, Ts...>
    : public EventHandler<T>
    , public CombinedEventHandlerHelper<Ts...>
{
protected:
	void registerForEventsHelper()
	{
		EventHandler<T>::registerForEvent();
		CombinedEventHandlerHelper<Ts...>::registerForEventsHelper();
	}

	void unregisterForEventsHelper()
	{
		EventHandler<T>::unregisterForEvent();
		CombinedEventHandlerHelper<Ts...>::unregisterForEventsHelper();
	}
};


template <typename... Ts>
class CombinedEventHandler: public CombinedEventHandlerHelper<Ts...>
{
protected:
	void registerForEvents()
	{
		CombinedEventHandlerHelper<Ts...>::registerForEventsHelper();
	}

	void unregisterForEvents()
	{
		CombinedEventHandlerHelper<Ts...>::unregisterForEventsHelper();
	}
};

#endif   // EVENT_HANDLER_H
