#ifndef __EventSender__H
#define __EventSender__H

#include "WimpLib:std.h"
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef enum
{ EListenerPriority_PreFilter_Top
, EListenerPriority_PreFilter
, EListenerPriority_Top
, EListenerPriority_Normal
, EListenerPriority_Bottom
, EListenerPriority_PostFilter
, EListenerPriority_PostFilter_Bottom
} EListenerPriority;

typedef enum
{ EListenerAction_ContinueEvent // Let the next listener receive the event.
, EListenerAction_StopEvent     // The listener has intercepted the event,
                                // no other ones should receive it.
, EListenerAction_RestartEvent  // The listener has done something which may have
                                // an impact on already processed listeners.
                                // Should only be used by very specific listeners.
} EListenerAction;

#define EListenerType_Global -1

typedef struct
{
	const void* pSender;
	int         Type;
	const void* pData;
} Event;

typedef EListenerAction (*Listener_FOnEvent)(void* pListener, const Event* pEvent);

typedef struct EventSender EventSender;

EventSender* throw_New_EventSender(void);
void Delete_EventSender(EventSender*);

void throw_EventSender_AddListener
	( EventSender*          This
	, EListenerPriority     priority
	, const void*           pSender
	, int                   Type
	, void*                 pListener
	, Listener_FOnEvent     fn
	);
void EventSender_RemoveListener
	( EventSender*          This
	, EListenerPriority     priority
	, const void*           pSender
	, int                   Type
	, void*                 pListener
	, Listener_FOnEvent     fn
	);
void EventSender_NotifyListeners
	( EventSender*
	, const void*     pSender
	, int             Type
	, const void*     pData
	);

#ifdef __cplusplus
}
#endif

#endif
