#pragma once
#include <Multimedia/SDX.h>
#include <Multimedia/Keyboard.h>
#include <Multimedia/Mouse.h>
#include <Multimedia/Joypad.h>

namespace SDX
{
/** キーやマウスによる入力をまとめて管理するクラス.*/
///	\include InputSample.h
class Input
{
private:
	Input(){}
	~Input();
	static int handle;

public:

	static Joypad pad;
	static Mouse mouse;
	static Keyboard key;

	/** 状態をリセット.*/
	static void Reset()
	{
		Input::pad.Reset();
		Input::mouse.Reset();
		Input::key.Reset();
	}
	
	/** 状態を更新.*/
	static void Update()
	{
		Input::pad.Update();
		Input::mouse.Update();
		Input::key.Update();
	}

	#ifdef SDL
	static void GetState(SDL_Event &event)
	{
		bool upState = true;

		switch (event.type)
		{
			case SDL_KEYUP:
				upState = false;
			case SDL_KEYDOWN:
				switch (event.key.keysym.sym)
				{
					case SDLK_BACKSPACE: key.press[(int)KeyCode::Back] = upState; break;
					case SDLK_TAB: key.press[(int)KeyCode::Tab] = upState; break;
					case SDLK_RETURN: key.press[(int)KeyCode::Return] = upState; break;
					case SDLK_LSHIFT: key.press[(int)KeyCode::LShift] = upState; break;
					case SDLK_RSHIFT: key.press[(int)KeyCode::RShift] = upState; break;
					case SDLK_LCTRL: key.press[(int)KeyCode::LControl] = upState; break;
					case SDLK_RCTRL: key.press[(int)KeyCode::RControl] = upState; break;
					case SDLK_ESCAPE: key.press[(int)KeyCode::Escape] = upState; break;
					case SDLK_SPACE: key.press[(int)KeyCode::Space] = upState; break;
					case SDLK_PAGEUP: key.press[(int)KeyCode::PageUp] = upState; break;
					case SDLK_PAGEDOWN: key.press[(int)KeyCode::PageDown] = upState; break;
					case SDLK_END: key.press[(int)KeyCode::End] = upState; break;
					case SDLK_HOME: key.press[(int)KeyCode::Home] = upState; break;
					case SDLK_LEFT:
						key.press[(int)KeyCode::Left] = upState;
						pad.press[(int)PadCode::Left] = upState;
						break;
					case SDLK_UP: 
						key.press[(int)KeyCode::Up] = upState;
						pad.press[(int)PadCode::Up] = upState;
					break;
					case SDLK_RIGHT:
						key.press[(int)KeyCode::Right] = upState;
						pad.press[(int)PadCode::Right] = upState;
						break;
					case SDLK_DOWN:
						key.press[(int)KeyCode::Down] = upState;
						pad.press[(int)PadCode::Down] = upState;
						break;
					case SDLK_INSERT: key.press[(int)KeyCode::Insert] = upState; break;
					case SDLK_DELETE: key.press[(int)KeyCode::Delete] = upState; break;

					case SDLK_MINUS: key.press[(int)KeyCode::Minus] = upState; break;
					//case Yen = SDLK_YEN,
					//case PrevTrack = SDLK_PREVTRACK,
					case SDLK_PERIOD: key.press[(int)KeyCode::Period] = upState; break;
					case SDLK_SLASH: key.press[(int)KeyCode::Slash] = upState; break;
					case SDLK_LALT: key.press[(int)KeyCode::LAlt] = upState; break;
					case SDLK_RALT: key.press[(int)KeyCode::RAlt] = upState; break;
					case SDLK_SCROLLLOCK: key.press[(int)KeyCode::Scroll] = upState; break;
					case SDLK_SEMICOLON: key.press[(int)KeyCode::Semicolon] = upState; break;
					case SDLK_COLON: key.press[(int)KeyCode::Colon] = upState; break;
					case SDLK_LEFTBRACKET: key.press[(int)KeyCode::LBracket] = upState; break;
					case SDLK_RIGHTBRACKET: key.press[(int)KeyCode::RBracket] = upState; break;
					case SDLK_AT: key.press[(int)KeyCode::At] = upState; break;
					case SDLK_BACKSLASH: key.press[(int)KeyCode::Backslash] = upState; break;
					case SDLK_COMMA: key.press[(int)KeyCode::Comma] = upState; break;
					case SDLK_CAPSLOCK: key.press[(int)KeyCode::Capslock] = upState; break;
					case SDLK_PAUSE: key.press[(int)KeyCode::Pause] = upState; break;

					case SDLK_KP_0: key.press[(int)KeyCode::Numpad0] = upState; break;
					case SDLK_KP_1: key.press[(int)KeyCode::Numpad1] = upState; break;
					case SDLK_KP_2: key.press[(int)KeyCode::Numpad2] = upState; break;
					case SDLK_KP_3: key.press[(int)KeyCode::Numpad3] = upState; break;
					case SDLK_KP_4: key.press[(int)KeyCode::Numpad4] = upState; break;
					case SDLK_KP_5: key.press[(int)KeyCode::Numpad5] = upState; break;
					case SDLK_KP_6: key.press[(int)KeyCode::Numpad6] = upState; break;
					case SDLK_KP_7: key.press[(int)KeyCode::Numpad7] = upState; break;
					case SDLK_KP_8: key.press[(int)KeyCode::Numpad8] = upState; break;
					case SDLK_KP_9: key.press[(int)KeyCode::Numpad9] = upState; break;
					case SDLK_ASTERISK: key.press[(int)KeyCode::Multiply] = upState; break;
					case SDLK_KP_PLUS: key.press[(int)KeyCode::Add] = upState; break;
					case SDLK_KP_MINUS: key.press[(int)KeyCode::Subtract] = upState; break;
					case SDLK_KP_PERIOD: key.press[(int)KeyCode::Decimal] = upState; break;
					case SDLK_KP_DIVIDE: key.press[(int)KeyCode::Divide] = upState; break;
					case SDLK_KP_ENTER: key.press[(int)KeyCode::NUMPADEnter] = upState; break;

					case SDLK_F1: key.press[(int)KeyCode::F1] = upState; break;
					case SDLK_F2: key.press[(int)KeyCode::F2] = upState; break;
					case SDLK_F3: key.press[(int)KeyCode::F3] = upState; break;
					case SDLK_F4: key.press[(int)KeyCode::F4] = upState; break;
					case SDLK_F5: key.press[(int)KeyCode::F5] = upState; break;
					case SDLK_F6: key.press[(int)KeyCode::F6] = upState; break;
					case SDLK_F7: key.press[(int)KeyCode::F7] = upState; break;
					case SDLK_F8: key.press[(int)KeyCode::F8] = upState; break;
					case SDLK_F9: key.press[(int)KeyCode::F9] = upState; break;
					case SDLK_F10: key.press[(int)KeyCode::F10] = upState; break;
					case SDLK_F11: key.press[(int)KeyCode::F11] = upState; break;
					case SDLK_F12: key.press[(int)KeyCode::F12] = upState; break;

					case SDLK_a:
						key.press[(int)KeyCode::A] = upState;
						pad.press[(int)PadCode::Button5] = upState;
						break;
					case SDLK_b: key.press[(int)KeyCode::B] = upState; break;
					case SDLK_c:
						key.press[(int)KeyCode::C] = upState;
						pad.press[(int)PadCode::Button3] = upState;
						break;
					case SDLK_d: 
						key.press[(int)KeyCode::D] = upState;
						pad.press[(int)PadCode::Button7] = upState;
						break;
					case SDLK_e: key.press[(int)KeyCode::E] = upState; break;
					case SDLK_f:
						key.press[(int)KeyCode::F] = upState;
						pad.press[(int)PadCode::Button8] = upState;
						break;
					case SDLK_g: key.press[(int)KeyCode::G] = upState; break;
					case SDLK_h: key.press[(int)KeyCode::H] = upState; break;
					case SDLK_i: key.press[(int)KeyCode::I] = upState; break;
					case SDLK_j: key.press[(int)KeyCode::J] = upState; break;
					case SDLK_k: key.press[(int)KeyCode::K] = upState; break;
					case SDLK_l: key.press[(int)KeyCode::L] = upState; break;
					case SDLK_m: key.press[(int)KeyCode::M] = upState; break;
					case SDLK_n: key.press[(int)KeyCode::N] = upState; break;
					case SDLK_o: key.press[(int)KeyCode::O] = upState; break;
					case SDLK_p: key.press[(int)KeyCode::P] = upState; break;
					case SDLK_q: key.press[(int)KeyCode::Q] = upState; break;
					case SDLK_r: key.press[(int)KeyCode::R] = upState; break;
					case SDLK_s: 
						key.press[(int)KeyCode::S] = upState;
						pad.press[(int)PadCode::Button6] = upState;
						break;
					case SDLK_t: key.press[(int)KeyCode::T] = upState; break;
					case SDLK_u: key.press[(int)KeyCode::U] = upState; break;
					case SDLK_v:
						key.press[(int)KeyCode::V] = upState;
						pad.press[(int)PadCode::Button4] = upState;
						break;
					case SDLK_w: key.press[(int)KeyCode::W] = upState; break;
					case SDLK_x:
						key.press[(int)KeyCode::X] = upState;
						pad.press[(int)PadCode::Button2] = upState;
						break;
					case SDLK_y: key.press[(int)KeyCode::Y] = upState; break;
					case SDLK_z:
						key.press[(int)KeyCode::Z] = upState;
						pad.press[(int)PadCode::Button1] = upState;
						break;
					case SDLK_0: key.press[(int)KeyCode::_0] = upState; break;
					case SDLK_1: key.press[(int)KeyCode::_1] = upState; break;
					case SDLK_2: key.press[(int)KeyCode::_2] = upState; break;
					case SDLK_3: key.press[(int)KeyCode::_3] = upState; break;
					case SDLK_4: key.press[(int)KeyCode::_4] = upState; break;
					case SDLK_5: key.press[(int)KeyCode::_5] = upState; break;
					case SDLK_6: key.press[(int)KeyCode::_6] = upState; break;
					case SDLK_7: key.press[(int)KeyCode::_7] = upState; break;
					case SDLK_8: key.press[(int)KeyCode::_8] = upState; break;
					case SDLK_9: key.press[(int)KeyCode::_9] = upState; break;
				}
				break;
			case SDL_MOUSEBUTTONUP:
				upState = false;
			case SDL_MOUSEBUTTONDOWN:
				switch (event.button.button)
				{
					case SDL_BUTTON_LEFT:mouse.press[(int)MouseCode::Left] = upState; break;
					case SDL_BUTTON_RIGHT:mouse.press[(int)MouseCode::Right] = upState; break;
					case SDL_BUTTON_MIDDLE:mouse.press[(int)MouseCode::Middle] = upState; break;
					case SDL_BUTTON_X1:mouse.press[(int)MouseCode::_4] = upState; break;
					case SDL_BUTTON_X2:mouse.press[(int)MouseCode::_5] = upState; break;
				}
				break;
			case SDL_JOYAXISMOTION:
				//左右の動き
				if (event.jaxis.axis == 0)
				{
					pad.StickX = event.jaxis.value;
					if (event.jaxis.value < -0x7000) pad.press[(int)PadCode::Left] = true;
					if (event.jaxis.value >  0x7000) pad.press[(int)PadCode::Right] = true;
				}
				//上下の動き
				if (event.jaxis.axis == 1)
				{
					pad.StickY = event.jaxis.value;
					if (event.jaxis.value < -0x7000) pad.press[(int)PadCode::Up] = true;
					if (event.jaxis.value >  0x7000) pad.press[(int)PadCode::Down] = true;
				}
				break;
			case SDL_JOYHATMOTION:
				switch (event.jhat.value)
				{
					case SDL_HAT_UP:pad.press[(int)PadCode::Up] = true;break;
					case SDL_HAT_LEFT:pad.press[(int)PadCode::Left] = true; break;
					case SDL_HAT_DOWN:pad.press[(int)PadCode::Down] = true; break;
					case SDL_HAT_RIGHT:pad.press[(int)PadCode::Right] = true;break;
				}
				break;
			case SDL_JOYBUTTONUP:
				upState = false;
			case SDL_JOYBUTTONDOWN:
				pad.press[event.jbutton.button] = upState;
				break;
		}
	}
	#endif

