#include "input_base.h"

using namespace Halley;

InputButtonBase::InputButtonBase(int nButtons)
{
	if (nButtons != -1) init(nButtons);
}

void InputButtonBase::init(int nButtons)
{
	buttonPressed.resize(nButtons);
	buttonReleased.resize(nButtons);
	buttonDown.resize(nButtons);
}

void InputButtonBase::onButtonPressed(int code)
{
	buttonPressed[code] = true;
	if (!buttonDown[code]) {
		// Note that this doesn't set released as false. It's possible to get a press and a release on the same step.
		buttonDown[code] = true;
	}
}

void InputButtonBase::onButtonReleased(int code)
{
	if (buttonDown[code]) {
		// See comment on method above
		buttonReleased[code] = true;
		buttonDown[code] = false;
	}
}

void InputButtonBase::onButtonStatus(int code, bool down)
{
	// This method should probably not be used with the two above
	// This is designed for polled input, such as XInput controllers
	bool wasDown = buttonDown[code] != 0;
	buttonDown[code] = down;
	if (wasDown && !down) buttonReleased[code] = true;
	if (!wasDown && down) buttonPressed[code] = true;
}

void InputButtonBase::clearPresses()
{
	size_t len = buttonPressed.size();
	for (size_t i=0; i<len; i++) {
		buttonPressed[i] = 0;
		buttonReleased[i] = 0;
	}
}

bool InputButtonBase::isButtonPressed(int code)
{
	try {
		return buttonPressed.at(code) != 0;
	} catch (...) {
		return false;
	}
}

bool InputButtonBase::isButtonReleased(int code)
{
	try {
		return buttonReleased.at(code) != 0;
	} catch (...) {
		return false;
	}
}

bool InputButtonBase::isButtonDown(int code)
{
	try {
		return buttonDown.at(code) != 0;
	} catch (...) {
		return false;
	}
}
