#pragma once

#include "ehs/Array.h"
#include "ButtonState.h"

#define EHS_HID_UNKNOWN 0

namespace ehs
{
	class EHS_LIB_IO HID
	{
	protected:
		UInt_8 type;
		UInt_64 hashName;
		Str_8 name;
		UInt_64 id;
		Array<ButtonState> states;

	public:
		HID();

		HID(const UInt_8 type, Str_8 name, const UInt_64 id);

		HID(HID&& hid) noexcept;

		HID(const HID& hid);

		HID& operator=(HID&& hid) noexcept;

		HID& operator=(const HID& hid);

		bool operator==(const HID& other) const;

		bool operator!=(const HID& other) const;

		bool operator==(const UInt_64 otherId) const;

		bool operator!=(const UInt_64 otherId) const;

		virtual void Poll();

		UInt_8 GetType() const;

		Str_8 GetName() const;

		UInt_64 GetId() const;

		void ReleaseAll();

		Vector<const ButtonState*> GetAllTouched() const;

		const ButtonState* IsTouched(const Button& button) const;

		const ButtonState* IsTouched() const;

		Vector<const ButtonState*> GetAllDown() const;

		const ButtonState* IsDown(const Button& button) const;

		const ButtonState* IsDown() const;

		Vector<const ButtonState*> GetAllJustReleased() const;

		const ButtonState* IsJustReleased(const Button& button) const;

		const ButtonState* IsJustReleased() const;

		Vector<const ButtonState*> GetAllUp() const;

		const ButtonState* IsUp(const Button& button) const;

		const ButtonState* IsUp() const;

		void ButtonDown(const Button& button);

		void ButtonUp(const Button& button);

		const ButtonState* GetState(const Button& button) const;

		bool IsValid() const;

		virtual HID* Clone() const;

	private:
		bool HasState(const Button& button) const;

		bool AddState(const ButtonState& state);

		ButtonState* GetState(const Button& button);
	};
}