
// Table 3-1, Information query commands
// Default data needs to be set to "none": `0x00`
enum InfoCommands
{
    // Note on time:
    // 0x20170101 indicates the time is January 1, 2017.

    // Returns 5 bytes - Convert to ascii
    Model,
    // Returns 3 bytes - 0x011420 means v1.14.20
    FPGA_Ver,
    // Returns 4 bytes - Big endian time
    FPGA_Comp_Time,
    // Returns 3 bytes - 0x010410 means v1.4.10
    Module_Software_Ver,
    // Returns 4 bytes - Big endian time
    Module_Software_Comp_Time,
    // Returns 4 bytes - Big endian time
    Camera_Calibration_Ver_Time,
    // Returns 4 bytes
    ISP_Parameter_Ver,
    // Returns 1 byte - Loading: `0x00`, or Streaming: `0x01`
    Init_State, 
};

// Table 3-2, Function setting commands
enum FuncCommands
{
    // TODO write only?
    // Data none?
    Manual_Shutter_Calibration,
    // TODO write only?
    // Data none?
    Manual_Background_Correction,
    // @brief Set shutter control. Data:
    //
    // `0x00` Automatic control off
    //
    // `0x01` Automatic switching, timing control
    //
    // `0x02` Automatic switching, temperature difference control
    //
    // `0x03` (Default) Full-automatic control
    Automatic_Shutter_Control,
    // Setting the shutter interval in minutes, 2 bytes.
    // Default, 10min: `0x00 0x0A` "Not recommended for users to modify"
    Automatic_Shutter_Switching_Interval,
    // TODO
    Vignetting_Correction,
    // 1 byte, default: `0x32` (50), range: 0~100.
    Brightness,
    // 1 byte, default: `0x32` (50), range: 0~100.
    Contrast,
    // 1 byte, default: `0x32` (50), range: 0~100.
    Digital_Enhancement,
    // 1 byte, default: `0x32` (50), range: 0~100.
    Static_De_Noising,
    // 1 byte, default: `0x32` (50), range: 0~100.
    Dynamic_De_Noising,
    // `0x00`: Turn off the cursor display
    //
    // `0x0F`: Turn on the cursor display
    //
    // `0x02`: Cursor up
    //
    // `0x03`: Cursor down
    //
    // `0x04`: Cursor shifted left
    //
    // `0x05`: Cursor shifted right
    //
    // `0x06`: Cursor to the center
    //
    // `0x0D`: Add the pixel to the defective pixel table.
    //
    // `0x0E`: Remove the pixel from the defective pixel table.
    //
    // `0x2N`: Cursor up for N pixels (N: 0x1~0xF)
    //
    // `0x3N`: Cursor down for N pixels (N: 0x1~0xF)
    //
    // `0x4N`: Cursor shifted left for N pixels (N: 0x1~0xF)
    //
    // `0x5N`: Cursor shifted right for N pixels (N: 0x1~0xF)
    Defective_Pixel_Correction,
    // `0x00`: White Hot (Default)
    //
    // `0x01`: Black Hot
    //
    // `0x02`: Fusion 1
    //
    // `0x03`: Rainbow
    //
    // `0x04`: Fusion 2
    //
    // `0x05`: Iron Red 1
    //
    // `0x06`: Iron Red 2
    //
    // `0x07`: Dark Brown
    //
    // `0x08`: Color 1
    //
    // `0x09`: Color 2
    //
    // `0x0A`: Ice Fire
    //
    // `0x0B`: Rain
    //
    // `0x0C`: Green Hot
    //
    // `0x0D`: Red Hot
    //
    // `0x0E`: Deep Blue
    Palette_Setting,
    // Send `0x00` as data (default)(none)
    Factory_Reset,
    // Send `0x00` as data (default)(none)
    Save_Settings,
    // `0x00`: No mirroring.
    //
    // `0x01`: Central mirroring.
    //
    // `0x02`: Left and right mirroring.
    //
    // `0x03`: Up and down mirroring.
    Mirroring,
};

class Addr
{

public:
    uint8_t device_address, class_address, subclass_address, rw_flag;

    explicit Addr(FuncCommands cmd);
    explicit Addr(InfoCommands cmd);
};

/// @brief Sets up command to send to camera.
/// @param cmd Addr object of the command you want to send.
/// @param data_in Any data that should go along with it. If there is no data then send [0x00]
/// @param data_len Length of data array.
/// @param buffer Buffer to output into. This should be 8 larger than the data array.
void command(Addr cmd, uint8_t data_in[], int data_len, uint8_t buffer[]);