	/** キーボードから文字を入力.*/
	///入力中は全ての処理が停止する
	static bool Text(int x,int y,int maxLength, char *str ,int isEscCancel ,bool isSingleOnly = false)
	{
	#ifdef DXLIB
		if (isSingleOnly)
		{
			return (DxLib::KeyInputString(x, y, maxLength, str, isEscCancel) == 1);
		}
		else{
			return ( DxLib::KeyInputSingleCharString( x , y ,maxLength , str , isEscCancel ) == 1 );
		}
	#elif defined(SDL)
		return false;
	#endif
	}
	
	/** キーボードから数字を入力.*/
	///数値入力ウィンドウを表示する
	///入力中は全ての処理が停止する
	///入力した値を返す、失敗した場合、範囲外の数値を返す
	static int Number(int x,int y,int min,int max,int isEscCancel)
	{
	#ifdef DXLIB
		return DxLib::KeyInputNumber(x, y, max, min, isEscCancel);
	#elif defined(SDL)
		return false;
	#endif
	}
	
	/** テキスト入力モードの開始.*/
	///他の処理を止めずに文字入力するモードを開始する
	static bool StartTextMode( int 最大文字数 , bool ESCキャンセル可能フラグ , bool 半角文字限定フラグ , bool 数値入力限定フラグ )
	{
	#ifdef DXLIB
		if (handle != NULL_HANDLE)
		{
			handle = DxLib::MakeKeyInput(最大文字数, ESCキャンセル可能フラグ, 半角文字限定フラグ, 数値入力限定フラグ);
		}
		DxLib::SetActiveKeyInput( handle );
	#elif defined(SDL)
		return false;
	#endif
	}
	
