/*
 * Command_Definition.h
 *
 * Created: Wed Dec 08 2021 14:05:35
 *  Author Chris
 */
#ifndef COMMAND_DEFINITION_H_
#define COMMAND_DEFINITION_H_

// ============================================================================================
// Includes
#include <stdint.h>

#include "pico/types.h"
#include "pico/binary_info.h"


/////////////////////
// General Defines //
/////////////////////
#define NUM_LED_CHANNELS								1
#define NUM_LED_COLORS									3

#define RECEIVED_MIDI_HISTORY_BUFFER_SIZE				30
#define HISTORY_ENTRY_UNDEFINED							-1

#define NOTES_PER_OCTAVE								12

#define TIMER_INTERVALL_LED_UPDATE_ms					10

#define FADE_SPEED_MAX									20
#define FADE_SPEED_MIN									1

#define PAUSE_LIGHT_DELAY_MAX_s							60
#define PAUSE_LIGHT_DELAY_MIN_s							1

#define SCREEN_TIMEOUT_MAX_s							600
#define SCREEN_TIMEOUT_MIN_s							0

#define CONFIRMATION_COUNTER_TICKS						24

#define NO_NOTE											-1

#define CHANNEL_NAME_MAX_LENGTH							8

#define THRESHOLD_NO_SUPPLY_mV							1000
#define THRESHOLD_UNDERVOLTAGE_mV						11500
#define THRESHOLD_OVERVOLTAGE_mV						12500
#define THRESHOLD_MEASUREMENT_MAX_DEVIATION_mV			1000			


//////////////////////
// Jam Mode Defines //
//////////////////////
#define COLOR_CHANGE_MAX								20
#define COLOR_CHANGE_MIN								1

#define DURATION_MAX_s									200
#define DURATION_MIN_s									1


/////////////////////
// Command Defines //
/////////////////////
#define MULTICORE_COMMAND_EMPTY							 0
#define MULTICORE_NO_PARAMETER							 0

// General // 
#define MULTICORE_COMMAND_SET_MIDI_TO_LIGHT_ENABLED		'A'

// Direct Control //
#define MULTICORE_COMMAND_SET_DIRECT_RED				'B'
#define MULTICORE_COMMAND_SET_DIRECT_GREEN				'C'
#define MULTICORE_COMMAND_SET_DIRECT_BLUE				'D'
#define MULTICORE_COMMAND_SET_DIRECT_FADE_SPEED			'E'

// Voltage Supervision //
#define MULTICORE_COMMAND_SET_INA260_BUSVOLTAGE			'F'

#define MULTICORE_COMMAND_GET_ANALOG_VOLTAGE			'a'
#define MULTICORE_COMMAND_GET_LED_POWER_ERROR			'b'
#define MULTICORE_COMMAND_GET_LED_ENABLE_PIN			'c'
#define MULTICORE_COMMAND_GET_LED_ALERT_PIN			    'd'


// ============================================================================================
// Datatypes

/////////////////////
// Data Structrues //
/////////////////////
typedef int8_t 	Note_t;
typedef uint8_t Value_t;

typedef union 
{
	uint32_t Data;
	struct Command_s
	{
		uint8_t 	Command;
		uint8_t 	Parameter;
		int16_t 	Value;
	} Fields;
} Command_u;

typedef union 
{
	struct
	{
		uint8_t R;		
		uint8_t G;
		uint8_t B;
		uint8_t A;	// Alpha channel (unused, for 32-bit alignment)
        // uint8_t Gap;
		// uint8_t B;
		// uint8_t R;
		// uint8_t G;
	};
	uint8_t Array[4];
	uint32_t Pixel;
} __packed LED_Data_t;

typedef struct {
    int32_t Min;
    int32_t Max;
} __packed MinMax_t;

typedef struct {
	int16_t 	Data;
	uint64_t 	Timestamp_ms;
} History_Buffer_t;

typedef struct {
	uint8_t		Event;
	Note_t		Note;
	Note_t		Note_In_Octave;
	uint8_t		Velocity;
	uint64_t 	Timestamp_ms;
} Info_Last_Received_Note_t;

typedef struct 
{
	int32_t		MIDI_Channel;
	int32_t		Octave;
	int32_t 	Note_Color_Red;
	int32_t 	Note_Color_Green;
	int32_t 	Note_Color_Blue;
	uint8_t		Skip_Note_Off_Event;
    uint8_t     Note_Reset_Enabled;
    int32_t     Note_Reset_Timeout;
} __packed Channel_MIDI_Configuration_s;

typedef struct 
{
	uint8_t		Enabled;
	LED_Data_t 	Color;
	uint32_t	Timeout;
	int32_t 	Reset_Condition;
	int32_t 	Fade_Speed;
} __packed Pause_Light_Configuration_s;

typedef struct 
{
	uint32_t	Timer;
	bool 		Is_Active;
} Pause_Light_Timer_s;

typedef struct 
{
	MinMax_t    Durations;
	int32_t		Hue_Angle_Start_Color;
	int32_t	    Color_Change;
	int32_t 	Fade_Speed;
} __packed Jam_Light_Configuration_s;

typedef struct 
{
	LED_Data_t 	Color;
	int32_t 	Fade_Speed;
} __packed Const_Light_Configuration_s;


//////////////////
// Enumerations //
//////////////////
enum LED_Channel
{
	LED_Channel_1 = 0
};

enum LED_Color
{
	Red 	= 0, R = 0, Any = 0,
	Green 	= 1, G = 1,
	Blue 	= 2, B = 2
};

