#ifndef KEYBOARD_H__
#define KEYBOARD_H__

#include <vector>

/** A keyboard action; key-down or key-up */
class KeyboardAction
{
public:
	static const int KEYUP = 0;
	static const int KEYDOWN = 1;

	KeyboardAction(unsigned char keyCode, int state) {
		this->key = keyCode;
		this->state = state;
	}

	int state;
	unsigned char key;
};

/* Iterators */
typedef std::vector<KeyboardAction> KeyboardActionVec;
typedef KeyboardActionVec::iterator KeyboardActionIt;
typedef KeyboardActionVec::const_iterator KeyboardActionCIt;

/** A static keyboard class, written to resemble the one in lwjgl somewhat */
class Keyboard
{
public:
	static const int KEY_A = 65;
	static const int KEY_B = 66;
	static const int KEY_C = 67;
	static const int KEY_D = 68;
	static const int KEY_E = 69;
	static const int KEY_F = 70;
	static const int KEY_G = 71;
	static const int KEY_H = 72;
	static const int KEY_I = 73;
	static const int KEY_J = 74;
	static const int KEY_K = 75;
	static const int KEY_L = 76;
	static const int KEY_M = 77;
	static const int KEY_N = 78;
	static const int KEY_O = 79;
	static const int KEY_P = 80;
	static const int KEY_Q = 81;
	static const int KEY_R = 82;
	static const int KEY_S = 83;
	static const int KEY_T = 84;
	static const int KEY_U = 85;
	static const int KEY_V = 86;
	static const int KEY_W = 87;
	static const int KEY_X = 88;
	static const int KEY_Y = 89;
	static const int KEY_Z = 90;

	static const int KEY_BACKSPACE = 8;
	static const int KEY_RETURN = 13;

	static const int KEY_F1 = 112;
	static const int KEY_F2 = 113;
	static const int KEY_F3 = 114;
	static const int KEY_F4 = 115;
	static const int KEY_F5 = 116;
	static const int KEY_F6 = 117;
	static const int KEY_F7 = 118;
	static const int KEY_F8 = 119;
	static const int KEY_F9 = 120;
	static const int KEY_F10 = 121;
	static const int KEY_F11 = 122;
	static const int KEY_F12 = 123;

	static const int KEY_ESCAPE = 27;
	static const int KEY_SPACE = 32;
	static const int KEY_LSHIFT = 10;

	static bool isKeyDown(int keyCode) {
		return _states[keyCode] == KeyboardAction::KEYDOWN;
	}

	static void reset() {
        _inputs.clear();
		_inputText.clear();
        _index = -1;
		_textIndex = -1;
    }

	static void feed(unsigned char keyCode, int state) {
		_inputs.push_back(KeyboardAction(keyCode, state));

		_states[keyCode] = state;
	}
	static void feedText(char character) {
		_inputText.push_back(character);
	}

	static bool next() {
        if (_index + 1 >= (int)_inputs.size())
            return false;

        ++_index;
        return true;
    }

	static bool nextTextChar() {
		if(_textIndex + 1 >= (int)_inputText.size())
			return false;
		++_textIndex;
		return true;
	}

	static void rewind() {
		_index = -1;
		_textIndex = -1;
	}

    static int getEventKey() {
        return _inputs[_index].key;
    }

    static int getEventKeyState() {
        return _inputs[_index].state;
    }
	static char getChar() {
		return _inputText[_textIndex];
	}
private:
    static int _index;
	static int _textIndex;
	static int _states[256];
	static std::vector<KeyboardAction> _inputs;
	static std::vector<char> _inputText;
	static bool _inited;
};

#endif//KEYBOARD_H__
