module y4d_input.keyboardinput;

//----------------------------------------------------------------------------
//	KeyInput class
//----------------------------------------------------------------------------
private import y4d_input.keyinputbase;
private import SDL;

///	キーボード入力クラス。
/**
	キーのスキャンコードはSDLのものと同等
	→SDL/SDL_keysym.dを参照のこと。
	→SDLのimportをしたくない場合、
		このヘッダのなかにある KeyCode というenumを用いても良い。

	関数仕様についてはJoyStickと同じなのでそちらを参照のこと。

	update関数に関してはSDLのSDL_PumpEventsを定期的に呼び出していることを
	前提とする。ここで得られるのは前回のSDL_PumpEventsを呼び出してからの
	入力情報である。

	また、キー入力には、
		SDL_SetVideoMode(640,480,16,SDL_SWSURFACE);
	に相当する命令で、SDLのウィンドゥを初期化してある必要がある。
	(キー入力は、ウィンドゥに付帯するものなので)
*/
class KeyBoardInput : KeyInputBase {

	bool isPush(int nButtonNo) {
		if (nButtonNo > getButtonNum()) return false;
		return cast(bool) ((buttonState[1-flip][nButtonNo]==0)
			&& (buttonState[flip][nButtonNo]!=0));
	}
	bool isPress(int nButtonNo) {
		if (nButtonNo > getButtonNum()) return false;
		return cast(bool) (buttonState[flip][nButtonNo]!=0);
	}

	int getButtonNum() { return buttonState[0].length; }

	char[] getDeviceName() { return "KeyBoard"; }
	void* getInfo() { return null; }

	void update()
	{
		if (updated) {
			return;
		}
		
		flip = 1 - flip;

		ubyte* keys = SDL_GetKeyState(null);

		//	これを現在のキー情報としてコピーしてやる必要がある
		int n = getButtonNum();
		for(int i=0;i<n;i++){
			buttonState[flip][i] = cast(bool) (keys[i] != 0);
		}
		updated = true;
	}
	
	/// updateを呼ぶのを制限したいので、これのを呼んだあと一回に限りupdateが行える
	void updateMark() {
		updated = false;
	}

	this() {
		for(int i=0;i<2;++i){
			buttonState[i] = new bool[SDLK_LAST];
		}
	}

private:
	bool[]	buttonState[2];	//	前回の入力状態と今回の入力状態
	int flip;	//	前回の入力状態と今回の入力状態をflipさせて使う。flip={0,1}
	bool updated;
}

///	KeyBoardInputで用いるキースキャンコード
enum KeyCode : int {
	/// The keyboard syms have been cleverly chosen to map to ASCII
	UNKNOWN		= 0,
	FIRST		= 0,
	BACKSPACE		= 8,
	TAB		= 9,
	CLEAR		= 12,
	RETURN		= 13,
	PAUSE		= 19,
	ESCAPE		= 27,
	SPACE		= 32,
	EXCLAIM		= 33,
	QUOTEDBL		= 34,
	HASH		= 35,
	DOLLAR		= 36,
	AMPERSAND		= 38,
	QUOTE		= 39,
	LEFTPAREN		= 40,
	RIGHTPAREN		= 41,
	ASTERISK		= 42,
	PLUS		= 43,
	COMMA		= 44,
	MINUS		= 45,
	PERIOD		= 46,
	SLASH		= 47,
	KEY0			= 48,
	KEY1			= 49,
	KEY2			= 50,
	KEY3			= 51,
	KEY4			= 52,
	KEY5			= 53,
	KEY6			= 54,
	KEY7			= 55,
	KEY8			= 56,
	KEY9			= 57,
	COLON		= 58,
	SEMICOLON		= 59,
	LESS		= 60,
	EQUALS		= 61,
	GREATER		= 62,
	QUESTION		= 63,
	AT			= 64,

	///   Skip uppercase letters

	LEFTBRACKET	= 91,
	BACKSLASH		= 92,
	RIGHTBRACKET	= 93,
	CARET		= 94,
	UNDERSCORE		= 95,
	BACKQUOTE		= 96,
	a			= 97,
	b			= 98,
	c			= 99,
	d			= 100,
	e			= 101,
	f			= 102,
	g			= 103,
	h			= 104,
	i			= 105,
	j			= 106,
	k			= 107,
	l			= 108,
	m			= 109,
	n			= 110,
	o			= 111,
	p			= 112,
	q			= 113,
	r			= 114,
	s			= 115,
	t			= 116,
	u			= 117,
	v			= 118,
	w			= 119,
	x			= 120,
	y			= 121,
	z			= 122,
	/// End of ASCII mapped keysyms
	DELETE		= 127,


	/// International keyboard syms 0xA0

