#include "JoystickInput.h"

void JoystickInput::Init()
{
	//关闭所有的手柄
	//打开所有手柄
	SDL_JoystickEventState(SDL_ENABLE);
	int num = SDL_NumJoysticks();
	for (int i = 0; i < num; i++)
	{
		auto pGameController = SDL_GameControllerOpen(i);
		if (pGameController)
			gameControllerList.insert(pGameController);
	}
}

void JoystickInput::Reset()
{
	for (auto& p : gameControllerList)
		SDL_GameControllerClose(p);
	gameControllerList.clear();
	Init();
}

bool JoystickInput::GetState(SDL_GameController* pGameController, SDL_GameControllerButtonBind* keyBind, float* outAxis)
{
	if (!pGameController || !keyBind)
		return false;
	if (outAxis)
		*outAxis = 0;
	float axisVal = 0;
	switch (keyBind->bindType)
	{
	case SDL_CONTROLLER_BINDTYPE_BUTTON://按钮
		return GetButton(pGameController, (SDL_GameControllerButton)keyBind->value.button);
	case SDL_CONTROLLER_BINDTYPE_AXIS://摇杆
		axisVal = GetAxis(pGameController, (SDL_GameControllerAxis)keyBind->value.axis);
		if (outAxis)
			*outAxis = axisVal;
		return axisVal != 0;
	}
	return false;
}

bool JoystickInput::GetButton(SDL_GameController* pGameController, SDL_GameControllerButton button)
{
	if (!pGameController)
		return false;
	return SDL_GameControllerGetButton(pGameController, button);
}

float JoystickInput::GetAxis(SDL_GameController* pGameController, SDL_GameControllerAxis axis)
{
	float retVal = 0;
	if (!pGameController)
		return retVal;
	auto val = SDL_GameControllerGetAxis(pGameController, axis);
	float v = ((float)val / (float)INT16_MAX);//%15-%90 -> [0,1]
	if (v >= 0)
	{
		if (v < 0.15f)
			retVal = 0;
		else if (v >= 0.9f)
			retVal = 1;
		else
			retVal = (v - 0.15f) / (0.75f);
	}
	else
	{
		if (v > -0.15)
			retVal = 0;
		else if (v <= -0.9)
			retVal = -1;
		else
			retVal = (v + 0.15f) / (0.75f);
	}
	return retVal;
}

std::unordered_set< SDL_GameController*>* JoystickInput::GetGameControllerList()
{
	return &gameControllerList;
}

SDL_GameController* JoystickInput::GetFirstGameController()
{
	if (!gameControllerList.empty())
		return *gameControllerList.begin();
	return nullptr;
}
