//..............................................................................
//
// Ninja log - representer
//

import "log_RecordCode.jnc"

namespace log {

//! \addtogroup api-log
//! @{

//..............................................................................

// each record is represented as a sequence of 'parts'

enum PartKind
{
	PlainText = 0,
	HyperText,
	Bin,
	DualBin,
	Break,
	BinPreview,
	DualBinPreview,
}

//..............................................................................

// visual attributes of representation

enum StdLogIcon
{
	Info = 0,
	Warning,
	Error,
	LightBulb,
	Play,
	Pause,
	Stop,
	Connect,
	Disconnect,
	Listen,
	StopListen,
	TxPacket,
	RxPacket,
	Packet,
	Tx,
	Rx,
	TxRx,
	_Count,
}

// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

enum StdLogColor
{
	Start      = ui.StdColor.PastelPurple,
	Connect    = ui.StdColor.PastelGreen,
	Disconnect = ui.StdColor.PastelGreen,
	Info       = ui.StdColor.PastelBlue,
	Warning    = ui.StdColor.PastelYellow,
	Alert      = ui.StdColor.PastelOrange,
	Error      = ui.StdColor.PastelRed,
	Tx         = ui.StdColor.Blue,
	Rx         = ui.StdColor.Green,
}

// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

bitflag enum LineAttrFlags
{
	TileIcon,
	Delimiter,
	Override,
	Preview,
}

// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

struct LineAttr: ui.TextAttr
{
	LineAttrFlags m_flags;
	uint_t m_iconIdx;
}

//..............................................................................

opaque class Representation
{
	uint64_t readonly m_timestamp;
	uint64_t readonly m_recordCode;
	LineAttr m_lineAttr;
	ui.TextAttr m_auxTextAttr; // for dual bin

	void addPart(
		PartKind partKind,
		uint64_t partCode,
		void const* p,
		size_t size
		);

	void retroColorize(
		intptr_t retroOffset,
		size_t length,
		ui.TextAttr attr,
		RetroColorizeFlags flags = 0
		);

	void addBreak()
	{
		addPart(PartKind.Break, 0, null, 0);
	}

	void addPlainText(
		uint64_t partCode,
		char const* text
		)
	{
		addPart(PartKind.PlainText, partCode, text, strlen(text));
	}

	void addPlainText(char const* text)
	{
		addPart(PartKind.PlainText, m_recordCode, text, strlen(text));
	}

	void addHyperText(
		uint64_t partCode,
		char const* text
		)
	{
		addPart(PartKind.HyperText, partCode, text, strlen(text));
	}

	void addHyperText(char const* text)
	{
		addPart(PartKind.HyperText, m_recordCode, text, strlen(text));
	}

	void addBin(
		uint64_t partCode,
		void const* p,
		size_t size
		)
	{
		addPart(PartKind.Bin, partCode, p, size);
	}

	void addBin(
		void const* p,
		size_t size
		)
	{
		addPart(PartKind.Bin, m_recordCode, p, size);
	}

	void addBinPreview(
		uint64_t partCode,
		void const* p,
		size_t size
		)
	{
		addPart(PartKind.BinPreview, partCode, p, size);
	}

	void addBinPreview(
		void const* p,
		size_t size
		)
	{
		addPart(PartKind.BinPreview, m_recordCode, p, size);
	}

	void addDualBin(
		uint64_t partCode,
		void const* p1,
		void const* p2,
		size_t size
		)
	{
		void const* p = memcat(p1, size, p2, size);
		addPart(PartKind.DualBin, partCode, p, size * 2);
	}

	void addDualBin(
		void const* p1,
		void const* p2,
		size_t size
		)
	{
		addDualBin(m_recordCode, p1, p2, size);
	}

	void addDualBinPreview(
		uint64_t partCode,
		void const* p1,
		void const* p2,
		size_t size
		)
	{
		void const* p = memcat(p1, size, p2, size);
		addPart(PartKind.DualBinPreview, partCode, p, size * 2);
	}

	void addDualBinPreview(
		void const* p1,
		void const* p2,
		size_t size
		)
	{
		addDualBinPreview(m_recordCode, p1, p2, size);
	}
}

//..............................................................................

// each representer must be a pure stateless function (depend ONLY on params)

typedef bool RepresenterFunc(
	Representation* representation,
	uint64_t recordCode,
	void const* p,
	size_t size,
	uint_t foldFlags
	);

//..............................................................................

//! @}

} // namespace log
