#pragma once
#include "IInput.h"

struct MouseState
{
	MouseState()
		: m_x( 0 )
		, m_y( 0 )
		, m_z( 0 )
		, m_buttons( 0 )
	{}

	int m_x, m_y, m_z;
	int m_buttons;
};

/*
	Implementation of IInput interface for Allegro5
*/
class AllegroInput5 : public IInput
{
	static const int MAX_EVENTS = 256;

	  // Initialized input methods
	bool m_hasKeyboard;
	bool m_hasMouse;
	bool m_hasGamepad;	

	  // Saved input events
	std::vector<InputEvent> m_events;
	  // Saved keyboard states
	std::bitset<ALLEGRO_KEY_MAX> m_keyStates;
	  // Keyboard repeat timer
	int m_repeatTimer;
	  // Mouse support disabled for reasons I can't remember :)
	  //MouseState m_mouseState;
	  // For catching double-click events
	int m_doubleClickTimer;

	ALLEGRO_EVENT_QUEUE *m_queue;

	  // Event index in queue, used for reading
	size_t m_eventIndex;

	void AddEvent( InputEvent ev );
public:
	AllegroInput5()
		: m_eventIndex( 0 )
		, m_queue( 0 )
		, m_doubleClickTimer( 0 )
	{}

	~AllegroInput5();

	  // Initializes Input with support for some devices
	bool Init( bool keyboard, bool mouse, bool gamepad );
	
	  // Helper/debug function
	void WaitAnyKey();
	
	  // Restarts reading event queue
	void BeginRead()
	{
		m_eventIndex = 0;
	}
	  // Get next event from queue. If there are no more events, return InputEvent with type EVENT_INVALID
	InputEvent GetEvent();
	  // Moves index to the next event without removing current one from queue
	void NextEvent();
	  // Removes current event from queue and move index to the next one
	void PopEvent();
	
	  // Polls states, processes events
	void Update( int dt );
	
	  // Removes all pending events from queue
	void Clear()
	{
		m_eventIndex = 0;
		m_events.clear();
	}
};

  // Singleton for accessing Input
IInput & GetInput()
{
	static AllegroInput5 input;
	return input;
}
