//..............................................................................
//
// SPI tap log representer
//

import "log_Representation.jnc"
import "SpiTapLogRecordCode.jnc"

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

string_t getTableString(
	uint_t value,
	string_t const* table
) {
	return value < dynamic countof(table) ? table[value] : "\e[31mundefined\e[m";
}

bool representSpiTapLog(
	log.Representation* representation,
	uint64_t recordCode,
	void const* p,
	size_t size,
	uint_t foldFlags
) {
	static string_t const endiannessStringTable[] = {
		"Little-endian (LSBit first)",
		"Big-endian (MSBit first)",
	}
	switch (recordCode) {
	case SpiTapLogRecordCode.TapOpened:
		SpiTapOpenParams const* params = (SpiTapOpenParams const*)p;
		string_t name = (char const*)(params + 1);

		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Connect;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Connect;

		string_t string;

		if (!(foldFlags & 1)) {
			string =
				$"[\e^+1\e[34m+\e[m] Opened tap \e[34m$name\e[m "
				$"\e[34m$(params.m_frequency)\e[m Hz "
				$"SPI mode $(params.m_mode)";
		} else {
			string_t endiannessString = getTableString(params.m_endianness, endiannessStringTable);

			string =
				$"[\e^-1\e[34m-\e[m] Opened tap \e[34m$name\n"
				$"    \e[90mClock:      \e[34m$(params.m_frequency)\e[m Hz\n"
				$"    \e[90mSPI mode:   \e[34m$(params.m_mode)\n"
				$"    \e[90mData bits:  $(params.m_dataBits)\n"
				$"    \e[90mEndianness: \e[34m$endiannessString";
		}

		representation.addHyperText(string);
		break;

	case SpiTapLogRecordCode.TapClosed:
		string_t name = (char const*)p;
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Disconnect;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Disconnect;
		representation.addHyperText($"Port \e[34m$name\e[m closed");
		break;

	case SpiTapLogRecordCode.TapOpenError:
		std.Error const* error = (std.Error const*)p;
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Error;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Error;
		representation.addHyperText($"Cannot open port: $(error.m_description)");
		break;

	case SpiTapLogRecordCode.FrequencyChanged:
		uint_t frequency = *(uint_t const*)p;

		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Info;
		representation.addHyperText($"Set clock frequency: \e[34m$frequency\e[m Hz");
		break;

	case SpiTapLogRecordCode.ModeChanged:
		uint_t mode = *(uint_t const*)p;
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Info;
		representation.addHyperText($"Set SPI mode: \e[34m$mode");
		break;

	case SpiTapLogRecordCode.DataBitsChanged:
		uint_t dataBits = *(uint_t const*)p;

		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Info;
		representation.addHyperText($"Set data bits: \e[34m$dataBits\e[m bits");
		break;

	case SpiTapLogRecordCode.EndiannessChanged:
		bool isMsbFirst = *(bool const*)p;
		string_t endiannessString = getTableString(isMsbFirst, endiannessStringTable);

		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Info;
		representation.addHyperText($"Set endianness: $endiannessString");
		break;

	case SpiTapLogRecordCode.TxRxOutOfSync:
		representation.m_lineAttr.m_iconIdx = log.StdLogIcon.Info;
		representation.m_lineAttr.m_backColor = log.StdLogColor.Info;
		representation.addHyperText($"SPI MOSI and MISO out-of-sync");
		break;

	default:
		return false;
	}

	return true;
}

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