	WORLD_0		= 160,
	WORLD_1		= 161,
	WORLD_2		= 162,
	WORLD_3		= 163,
	WORLD_4		= 164,
	WORLD_5		= 165,
	WORLD_6		= 166,
	WORLD_7		= 167,
	WORLD_8		= 168,
	WORLD_9		= 169,
	WORLD_10		= 170,
	WORLD_11		= 171,
	WORLD_12		= 172,
	WORLD_13		= 173,
	WORLD_14		= 174,
	WORLD_15		= 175,
	WORLD_16		= 176,
	WORLD_17		= 177,
	WORLD_18		= 178,
	WORLD_19		= 179,
	WORLD_20		= 180,
	WORLD_21		= 181,
	WORLD_22		= 182,
	WORLD_23		= 183,
	WORLD_24		= 184,
	WORLD_25		= 185,
	WORLD_26		= 186,
	WORLD_27		= 187,
	WORLD_28		= 188,
	WORLD_29		= 189,
	WORLD_30		= 190,
	WORLD_31		= 191,
	WORLD_32		= 192,
	WORLD_33		= 193,
	WORLD_34		= 194,
	WORLD_35		= 195,
	WORLD_36		= 196,
	WORLD_37		= 197,
	WORLD_38		= 198,
	WORLD_39		= 199,
	WORLD_40		= 200,
	WORLD_41		= 201,
	WORLD_42		= 202,
	WORLD_43		= 203,
	WORLD_44		= 204,
	WORLD_45		= 205,
	WORLD_46		= 206,
	WORLD_47		= 207,
	WORLD_48		= 208,
	WORLD_49		= 209,
	WORLD_50		= 210,
	WORLD_51		= 211,
	WORLD_52		= 212,
	WORLD_53		= 213,
	WORLD_54		= 214,
	WORLD_55		= 215,
	WORLD_56		= 216,
	WORLD_57		= 217,
	WORLD_58		= 218,
	WORLD_59		= 219,
	WORLD_60		= 220,
	WORLD_61		= 221,
	WORLD_62		= 222,
	WORLD_63		= 223,
	WORLD_64		= 224,
	WORLD_65		= 225,
	WORLD_66		= 226,
	WORLD_67		= 227,
	WORLD_68		= 228,
	WORLD_69		= 229,
	WORLD_70		= 230,
	WORLD_71		= 231,
	WORLD_72		= 232,
	WORLD_73		= 233,
	WORLD_74		= 234,
	WORLD_75		= 235,
	WORLD_76		= 236,
	WORLD_77		= 237,
	WORLD_78		= 238,
	WORLD_79		= 239,
	WORLD_80		= 240,
	WORLD_81		= 241,
	WORLD_82		= 242,
	WORLD_83		= 243,
	WORLD_84		= 244,
	WORLD_85		= 245,
	WORLD_86		= 246,
	WORLD_87		= 247,
	WORLD_88		= 248,
	WORLD_89		= 249,
	WORLD_90		= 250,
	WORLD_91		= 251,
	WORLD_92		= 252,
	WORLD_93		= 253,
	WORLD_94		= 254,
	/// 0xFF
	WORLD_95		= 255,

	/// Numeric keypad
	KP0		= 256,
	KP1		= 257,
	KP2		= 258,
	KP3		= 259,
	KP4		= 260,
	KP5		= 261,
	KP6		= 262,
	KP7		= 263,
	KP8		= 264,
	KP9		= 265,
	KP_PERIOD		= 266,
	KP_DIVIDE		= 267,
	KP_MULTIPLY	= 268,
	KP_MINUS		= 269,
	KP_PLUS		= 270,
	KP_ENTER		= 271,
	KP_EQUALS		= 272,

	/// Arrows + Home/End pad
	UP			= 273,
	DOWN		= 274,
	RIGHT		= 275,
	LEFT		= 276,
	INSERT		= 277,
	HOME		= 278,
	END		= 279,
	PAGEUP		= 280,
	PAGEDOWN		= 281,

	/// Function keys
	F1			= 282,
	F2			= 283,
	F3			= 284,
	F4			= 285,
	F5			= 286,
	F6			= 287,
	F7			= 288,
	F8			= 289,
	F9			= 290,
	F10		= 291,
	F11		= 292,
	F12		= 293,
	F13		= 294,
	F14		= 295,
	F15		= 296,

	/// Key state modifier keys
	NUMLOCK		= 300,
	CAPSLOCK		= 301,
	SCROLLOCK		= 302,
	RSHIFT		= 303,
	LSHIFT		= 304,
	RCTRL		= 305,
	LCTRL		= 306,
	RALT		= 307,
	LALT		= 308,
	RMETA		= 309,
	LMETA		= 310,
		/// Left "Windows" key
	LSUPER		= 311,
		/// Right "Windows" key
	RSUPER		= 312,
		/// "Alt Gr" key
	MODE		= 313,
		/// Multi-key compose key
	COMPOSE		= 314,

		/// Miscellaneous function keys
	HELP		= 315,
	PRINT		= 316,
	SYSREQ		= 317,
	BREAK		= 318,
	MENU		= 319,
		/// Power Macintosh power key
	POWER		= 320,
		/// Some european keyboards
	EURO		= 321,
		/// Atari keyboard has Undo
	UNDO		= 322,

	/// Add any other keys here

	LAST
}
