#include "MidiNrpn.h"

MidiNrpn::MidiNrpn()
: mState(0)
, mId(0)
, mValue(0)
, mMaxValue(0)
, mIsValid(false)
{

}

MidiNrpn::~MidiNrpn()
{

}

void MidiNrpn::reset()
{
	mIsValid = false;
	mId = 0;
	mValue = 0;
	mMaxValue = 0;
	mState = 0;
}

int MidiNrpn::getId()
{
	return mId;
}

bool MidiNrpn::isValid(bool doClear)
{
	bool result = mIsValid;
	if (doClear)
	{
		mIsValid = false;
	}
	return result;
}

int MidiNrpn::getValue()
{
	return mValue;
}

int MidiNrpn::getMaxValue()
{
	return mMaxValue;
}

bool MidiNrpn::process(uint8_t controllerNumber, uint8_t controllerValue)
{
	int state_nxt = mState;
	switch (mState)
	{
		case 0:
		if (controllerNumber == 99)
		{
			state_nxt = 1;
			mId = (uint16_t)controllerValue & 0x007F;
		}
		break;

		case 1:
		if (controllerNumber == 98)
		{
			state_nxt = 2;
			mId = mId << 7 | (uint16_t)controllerValue & 0x007F;
		}
		else
		{
			reset();
		}
		break;

		case 2:
		if (controllerNumber == 6)
		{
			state_nxt = 3;
			mValue = (uint16_t)controllerValue & 0x007F;
			mMaxValue = 128;
		}
		else
		{
			reset();
		}
		break;

		case 3:
		if (controllerNumber == 38)
		{
			state_nxt = 4;
			mValue = mValue << 7 | (uint16_t)controllerValue & 0x007F;
			mMaxValue *= 128;
		}
		else if (controllerNumber == 99)
		{
			state_nxt = 4;
		}
		else
		{
			reset();
		}
		break;

		case 4:
		if (controllerNumber == 99)
		{
			// Do nothing
		}
		else if (controllerNumber == 98)
		{
			state_nxt = 0;
			mIsValid = true;
		}
		else
		{
			reset();
		}
		break;

		default:
		break;
	}
	mState = state_nxt;

	return mState != 0;
}