enum Pause_Light_Reset_Condition_e
{
	ANY_TRAFFIC,
	CHANNEL_MATCH,
	EVENT_MATCH,
	CHANNEL_AND_EVENT_MATCH
};
typedef enum Pause_Light_Reset_Condition_e Pause_Light_Reset_Condition;

enum MIDI_Channel_e
{
	MIDI_CHANNEL_1	= 0,
	MIDI_CHANNEL_2	= 1,
	MIDI_CHANNEL_3	= 2,
	MIDI_CHANNEL_4	= 3,
	MIDI_CHANNEL_5	= 4,
	MIDI_CHANNEL_6	= 5,
	MIDI_CHANNEL_7	= 6,
	MIDI_CHANNEL_8	= 7,
	MIDI_CHANNEL_9	= 8,
	MIDI_CHANNEL_10	= 9,
	MIDI_CHANNEL_11	= 10,
	MIDI_CHANNEL_12	= 11,
	MIDI_CHANNEL_13	= 12,
	MIDI_CHANNEL_14	= 13,
	MIDI_CHANNEL_15	= 14,
	MIDI_CHANNEL_16	= 15
};
typedef enum MIDI_Channel_e MIDI_Channel;

enum Octave_Note_e
{
	NOTE_C 	= 0,
	NOTE_CS = 1,
	NOTE_D 	= 2,
	NOTE_DS = 3,
	NOTE_E 	= 4,
	NOTE_F 	= 5,
	NOTE_FS	= 6,
	NOTE_G 	= 7,
	NOTE_GS	= 8,
	NOTE_A 	= 9,
	NOTE_AS	= 10,
	NOTE_B	= 11
};
typedef enum Octave_Note_e Octave_Note;

enum Idle_Screen
{
	IDLE_SCREEN_BLACK,
	IDLE_SCREEN_LOGO,
	IDLE_SCREEN_CURRENT_MODE,
	IDLE_SCREEN_MODE_ACTIVITY
};


//////////////////////////////
// MIDI Messages Definition //
//////////////////////////////
// Upper Byte
#define MIDI_EVENT_NOTE_OFF							0x8		// Note off
#define	MIDI_EVENT_NOTE_ON							0x9		// Note on
#define	MIDI_EVENT_POLYPHONIC_KEY_PRESSURE			0xA		// Polyphonic Key Pressure
#define MIDI_EVENT_CONTROL_CHANGE					0xB		// Control Change
#define MIDI_EVENT_PROGRAM_CHANGE					0xC		// Program Change
#define MIDI_EVENT_CHANNEL_PRESSURE					0xD		// Channel Pressure
#define MIDI_EVENT_PITCH_BEND						0xE		// Pitch Bend Change
#define MIDI_EVENT_SYSTEM							0xF		// System Messages

// Lower Byte in case of System Event
#define MIDI_SYSTEM_EXCLUSIVE						0x0		// System Exclusive Messages
#define MIDI_SYSTEM_TIME_CODE_QUARTER_FRAME			0x1		// MIDI Time Code Quarter Frame
#define MIDI_SYSTEM_SONG_POSITION_POINTER			0x2		// Song Position Pointer
#define MIDI_SYSTEM_SONG_SELECT						0x3		// Song Select
#define MIDI_SYSTEM_UNDEFINED_1						0x4		// Undefined. (Reserved)
#define MIDI_SYSTEM_UNDEFINED_2						0x5		// Undefined. (Reserved)
#define MIDI_SYSTEM_TUNE_REQUEST					0x6		// System Tune Request
#define MIDI_SYSTEM_EXCLUSIVE_END					0x7		// End of Exclusive

#define MIDI_SYSTEM_TIMING_CLOCK					0x8		// Timing Clock
#define MIDI_SYSTEM_UNDEFINED_3						0x9		// Undefined. (Reserved)
#define MIDI_SYSTEM_START							0xA		// Start Sequence
#define MIDI_SYSTEM_CONTINUE						0xB		// Continue Sequence
#define MIDI_SYSTEM_STOP							0xC		// Stop Sequence
#define MIDI_SYSTEM_UNDEFINED_4						0xD		// Undefined. (Reserved)
#define MIDI_SYSTEM_ACTIVE_SENSING					0xE		// Active Sensing (Keep Alive)
#define MIDI_SYSTEM_RESET							0xF		// Reset

// MIDI Control Changes
#define MIDI_CC_ALL_NOTES_OFF                       0x7B    // [Channel Mode Message] All Notes Off


/////////////////////////////////////////
// Helping functions parsing MIDI Data //
/////////////////////////////////////////
#define IS_MIDI_COMMAND(__C__)						((__C__ & 0x80) > 0)
#define IS_MIDI_DATA(__D__)							((__D__ & 0x80) == 0)
#define MIDI_EVENT_FROM_COMMAND(__C__)				((__C__ & 0xF0) >> 4)
#define MIDI_CHANNEL_FROM_COMMAND(__C__)			(__C__ & 0x0F)
#define IS_MIDI_COMMAND_WITH_CHANNEL(__C__)			(MIDI_EVENT_FROM_COMMAND(__C__) >= MIDI_EVENT_NOTE_OFF && MIDI_EVENT_FROM_COMMAND(__C__) <= MIDI_EVENT_PITCH_BEND)


// ============================================================================================
// Function Declarations


#endif /* COMMAND_DEFINITION_H_ */
