#ifndef _VN200_
#define _VN200_

#include <map>
#include <stdint.h>
#include <vector>

#define VN_SPI_READ 0x01
#define VN_SPI_WRITE 0x02

#define VN_ID_IMU_MEASUREMENT_REGISTER 54

namespace vn {

const uint8_t ImuMeasurementsRegisterID = 54;

/* TODO */
union header_t {
  struct request_t {
    uint8_t Cmd = 0;    /* Defined in VN200_SPI_READ - set in standard constructor */
    uint8_t ID = 0;     /* Register ID */
    uint16_t Empty = 0; /* Spacer */
    request_t(uint8_t ID, uint8_t Cmd) {
      this->ID = ID;
      this->Cmd = Cmd;
    };
  };
  struct response_t {
    uint8_t Empty1 = 0; /* Spacer */
    uint8_t Cmd = 0;    /* Defined in VN200_SPI_READ - set in standard constructor */
    uint8_t ID = 0;     /* Register ID */
    uint8_t Empty2 = 0; /* Spacer */
    response_t(){};
    response_t(uint8_t ID, uint8_t Cmd) {
      this->ID = ID;
      this->Cmd = Cmd;
    };
  };
};

/* Writes the desired payload into the specified register */
template <typename payload_t> struct pkg_request_write_t {
  struct header_t::request_t header;
  payload_t payload;
  /* TODO */
  pkg_request_write_t(uint8_t ID) : header(ID, VN_SPI_WRITE){};
};

/* Writes the desired payload into the specified register */
struct pkg_request_read_t {
  struct header_t::request_t header;
  /* TODO */
  pkg_request_read_t(uint8_t ID) : header(ID, VN_SPI_READ){};
};

/* Writes the desired payload into the specified register */
template <typename payload_t> struct pkg_response_t {
  struct header_t::response_t header;
  payload_t payload;
  /* TODO */
  pkg_response_t() : header(){};
};

// namespace IMU {
// const uint8_t ID = 54;
// struct imu_t {
//   float MagX = 0.0;
//   float MagY = 0.0;
//   float MagZ = 0.0;
//   float AccelX = 0.0;
//   float AccelY = 0.0;
//   float AccelZ = 0.0;
//   float GyroX = 0.0;
//   float GyroY = 0.0;
//   float GyroZ = 0.0;
//   float Pressure = 0.0;
// };
// } // namespace IMU
// namespace ATT {
// const uint8_t ID = 239;
// struct attitude_t {
//   float Yaw = 0.0;
//   float Pitch = 0.0;
//   float Roll = 0.0;
//   float BodyAccelX = 0.0;
//   float BodyAccelY = 0.0;
//   float BodyAccelZ = 0.0;
//   float GyroX = 0.0;
//   float GyroY = 0.0;
//   float GyroZ = 0.0;
// };
// } // namespace ATT
// namespace INS {
// namespace LLA {
// const uint8_t ID = 63;
// struct lla_t {
//   float Yaw = 0.0;
//   float Pitch = 0.0;
//   float Roll = 0.0;
//   double Lattitude = 0.0;
//   double Longitude = 0.0;
//   double Altitude = 0.0;
//   float VelocityX = 0.0;
//   float VelocityY = 0.0;
//   float VelocityZ = 0.0;
//   float AccelX = 0.0;
//   float AccelY = 0.0;
//   float AccelZ = 0.0;
//   float AngularRateX = 0.0;
//   float AngularRateY = 0.0;
//   float AngularRateZ = 0.0;
// };
// } // namespace LLA
// } // namespace INS
// namespace GPS {
// namespace LLA {
// const uint8_t ID = 58;
// struct lla_t {
//   double Time = 0.0;
//   uint16_t Week = 0;
//   uint8_t GpsFix = 0;
//   uint8_t NumSats = 0;
//   uint32_t PADDING = 0;
//   double Latitude = 0.0;
//   double Longitude = 0.0;
//   double Altitude = 0.0;
//   float NedVelX = 0.0;
//   float NedVelY = 0.0;
//   float NedVelZ = 0.0;
//   float NorthAcc = 0.0;
//   float EastAcc = 0.0;
//   float VertAcc = 0.0;
//   float SpeedAcc = 0.0;
//   float TimeAcc = 0.0;
// };
// } // namespace LLA
// } // namespace GPS
} // namespace vn

#endif
