#ifndef _INPUT_H_
#define _INPUT_H_

#include "Input_Macros.h"

namespace Input
{

	class InputManager
	{
		// Singleton
		static InputManager* sInstance;
		InputManager();
		InputManager(const InputManager& im) {}

		// Will we use this type of input?
		bool mMouseEnabled;
		bool mKeyboardEnabled;

		// Mouse data
		int mMouseX;
		int mMouseY;
		int mMouseLastX;
		int mMouseLastY;
		bool mResetMousePos;
		float mMouseSpeedH;
		float mMouseSpeedV;

		ADD_INPUT_KEY(W);
		ADD_INPUT_KEY(A);
		ADD_INPUT_KEY(S);
		ADD_INPUT_KEY(D);
		ADD_INPUT_KEY(Shift);
		ADD_INPUT_KEY(LMouseButton);
		ADD_INPUT_KEY(Space);

	private: // Need to say private again for anything below because input macros leave it off at public!


	public:
		static InputManager& I();

		enum InputType
		{
			INPUT_TYPE_MOUSE = 0,
			INPUT_TYPE_KEYBOARD = 1,
			// Joypad input??
		};

		// Updates
		void UpdateMousePos(int aX, int aY); // This gets called in the mouse moved callback function
		void UpdateMouseButtons();
		void UpdateKeyboardButtons();

		// Input flags
		bool IsEnabled(InputType aType);
		void SetEnabled(InputType aType, bool aState);

		bool IsMouseEnabled() const { return mMouseEnabled; }
		bool IsKeyboardEnabled() const { return mKeyboardEnabled; }
		void EnableMouse() { mMouseEnabled = true; }
		void EnableKeyboard() { mKeyboardEnabled = true; }
		void DisableMouse() { mMouseEnabled = false; }
		void DisableKeyboard() { mKeyboardEnabled = false; }

		// Mouse logic
		void CenterMousePos();
		void ShowMouseCursor(bool aShow);

		int GetMouseXDelta() const { return (mMouseX - mMouseLastX); }
		int getMouseYDelta() const { return (mMouseY - mMouseLastY); }
		int GetMouseX() const { return mMouseX; }
		int GetMouseY() const { return mMouseY; }
		bool IsResetMousPos() const { return mResetMousePos; }
		bool SetResetMousePos(bool aState) { mResetMousePos = aState; }
		float GetMouseSpeedH() const { return mMouseSpeedH; }
		float GetMouseSpeedV() const { return mMouseSpeedV; }
		void SetMouseSpeedH(float aSpeed) { mMouseSpeedH = aSpeed; }
		void SetMouseSpeedV(float aSpeed) { mMouseSpeedV = aSpeed; }
		int GetMouseLastX() const { return mMouseLastX; }
		int GetMouseLastY() const { return mMouseLastY; }
	};

}

#endif // Close _INPUT_H_