#ifndef _ENDEC_HPP_
#define _ENDEC_HPP_

#include "can1.h"
#include <functional>

namespace canlib {
// frame structures
namespace frame {
namespace decoded {
namespace can1 {
struct vn200_gnss_ll_t {
	double latitude;
	double longitude;
	double uncertainty_n;
	double uncertainty_e;
vn200_gnss_ll_t() {
	this->latitude = 0.0;
	this->longitude = 0.0;
	this->uncertainty_n = 0.0;
	this->uncertainty_e = 0.0;
}

vn200_gnss_ll_t(
	double latitude,
	double longitude,
	double uncertainty_n,
	double uncertainty_e) {
	this->latitude = latitude;
	this->longitude = longitude;
	this->uncertainty_n = uncertainty_n;
	this->uncertainty_e = uncertainty_e;
}

};
struct vn200_ins_ypr_t {
	double yaw;
	double pitch;
	double roll;
	double uncertainty;
vn200_ins_ypr_t() {
	this->yaw = 0.0;
	this->pitch = 0.0;
	this->roll = 0.0;
	this->uncertainty = 0.0;
}

vn200_ins_ypr_t(
	double yaw,
	double pitch,
	double roll,
	double uncertainty) {
	this->yaw = yaw;
	this->pitch = pitch;
	this->roll = roll;
	this->uncertainty = uncertainty;
}

};
struct vn200_imu_acc_lin_t {
	double acc_lin_x;
	double acc_lin_y;
	double acc_lin_z;
vn200_imu_acc_lin_t() {
	this->acc_lin_x = 0.0;
	this->acc_lin_y = 0.0;
	this->acc_lin_z = 0.0;
}

vn200_imu_acc_lin_t(
	double acc_lin_x,
	double acc_lin_y,
	double acc_lin_z) {
	this->acc_lin_x = acc_lin_x;
	this->acc_lin_y = acc_lin_y;
	this->acc_lin_z = acc_lin_z;
}

};
struct vn200_imu_acc_ang_t {
	double acc_ang_x;
	double acc_ang_y;
	double acc_ang_z;
vn200_imu_acc_ang_t() {
	this->acc_ang_x = 0.0;
	this->acc_ang_y = 0.0;
	this->acc_ang_z = 0.0;
}

vn200_imu_acc_ang_t(
	double acc_ang_x,
	double acc_ang_y,
	double acc_ang_z) {
	this->acc_ang_x = acc_ang_x;
	this->acc_ang_y = acc_ang_y;
	this->acc_ang_z = acc_ang_z;
}

};
struct vn200_ins_ll_t {
	double latitude;
	double longitude;
	double uncertainty_n;
	double uncertainty_e;
vn200_ins_ll_t() {
	this->latitude = 0.0;
	this->longitude = 0.0;
	this->uncertainty_n = 0.0;
	this->uncertainty_e = 0.0;
}

vn200_ins_ll_t(
	double latitude,
	double longitude,
	double uncertainty_n,
	double uncertainty_e) {
	this->latitude = latitude;
	this->longitude = longitude;
	this->uncertainty_n = uncertainty_n;
	this->uncertainty_e = uncertainty_e;
}

};
struct vn200_ins_vel_t {
	double vel_lin_x;
	double vel_lin_y;
	double vel_lin_z;
	double uncertainty;
vn200_ins_vel_t() {
	this->vel_lin_x = 0.0;
	this->vel_lin_y = 0.0;
	this->vel_lin_z = 0.0;
	this->uncertainty = 0.0;
}

vn200_ins_vel_t(
	double vel_lin_x,
	double vel_lin_y,
	double vel_lin_z,
	double uncertainty) {
	this->vel_lin_x = vel_lin_x;
	this->vel_lin_y = vel_lin_y;
	this->vel_lin_z = vel_lin_z;
	this->uncertainty = uncertainty;
}

};

}
}
}
    
// encode functions
namespace encode {
namespace can1 {
inline can1_vn200_gnss_ll_t vn200_gnss_ll(const frame::decoded::can1::vn200_gnss_ll_t frame_decoded) {
    can1_vn200_gnss_ll_t frame_encoded;
	frame_encoded.latitude = can1_vn200_gnss_ll_latitude_encode(frame_decoded.latitude);
	frame_encoded.longitude = can1_vn200_gnss_ll_longitude_encode(frame_decoded.longitude);
	frame_encoded.uncertainty_n = can1_vn200_gnss_ll_uncertainty_n_encode(frame_decoded.uncertainty_n);
	frame_encoded.uncertainty_e = can1_vn200_gnss_ll_uncertainty_e_encode(frame_decoded.uncertainty_e);
    return frame_encoded;
}

inline can1_vn200_ins_ypr_t vn200_ins_ypr(const frame::decoded::can1::vn200_ins_ypr_t frame_decoded) {
    can1_vn200_ins_ypr_t frame_encoded;
	frame_encoded.yaw = can1_vn200_ins_ypr_yaw_encode(frame_decoded.yaw);
	frame_encoded.pitch = can1_vn200_ins_ypr_pitch_encode(frame_decoded.pitch);
	frame_encoded.roll = can1_vn200_ins_ypr_roll_encode(frame_decoded.roll);
	frame_encoded.uncertainty = can1_vn200_ins_ypr_uncertainty_encode(frame_decoded.uncertainty);
    return frame_encoded;
}

inline can1_vn200_imu_acc_lin_t vn200_imu_acc_lin(const frame::decoded::can1::vn200_imu_acc_lin_t frame_decoded) {
    can1_vn200_imu_acc_lin_t frame_encoded;
	frame_encoded.acc_lin_x = can1_vn200_imu_acc_lin_acc_lin_x_encode(frame_decoded.acc_lin_x);
	frame_encoded.acc_lin_y = can1_vn200_imu_acc_lin_acc_lin_y_encode(frame_decoded.acc_lin_y);
	frame_encoded.acc_lin_z = can1_vn200_imu_acc_lin_acc_lin_z_encode(frame_decoded.acc_lin_z);
    return frame_encoded;
}

inline can1_vn200_imu_acc_ang_t vn200_imu_acc_ang(const frame::decoded::can1::vn200_imu_acc_ang_t frame_decoded) {
    can1_vn200_imu_acc_ang_t frame_encoded;
	frame_encoded.acc_ang_x = can1_vn200_imu_acc_ang_acc_ang_x_encode(frame_decoded.acc_ang_x);
	frame_encoded.acc_ang_y = can1_vn200_imu_acc_ang_acc_ang_y_encode(frame_decoded.acc_ang_y);
	frame_encoded.acc_ang_z = can1_vn200_imu_acc_ang_acc_ang_z_encode(frame_decoded.acc_ang_z);
    return frame_encoded;
}

inline can1_vn200_ins_ll_t vn200_ins_ll(const frame::decoded::can1::vn200_ins_ll_t frame_decoded) {
    can1_vn200_ins_ll_t frame_encoded;
	frame_encoded.latitude = can1_vn200_ins_ll_latitude_encode(frame_decoded.latitude);
	frame_encoded.longitude = can1_vn200_ins_ll_longitude_encode(frame_decoded.longitude);
	frame_encoded.uncertainty_n = can1_vn200_ins_ll_uncertainty_n_encode(frame_decoded.uncertainty_n);
	frame_encoded.uncertainty_e = can1_vn200_ins_ll_uncertainty_e_encode(frame_decoded.uncertainty_e);
    return frame_encoded;
}

inline can1_vn200_ins_vel_t vn200_ins_vel(const frame::decoded::can1::vn200_ins_vel_t frame_decoded) {
    can1_vn200_ins_vel_t frame_encoded;
	frame_encoded.vel_lin_x = can1_vn200_ins_vel_vel_lin_x_encode(frame_decoded.vel_lin_x);
	frame_encoded.vel_lin_y = can1_vn200_ins_vel_vel_lin_y_encode(frame_decoded.vel_lin_y);
	frame_encoded.vel_lin_z = can1_vn200_ins_vel_vel_lin_z_encode(frame_decoded.vel_lin_z);
	frame_encoded.uncertainty = can1_vn200_ins_vel_uncertainty_encode(frame_decoded.uncertainty);
    return frame_encoded;
}

}
}
    
// decode functions
namespace decode {
namespace can1 {
inline frame::decoded::can1::vn200_gnss_ll_t vn200_gnss_ll(const can1_vn200_gnss_ll_t frame_encoded) {
    frame::decoded::can1::vn200_gnss_ll_t frame_decoded;
	frame_decoded.latitude = can1_vn200_gnss_ll_latitude_decode(frame_encoded.latitude);
	frame_decoded.longitude = can1_vn200_gnss_ll_longitude_decode(frame_encoded.longitude);
	frame_decoded.uncertainty_n = can1_vn200_gnss_ll_uncertainty_n_decode(frame_encoded.uncertainty_n);
	frame_decoded.uncertainty_e = can1_vn200_gnss_ll_uncertainty_e_decode(frame_encoded.uncertainty_e);
    return frame_decoded;
}

inline frame::decoded::can1::vn200_ins_ypr_t vn200_ins_ypr(const can1_vn200_ins_ypr_t frame_encoded) {
    frame::decoded::can1::vn200_ins_ypr_t frame_decoded;
	frame_decoded.yaw = can1_vn200_ins_ypr_yaw_decode(frame_encoded.yaw);
	frame_decoded.pitch = can1_vn200_ins_ypr_pitch_decode(frame_encoded.pitch);
	frame_decoded.roll = can1_vn200_ins_ypr_roll_decode(frame_encoded.roll);
	frame_decoded.uncertainty = can1_vn200_ins_ypr_uncertainty_decode(frame_encoded.uncertainty);
    return frame_decoded;
}

inline frame::decoded::can1::vn200_imu_acc_lin_t vn200_imu_acc_lin(const can1_vn200_imu_acc_lin_t frame_encoded) {
    frame::decoded::can1::vn200_imu_acc_lin_t frame_decoded;
	frame_decoded.acc_lin_x = can1_vn200_imu_acc_lin_acc_lin_x_decode(frame_encoded.acc_lin_x);
	frame_decoded.acc_lin_y = can1_vn200_imu_acc_lin_acc_lin_y_decode(frame_encoded.acc_lin_y);
	frame_decoded.acc_lin_z = can1_vn200_imu_acc_lin_acc_lin_z_decode(frame_encoded.acc_lin_z);
    return frame_decoded;
}

inline frame::decoded::can1::vn200_imu_acc_ang_t vn200_imu_acc_ang(const can1_vn200_imu_acc_ang_t frame_encoded) {
    frame::decoded::can1::vn200_imu_acc_ang_t frame_decoded;
	frame_decoded.acc_ang_x = can1_vn200_imu_acc_ang_acc_ang_x_decode(frame_encoded.acc_ang_x);
	frame_decoded.acc_ang_y = can1_vn200_imu_acc_ang_acc_ang_y_decode(frame_encoded.acc_ang_y);
	frame_decoded.acc_ang_z = can1_vn200_imu_acc_ang_acc_ang_z_decode(frame_encoded.acc_ang_z);
    return frame_decoded;
}

inline frame::decoded::can1::vn200_ins_ll_t vn200_ins_ll(const can1_vn200_ins_ll_t frame_encoded) {
    frame::decoded::can1::vn200_ins_ll_t frame_decoded;
	frame_decoded.latitude = can1_vn200_ins_ll_latitude_decode(frame_encoded.latitude);
	frame_decoded.longitude = can1_vn200_ins_ll_longitude_decode(frame_encoded.longitude);
	frame_decoded.uncertainty_n = can1_vn200_ins_ll_uncertainty_n_decode(frame_encoded.uncertainty_n);
	frame_decoded.uncertainty_e = can1_vn200_ins_ll_uncertainty_e_decode(frame_encoded.uncertainty_e);
    return frame_decoded;
}

inline frame::decoded::can1::vn200_ins_vel_t vn200_ins_vel(const can1_vn200_ins_vel_t frame_encoded) {
    frame::decoded::can1::vn200_ins_vel_t frame_decoded;
	frame_decoded.vel_lin_x = can1_vn200_ins_vel_vel_lin_x_decode(frame_encoded.vel_lin_x);
	frame_decoded.vel_lin_y = can1_vn200_ins_vel_vel_lin_y_decode(frame_encoded.vel_lin_y);
	frame_decoded.vel_lin_z = can1_vn200_ins_vel_vel_lin_z_decode(frame_encoded.vel_lin_z);
	frame_decoded.uncertainty = can1_vn200_ins_vel_uncertainty_decode(frame_encoded.uncertainty);
    return frame_decoded;
}

}
}
    
// callback structure
namespace callback {
namespace can1 {
	inline std::function<void(can1_vn200_gnss_ll_t, frame::decoded::can1::vn200_gnss_ll_t)> vn200_gnss_ll = NULL;
	inline std::function<void(can1_vn200_ins_ypr_t, frame::decoded::can1::vn200_ins_ypr_t)> vn200_ins_ypr = NULL;
	inline std::function<void(can1_vn200_imu_acc_lin_t, frame::decoded::can1::vn200_imu_acc_lin_t)> vn200_imu_acc_lin = NULL;
	inline std::function<void(can1_vn200_imu_acc_ang_t, frame::decoded::can1::vn200_imu_acc_ang_t)> vn200_imu_acc_ang = NULL;
	inline std::function<void(can1_vn200_ins_ll_t, frame::decoded::can1::vn200_ins_ll_t)> vn200_ins_ll = NULL;
	inline std::function<void(can1_vn200_ins_vel_t, frame::decoded::can1::vn200_ins_vel_t)> vn200_ins_vel = NULL;
}
}
}


#endif // _ENDEC_HPP_

