#ifndef UI_INTERFACE_H_
#define UI_INTERFACE_H_

#define PACKET_DATA_BUFFER_SIZE		(64u)

/* Packet formatting
 * 
 * Byte#:	Data
 * 0	:	START_BYTE0 (0x9C)
 * 1	:	START_BYTE1 (0x55)
 * 2	:	Packet type
 * 3	:	Bit inversion of packet type (eg if packet type = 0x3A, byte 3 = ~(0x3A) = 0xC5
 * 4	:	Data length n (LSB)
 * 5	:	Data length n (MSB)
 * 6 through 6+n	:	Data
 */
#define USART_START_BYTE0	(0x9Cu)
#define USART_START_BYTE1	(0x55u)

#define USART_START_BYTE0_OFFSET	(0u)
#define USART_START_BYTE1_OFFSET	(1u)
#define USART_PACKET_TYPE_OFFSET	(2u)
#define USART_INV_PACKET_TYPE_OFFSET	(3u)
#define USART_DATA_LENGTH_LSB_OFFSET	(4u)
#define USART_DATA_LENGTH_MSB_OFFSET	(5u)
#define USART_DATA_OFFSET			(6u)

#define MAX_PACKET_DATA_LENGTH		(PACKET_DATA_BUFFER_SIZE - USART_DATA_OFFSET)

typedef struct _data_packet {
	uint8_t Type;
	uint8_t ErrorCode;
	uint16_t Length;
	uint8_t Data[PACKET_DATA_BUFFER_SIZE];
	
} Data_Packet_T;


/* Packet error codes */
#define UI_ERR_NO_PACKET	(0x00u) // packet wasn't found in the buffer (no start byte or not long enough for zero-data packet)
#define UI_ERR_SUCCESS		(0x01u) // no errors here!

#define UI_ERR_BAD_START_SEQ	(0x10u) // START1 doesn't follow START0
#define UI_ERR_BAD_TYPE			(0x11u) // type and inverted type don't match
#define UI_ERR_INVALID_LENGTH	(0x12u) // length is too long

/* Packet types */
#define UI_ACK			HID_CODE_FOR_SUCCESS_REPLY
#define UI_NACK			HID_CODE_FOR_ERROR_REPLY

uint8_t* UI_check_packet(uint8_t* buf, uint32_t buf_length, Data_Packet_T* received_packet);
uint8_t UI_build_packet(uint8_t* buf, uint32_t buf_length, Data_Packet_T* pkt);
void UI_process_command(Data_Packet_T* req_pkt);
Data_Packet_T* UI_get_response(void);


#endif /* UI_INTERFACE_H_ */
