#include "input_virtual.h"

using namespace Halley;

InputVirtual::InputVirtual(int nButtons, int nAxes)
{
	buttons.resize(nButtons);
	axes.resize(nAxes);
}

size_t InputVirtual::getNumberButtons()
{
	return buttons.size();
}

size_t InputVirtual::getNumberAxes()
{
	return axes.size();
}

bool InputVirtual::isButtonPressed(int code)
{
	auto& binds = buttons.at(code);
	foreach (Bind& bind, binds) {
		if (bind.device->isButtonPressed(bind.a)) {
			return true;
		}
	}
	return false;
}

bool InputVirtual::isButtonReleased(int code)
{
	auto& binds = buttons.at(code);
	foreach (Bind& bind, binds) {
		if (bind.device->isButtonReleased(bind.a)) {
			return true;
		}
	}
	return false;
}

bool InputVirtual::isButtonDown(int code)
{
	auto& binds = buttons.at(code);
	foreach (Bind& bind, binds) {
		if (bind.device->isButtonDown(bind.a)) {
			return true;
		}
	}
	return false;
}

float InputVirtual::getAxis(int n)
{
	auto& binds = axes.at(n);
	float value = 0;

	foreach (Bind& b, binds) {
		if (b.isAxis) {
			value += b.device->getAxis(b.a);
		} else {
			int left = b.device->isButtonDown(b.a) ? 1 : 0;
			int right = b.device->isButtonDown(b.b) ? 1 : 0;
			value += right - left;
		}
	}

	return value;
}

void InputVirtual::bindButton(int n, spInputBase device, int deviceN)
{
	buttons.at(n).push_back(Bind(device, deviceN));
}

void InputVirtual::bindAxis(int n, spInputBase device, int deviceN)
{
	axes.at(n).push_back(Bind(device, deviceN));
}

void InputVirtual::bindAxisButton(int n, spInputBase device, int negativeButton, int positiveButton)
{
	axes.at(n).push_back(Bind(device, negativeButton, positiveButton));
}

void InputVirtual::bindVibration(spInputBase joy)
{
	vibration = joy;
}

void InputVirtual::unbindButton(int n)
{
	buttons.at(n).clear();
}

void InputVirtual::unbindAxis(int n)
{
	axes.at(n).clear();
}

void InputVirtual::clearBindings()
{
	for (size_t i=0; i<buttons.size(); i++) {
		buttons[i].clear();
	}
	for (size_t i=0; i<axes.size(); i++) {
		axes[i].clear();
	}
	vibration = spInputBase();
}

void InputVirtual::setVibration(float high, float low)
{
	if (vibration) {
		vibration->setVibration(high, low);
	}
}
