#include "input.h"

#include <map>

#include "internal.h"

namespace kek::Input {

static InputListener nextID = 0;

InputListener addPeriodicCallback(PeriodicCallback callback) {
	InputListener id = nextID++;
	kekData.periodicCallbacks.emplace(id, callback);
	return id;
}

void removePeriodicCallback(InputListener listener) {
	kekData.periodicCallbacks.erase(listener);
}

InputListener addKeyListener(KeyCallback callback) {
	InputListener id = nextID++;
	kekData.keyCallbacks.emplace(id, callback);
	return id;
}

void removeKeyListener(InputListener listener) {
	kekData.keyCallbacks.erase(listener);
}

InputListener addMouseListener(MouseCallback callback) {
	InputListener id = nextID++;
	kekData.mouseCallbacks.emplace(id, callback);
	return id;
}

void removeMouseListener(InputListener listener) {
	kekData.mouseCallbacks.erase(listener);
}

KeyMapping createKeyMapping(std::string name, GLFWKey defaultKey) {
	if(name == KEK_INVALID_KEY_MAPPING_NAME) return KEK_INVALID_KEY_MAPPING;
	KeyMapping id = nextID++;
	KeyMappingData d;
	d.name = name;
	d.key = defaultKey;
	kekData.keyMappings.emplace(id, d);
	return id;
}

void reassignKeyMapping(KeyMapping mapping, GLFWKey key) {
	auto it = kekData.keyMappings.find(mapping);
	if(it == kekData.keyMappings.end()) return;
	KeyMappingData d = it->second;
	d.key = key;
	it->second = d;
}

KeyMappingData getKeyMapping(KeyMapping mapping) {
	auto it = kekData.keyMappings.find(mapping);
	if(it == kekData.keyMappings.end()) return {.name = KEK_INVALID_KEY_MAPPING_NAME};
	return it->second;
}

GLFWKeyState getKeyState(KeyMapping mapping) {
	auto it = kekData.keyMappings.find(mapping);
	if(it == kekData.keyMappings.end()) return -1;
	return glfwGetKey(kekData.window, it->second.key);
}

}
