#ifndef ROGUE_INPUT_H
#define ROGUE_INPUT_H

#include <SDL2/SDL_events.h>
#include <SDL2/SDL_scancode.h>
#include <functional>
#include <set>

namespace rogue {
// Interface representing a handler for SDL os events that can be used to handle input
// Uses RAII to register and deregister with the static input service
struct InputHandler {
	InputHandler();
	virtual ~InputHandler();
	virtual void process_event(SDL_Event event) = 0;
};

// implementation of the InputHandler interface that filters for SDL_KeyEvents that represent a given key or keys being pressed
// 
class KeyEventHandler : public InputHandler {
public:
	typedef std::function<void(bool down)> Listener; // defines the interface required for listening for key events
	// from this constructor until the object is destroyed, these settings remain the same, if you need to modify them, recreate the object
	KeyEventHandler(std::set<SDL_Scancode> codes, Listener listener, bool allow_repeat = true);
	// handle events passed in from the OS through SDL
	virtual void process_event(SDL_Event event) override;
private:
	std::set<SDL_Scancode> scancodes{}; // scancodes to listen for
	Listener listener{}; // function to notify when event is triggered
	bool allow_repeat{false}; // whether or not to allow key repeat (multiple down events before an up on the same key)
};

class Input {
public:
	// register an input handler, registered handlers will be notified when Input::process_event is called
	static void add_handler(InputHandler *handler);
	static void remove_handler(InputHandler *handler);
	// notify registered InputHandlers of an event
	static void process_event(SDL_Event event);
private:
	static std::set<InputHandler*> handlers;
};
}

#endif // !ROGUE_INPUT_H
