#pragma once
#include <stdint.h>

enum RpcNum {
    Get_Info            = 0x0,
    Home                = 0x1,
    Move_Step           = 0x2,
    Move_XY             = 0x3,
    Set_Padding         = 0x4,
    Release_Motors      = 0x5,
    Drop_Stones         = 0x6,
    Get_Stone_Status    = 0x7,
    Mov_Z_Axis          = 0x8,
    Set_Vacum           = 0x9,
    INVALID             = 0xF,
};

struct RPCHeader {
    unsigned char rpc_num : 4;
    unsigned char response : 1;
    unsigned char error : 1;
    unsigned char rpc_segement : 1;
};

struct RPCFrame {
    RPCHeader header;
    uint8_t data[7];
};

enum RPC_Node_Type {
    NODE_ALL        = 0x0,
    NODE_CORE_XY    = 0x1,
    NODE_HEAD       = 0x2,
    NODE_VACUM      = 0x3,
};

// RPC Request and Response structures
struct RPC_RES_Get_Info {
    uint32_t can_address;
    RPC_Node_Type node_type;
    uint32_t status;
    uint32_t error;
};

enum RPC_Home_Corner {
    HOME_CORNER_0 = 0b00,
    HOME_CORNER_1 = 0b01,
    HOME_CORNER_2 = 0b10,
    HOME_CORNER_3 = 0b11,
};

struct RPC_REQ_Home {
    RPC_Home_Corner corner;
};

struct RPC_RES_Home {
    uint32_t x;
    uint32_t y;
};

struct RPC_REQ_Move_Step {
    int32_t x;
    int32_t y;
};

struct RPC_RES_Move_Step {
    uint32_t x;
    uint32_t y;
};

struct RPC_REQ_Set_Padding {
    uint32_t c_1x;
    uint32_t c_1y;
    uint32_t c_2x;
    uint32_t c_2y;
    uint8_t n_x;
    uint8_t n_y;
};

struct RPC_REQ_Move_Z_Axis {
    bool up;
};

struct RPC_REQ_Set_Vacum {
    bool on;
};

// Segment3, Segment2, Segment1, Segment0
const uint8_t SEGMENT_MASK_REQUEST[16] = {
    0b0001, // Get_Info
    0b0001, // Home
    0b0001, // Move_Step
    0b0001, // Move_XY
    0b0111, // Set_Padding
    0b0001, // Release_Motors
    0b0001, // Drop_Stones
    0b0001, // Get_Stone_Status
    0b0001, // Mov_Z_Axis
    0b0001, // Set_Vacum
    0b0001, //
    0b0001, //
    0b0001, //
    0b0001, //
    0b0001, //
};

const uint8_t SEGMENT_MASK_RESPONSE[16] = {
    0b0001, // Get_Info
    0b0001, // Home
    0b0001, // Move_Step
    0b0001, // Move_XY
    0b0001, // Set_Padding
    0b0001, // Release_Motors
    0b0001, // Drop_Stones
    0b0001, // Get_Stone_Status
    0b0001, // Mov_Z_Axis
    0b0001, // Set_Vacum
    0b0001, //
    0b0001, //
    0b0001, //
    0b0001, //
    0b0001, //
};