#include <GLFW/glfw3.h>

#include "client/input/Keys.h"

Keys::Key::Key() : down(false), shouldRelease(false), downTime(0) {
}

bool Keys::Key::isDown() const {
    return down;
}

bool Keys::Key::isReleased() const {
    return shouldRelease;
}

u32 Keys::Key::getDownTime() const {
    return downTime;
}

std::ostream& operator<<(std::ostream& os, const Keys::Key& k) {
    os << "Key(down: " << k.isDown() << ", release: " << k.isReleased() <<
            ", time: " << k.getDownTime() << ")";
    return os;
}

Keys::Keys() : left(keys[0]), right(keys[1]), up(keys[2]), down(keys[3]), jump(keys[4]), sneak(keys[5]),
camLeft(keys[6]), camRight(keys[7]), camUp(keys[8]), camDown(keys[9]), test(keys[10]), test2(keys[11]), test3(keys[12]),
test4(keys[13]), test5(keys[14]) {
    keys[0].glfwKey = GLFW_KEY_A;
    keys[1].glfwKey = GLFW_KEY_D;
    keys[2].glfwKey = GLFW_KEY_W;
    keys[3].glfwKey = GLFW_KEY_S;
    keys[4].glfwKey = GLFW_KEY_SPACE;
    keys[5].glfwKey = GLFW_KEY_LEFT_SHIFT;
    keys[6].glfwKey = GLFW_KEY_LEFT;
    keys[7].glfwKey = GLFW_KEY_RIGHT;
    keys[8].glfwKey = GLFW_KEY_UP;
    keys[9].glfwKey = GLFW_KEY_DOWN;
    keys[10].glfwKey = GLFW_KEY_T;
    keys[11].glfwKey = GLFW_KEY_Y;
    keys[12].glfwKey = GLFW_KEY_U;
    keys[13].glfwKey = GLFW_KEY_I;
    keys[14].glfwKey = GLFW_KEY_R;
}

void Keys::release(int key) {
    for(Key& k : keys) {
        if(k.glfwKey == key) {
            k.shouldRelease = true;
        }
    }
}

void Keys::press(int key) {
    for(Key& k : keys) {
        if(k.glfwKey == key) {
            k.down = true;
            k.shouldRelease = false;
        }
    }
}

void Keys::tick() {
    for(Key& k : keys) {
        k.downTime += k.down;
        k.down = k.down && !k.shouldRelease;
        k.downTime *= !k.shouldRelease;
        k.shouldRelease = false;
    }
}