#include "stdafx.h"
#include "WaveParserFront.h"


CWaveParserFront::CWaveParserFront()
    = default;


CWaveParserFront::~CWaveParserFront()
    = default;



//////////////////////////////////////////////////////////////////////
// Вход: pos - текущая позиция в сэмплах
//		 nLength - длина wave в сэмплах, предел, дальше которого нельзя
// Выход: длина импульса в сэмплах
int CWaveParserFront::CalcImpLength(WaveData &pWave, int &pos)
{
	auto nWaveLength = int(pWave.size());

	if (pos >= nWaveLength)
	{
		return CWaveParserProto::BAD_LENGTH;
	}

	int p = pos; //текущая позиция
	int len_0 = 0;
	int len_1 = 0;

	if (m_bInverse)
	{
		//тут всё инверсно, минимум - это максимум и наоборот

		//сперва надо найти локальный минимум
		if (findLocMax(pWave, p) == CWaveParserProto::BAD_LENGTH)
		{
			return CWaveParserProto::BAD_LENGTH;
		}
		//теперь подсчитаем, сколько сэмплов выполняется возрастание
		len_1 = findLocMin(pWave, p);

		if (len_1 == CWaveParserProto::BAD_LENGTH)
		{
			return CWaveParserProto::BAD_LENGTH;
		}
		//теперь подсчитаем, сколько сэмплов выполняется убывание
		len_0 = findLocMax(pWave, p);

		if (len_0 == CWaveParserProto::BAD_LENGTH)
		{
			return CWaveParserProto::BAD_LENGTH;
		}
	}
	else
	{
		//сперва надо найти локальный минимум
		if (findLocMin(pWave, p) == CWaveParserProto::BAD_LENGTH)
		{
			return CWaveParserProto::BAD_LENGTH;
		}
		//теперь подсчитаем, сколько сэмплов выполняется возрастание
		len_1 = findLocMax(pWave, p);

		if (len_1 == CWaveParserProto::BAD_LENGTH)
		{
			return CWaveParserProto::BAD_LENGTH;
		}
		//теперь подсчитаем, сколько сэмплов выполняется убывание
		len_0 = findLocMin(pWave, p);

		if (len_0 == CWaveParserProto::BAD_LENGTH)
		{
			return CWaveParserProto::BAD_LENGTH;
		}
	}

	pos = p;
	return len_1 + len_0;
}


int CWaveParserFront::findLocMin(WaveData &pWave, int &pos)
{
	auto nWaveLength = int(pWave.size());
	int len_0 = 0;

	while (true)
	{
		if (pos >= nWaveLength)
		{
			return CWaveParserProto::BAD_LENGTH;
		}

		double v = pWave[pos];  //берём очередной сэмпл

		if (v > m_dPrevV)   //если перестало уменьшаться
		{
			break;      //то мы нашли конец участка убывания
		}

		//если текущее значение меньше минимального
		m_dPrevV = v;   //то это новое минимальное

		if (++pos >= nWaveLength)
		{
			return CWaveParserProto::BAD_LENGTH;
		}

		len_0++;
	}

	return len_0;
}

int CWaveParserFront::findLocMax(WaveData &pWave, int &pos)
{
	auto nWaveLength = int(pWave.size());
	int len_1 = 0;

	while (true)
	{
		if (pos >= nWaveLength)
		{
			return CWaveParserProto::BAD_LENGTH;
		}

		double v = pWave[pos];  //берём очередной сэмпл

		if (v < m_dPrevV)   //если перестало увеличиваться
		{
			break;      //то мы нашли конец участка возрастания
		}

		m_dPrevV = v;   //то это новое максимальное

		if (++pos >= nWaveLength)
		{
			return CWaveParserProto::BAD_LENGTH;
		}

		len_1++;
	}

	return len_1;
}


//поиск первого маркера
bool CWaveParserFront::FindMarker1(WaveData &pWave)
{
	auto nWaveLength = int(pWave.size());
	int size = 0;
	int pos = m_nPos;

	for (;;)
	{
		//теперь подсчитаем, сколько сэмплов выполняется возрастание
		int len_1 = findLocMax(pWave, pos);

		if (len_1 == CWaveParserProto::BAD_LENGTH)
		{
			return false;
		}

		double l = double(len_1) / m_dAvgLength;

		if (MinusDelta(4.0) / 2.0 <= l && l <= PlusDelta(4.0) / 2.0)
		{
			break;
		}
		//теперь подсчитаем, сколько сэмплов выполняется убывание
		int len_0 = findLocMin(pWave, pos);

		if (len_0 == CWaveParserProto::BAD_LENGTH)
		{
			return false;
		}

		l = double(len_0) / m_dAvgLength;

		if (MinusDelta(4.0) / 2.0 <= l && l <= PlusDelta(4.0) / 2.0)
		{
			m_bInverse = true;
			break;
		}
	}

	m_nPos = pos;
	bool bBit;

	if (ReadBit(pWave, bBit))
	{
		return bBit;    //в правильном маркере бит - "1"
	}

	return false;
}


