// --------------------------------------------------------------
#ifndef _RADIO_FRAME_HPP_
#define	_RADIO_FRAME_HPP_

#include <cstdint>
#include <radio/radio_types.h>
#include <radio/cpx.h>
#include "FrameDefs.hpp"
#include "Symbolizer.hpp"
#include "Formatter.hpp"

class FrameReceiver
{
public:
	FrameReceiver(IDeFormatter *pRawFrameHandler)
		: m_deformatter(pRawFrameHandler)
		, m_desymbolizer( &m_deformatter)
		, m_framesCount(0)
		, m_byteCount(0)
	{
	}

	~FrameReceiver()
	{
	}

	frame_statistics_t getStats()
	{
		return m_deformatter.getStats();
	}

	void resetStats()
	{
		m_deformatter.resetStats();
	}

	void setNumBitsPerSymbol(uint32_t nBitsPerSym)
	{
		m_desymbolizer.setNumBitsPerSymbol(nBitsPerSym);
		m_deformatter.resetStats();
	}

	void process(symbol_t symbol)
	{
		m_desymbolizer.process(symbol);
	}

private:
	DeFormatter m_deformatter;
	DeSymbolizer m_desymbolizer;
	uint32_t m_framesCount;
	uint32_t m_byteCount;
};

class UnitFrameTransmitter
{
public:
	UnitFrameTransmitter(uint32_t nBitsPerSym, ISymbolizer *pReceiver)
		: m_symbolizer(pReceiver)
		, m_formatter(&m_symbolizer)
	{
		m_symbolizer.setNumBitsPerSymbol(nBitsPerSym);
	}
	~UnitFrameTransmitter()
	{
	}

	void process()
	{
		{
			uint8_t data[12];
			for (uint32_t i=0; i < sizeof(data); i++)
			{
				data[i] = i;
			}
			m_formatter.process(data, sizeof(data));
		}

		m_formatter.process(nullptr, 100);
		{
			uint8_t data[100];
			for (uint32_t i=0; i < sizeof(data); i++)
			{
				data[i] = i;
			}
			m_formatter.process(data, sizeof(data));
		}
		m_formatter.process(nullptr, 1);
	}

private:
	Symbolizer m_symbolizer;
	Formatter m_formatter;
};

class UnitFrameReceiver : public ISymbolizer, public IDeFormatter
{
public:
	UnitFrameReceiver(uint32_t nBitsPerSym)
		: m_deformatter(this)
		, m_desymbolizer(&m_deformatter)
	{
		m_desymbolizer.setNumBitsPerSymbol(nBitsPerSym);
	}

	~UnitFrameReceiver()
	{
	}

private:
	DeFormatter m_deformatter;
	DeSymbolizer m_desymbolizer;

	void onSymbol(symbol_t symbol) override
	{
		m_desymbolizer.process(symbol);
	}

	void onData(void *pData, uint32_t size) override 
	{
		// Received raw data		
		(void)pData;
		(void)size;
	}
 
};

// --------------------------------------------------------------
#endif // _RADIO_FRAME_HPP_