	/** テキスト入力モードの確認.*/
	static int CheckText()
	{
	#ifdef DXLIB
		return DxLib::CheckKeyInput( handle );
	#elif defined(SDL)
		return false;
	#endif
	}
	
	/** テキストの描画.*/
	static bool DrawText(int X座標 , int Y座標 )
	{
	#ifdef DXLIB
		DxLib::DrawKeyInputString( X座標 , Y座標 , handle );
	#elif defined(SDL)
		return false;
	#endif
	}
	
	/** テキストの設定.*/
	static bool SetText( const char* 文字列 )
	{
	#ifdef DXLIB
		DxLib::SetKeyInputString(文字列, handle);
	#elif defined(SDL)
		return false;
	#endif
	}
	static bool SetText( int 数値 )
	{
	#ifdef DXLIB
		DxLib::SetKeyInputNumber(数値, handle);
	#elif defined(SDL)
		return false;
	#endif
	}

	/** テキストの取得.*/
	static bool GetText( char* 出力バッファ )
	{
	#ifdef DXLIB
		return !GetKeyInputString(出力バッファ, handle);
	#elif defined(SDL)
		return false;
	#endif
	}


	/** キーボード入力時の表示色設定.*/
	static int SetKeyColor(
		int 入力文字色 ,
		int IME非使用時カーソル色 ,
		int IME使用時文字色 ,
		int IME使用時カーソル色 ,
		int 変換時下線色 ,
		int IME使用時変換候補色 ,
		int 入力モード名色 ,
		int 入力文字縁色 ,
		int 変換候補縁色 ,
		int 入力モード名縁色 ,
		int 変換候補ウィンドウ縁色 ,
		int 変換候補ウィンドウ色 ) 
	{
		#ifdef DXLIB
		return DxLib::SetKeyInputStringColor
			(
			入力文字色,
			IME非使用時カーソル色,
			IME使用時文字色,
			IME使用時カーソル色,
			変換時下線色,
			IME使用時変換候補色,
			入力モード名色,
			入力文字縁色,
			変換候補縁色,
			入力モード名縁色,
			変換候補ウィンドウ縁色,
			変換候補ウィンドウ色
			);
		#elif defined(SDL)
		return false;
		#endif
	}

};

}