#pragma once
#include <stdint.h>
#include "AVRDriver.h"

class AVRInterface : public AVRDriver {
public:
	/// @brief 
	/// @param SendMessage is the function this AVRInterface calls to send a message to the device
	/// 
	AVRInterface(
		NotifyCallBack notifyCB,	///<! used to notify the host of internal events
		SendCallBack sendCB			///<! used to send to the RS-232 interface
	);
	
	~AVRInterface();


	/// @brief Initialize the AVR interface and issue the ready command.
	/// 
	/// This is temporarily blocking since nothing else should run until ready
	/// 
	/// @return true if initialized
	/// 
	//bool Initialize();


	/// ReportAllStatus
	/// 
	/// @brief This will loop through the DT array and report the status of everything via the registered callback
	/// @param[in] offsetChanged indicates what index into the big buffer changed
	///				which can be used to highlight the fresh data
	/// 
	void ReportAllStatus(uint8_t offsetChanged = 0);

	/// ExportInformation
	/// 
	/// @brief Export all the numeric data to support a command line control option
	///
	/// @param[in] subsystem: Main | Zone 1 | Zone 2 | Zone 3
	/// @param[in] function : Power, Speaker, Volume, etc.
	/// @param[in] arg: on/off, etc.
	///
	void ExportInformation(AVRSubsystem_T subsystem = subsystemCount,
		AVRFunction_T function = fncFunctionCount,
		AVRArg_T arg = eARGCount);

	/// VolumeDBtoAPIValue
	/// 
	/// @brief Convert a floating point value to the internal API db units for volume
	/// @param db in the range of -80.0 to +16.5 db
	/// @return scaled to internal volume units
	/// 
	uint8_t VolumeDBtoAPIValue(float db);

	/// @brief permits snooping on what the driver intends to send to the AVR via RS-232
	/// 
	/// @param message 
	/// @param len 
	/// @return true
	//bool HostSendPassthru(const uint8_t * message, uint32_t len);


	const char *GetStateLabel(uint32_t st);

private:
	// Instance pointer used by the C-style NotifyCallBack trampoline.
	// There is only one AVRInterface instance expected in this design.
	static AVRInterface *s_instance;

	// The application supplied notify callback -- invoked by this interface
	// after the driver's notifications are processed by AVRInterface.
	NotifyCallBack AppNotify;

	// Trampoline used to set the AVRDriver::NotifyHost to a function
	// that dispatches into the instance method ProcessReportResponse.
	static bool NotifyTrampoline(AVRMessageType_T type, const void *message, uint32_t attrib);

	bool IsSanityCheckOK();
	void MessageHandlerSanityCheck();
	

	// host provided method to update the user with a text message
	//void(*ReportInformation)(AVRMessageType_T type, const char * message);

	uint8_t PCMessage(const char *msg, uint8_t len, uint8_t **src, const char *(fncHelper)(uint8_t val) = NULL, bool highlight = false);
	bool ProcessReportResponse(AVRMessageType_T type, const void * message, uint32_t attrib);
	void MessageReport(const char *prefix, const void *buf, size_t len = 0);
	const char *MessageToText(const char *msg, size_t len);
};
