#pragma once

enum class MESSAGES_ID : unsigned char
{
  SysInfo = 1,
  GyroInfo = 2,
  AccelInfo = 3,
  GpsInfo = 4,
  InertialInfo = 5,
  BatteryInfo = 6,
  Ack = 7,
  StatusCommand = 8,
  StatusAllCommands = 9,
  Command = 10,
  RequestReg = 11,
  ResponseReg = 12,
  Auth = 13,
  OpenKey = 14,
  MissionCount = 15,
  MissionItem = 16,
  MissionItemAck = 17,
  MissionRequestItem = 18,
  RequestLastMessage = 19,
  ConnectionTest = 20,

  CountMenuCategories = 32,
  CategoriesMenu = 33,
  CategoriesParameters = 34,

	//Ping = 200, // :)
	//Pong = 201, // :]
};
enum class COMMANDS_NAME : unsigned char
{
  ChangeNav = 1,
  ChangeSpeed = 2,
  Land = 3,
  GoHome = 4,
  StopEngine = 5,
  StartEngine = 6,
  Pause = 7,
  Continue = 8,
  GoToGlobal = 9,
  GoToLocal = 10,
  
  SetParameter = 15,
};
enum class ERROR_CODE_COMMAND : unsigned char
{
  No_error = 0,
  Speed_has_already_been_set = 1,
  Engines_are_already_running = 2,
  Engines_have_already_been_stopped = 3,
  UAV_is_already_on_the_ground = 4,
  UAV_is_already_landing = 5,
  UAV_is_already_moving = 6,
  Mission_has_not_been_launched = 7,
  Mission_is_already_on_pause = 8,
  Mission_was_not_on_pause = 9,
  Mission_was_not_launched = 10,
  This_NavSys_has_already_been_applied = 11,
  Lost_connection_with_controller = 12,
  The_command_is_canceled_when_a_new_one_is_received = 13,
  Error_reading_the_mission_file = 14,
  Error_validating_the_mission_file = 15
};
enum class ENGINE_STATUS : unsigned char
{
  disable = 0,
  enable = 1
};

enum class STATUS_MODE : unsigned char
{
  on_ground = 1,
  taking_off = 2,
  fly = 3,
  landing = 4
};

enum class SYS_MODE : unsigned char
{
  take_off = 1,
  land = 2,
  go_home = 3,
  auto_mode = 4,
  hold = 5
};

enum class NAV_SYS_MODE : unsigned char
{
  inertial = 1,
  gps = 2,
  Optical_flow = 3
};

enum class EXEC_CODE_COMMAND : unsigned char
{
  error = 0,
  in_progress = 1,
  completed = 2
};

enum class FEASIBILITY_CODE_COMMAND : unsigned char
{
  cannot_be_performed = 0,
  accepted = 1
};

enum class DATA_TYPES : unsigned char
{
  dt_char = 0,
  dt_unsigned_char = 1,
  dt_string = 2,
  dt_short = 3,
  dt_bool = 4,
  dt_unsigned_short = 5,
  dt_int = 6,
  dt_unsigned_int = 7,
  dt_long = 8,
  dt_unsigned_long = 9,
  dt_long_long = 10,
  dt_unsigned_long_long = 11,
  dt_float_32 = 12,
  dt_float_64 = 13,
  dt_unknown = 255
};

#pragma pack(push,1)

const unsigned short MaxLength = 256;
const unsigned char Global_stx = 0xAA;
//Начало заголовка
struct HeaderBegin
{
  unsigned char stx;
  unsigned short len1; //Len header + payload (message) 
  unsigned short len2; //Len header + payload (message)
  unsigned char crc; // CRC MESSAGE
  unsigned char data[0]; // Message
  //---
  bool CheckCRC();
  void SetCRC();
};
// Заголовок сообщения
struct HeaderMessages
{
  MESSAGES_ID msgId;
  unsigned char srcId;
  unsigned char dstId;
  unsigned char len;
  unsigned long long timeusec;
  unsigned char data[0];
};
struct CommandObj
{
	COMMANDS_NAME commandId;
	unsigned char data[0];
};
//Полезная нагрузка сообщения с данными по АКБ
struct PayloadBatteryInfo
{
  unsigned char perCharge;
  float voltage;
  float amperage;
  float temp;
  float totalPower;
  unsigned long long timeRemaining;
};
// Структура с данными по каждому мотору
struct EnginePowerInfo
{
	unsigned char power; //Текущая нагрузка на мотор от 0 до 100%
	unsigned int engineSpeed;//Текущие оборты в секунду мотора
	float current; // Ток потребляемый мотором
	float voltage; // Напряжение на моторе
	float temp; // Температура мотора

};
struct PayloadSysInfo // Полезная нагрузка с данными о остоянии БПЛА
{
	SYS_MODE mode; //Текущий режим полета (взлет - 1, посадка - 2, режим автоматического возврата домой - 3, режим автономного полета - 4, ожидание - 5)
	STATUS_MODE statusMode; //Текущий статус режим (На земле (on ground) - 1, набор высоты (TakingOff) - 2, полет (In air) - 3, приземление (Landing) - 4)
	NAV_SYS_MODE navSys; // Текущая используемая система навигации (GPS\ИНС\Optical Flow) ИНС - 1, GPS - 2, Optical Flow - 3
	ENGINE_STATUS engineStatus; // Текущее состояние моторов. Выкл - 0, Вкл - 1.
	unsigned char engineCount; // Количество двигателей на БПЛА
	float pressureBaro; //Атмосферное давление
	float tempBaro; // Температура Окр. среды
	EnginePowerInfo enginePower[0];
};
struct PayloadGyroInfo // Полезная нагрузка с данными от гироскопа
{
	float yawGyroVel; // Текущая скорость изменения угла рысканья (в чем будет измеряться? рад\с?)
	float pitchGyroVel; // Текущая скорость изменения угла тангажа (в чем будет измеряться? рад\с?)
	float rollGyroVel; // Текущая скорость изменения угла крена  (в чем будет измеряться? рад\с?)
};
struct PayloadAccelInfo // Полезная нагрузка сообщения с данными от акселерометра
{
	float yawAccelVel; // текущее ускорение изменения угла рысканья (Z)
	float pitchAccelVel; // текущее ускорение изменения угла тангажа (Y)
	float rollAccelVel; // текущее ускорение изменения угла крена (X)
	float aX; // ускорение по X (м\с^2)
	float aY; // ускорение по У (м\с^2)
	float aZ; // ускорение по Z (м\с^2)
	float tempAccel; //Температура акселерометра
};
struct PayloadGpsInfo // Полезная нагрузка сообщения с данными от GPS датчика
{
	float lat; //
	float lon; //
	float absAlt; //
	float realAlt; //
	float hdop; //
	float vdop; //
	float pdop; //
	float noise; //
	float jamming; //
	unsigned char satVisible;
	unsigned char satUsed; //
	float speed; // 
	unsigned char fixType; // NO_GPS - 0, NO_FIX - 1, 2D_FIX - 2, 3D_FIX - 3, DGPS - 4, RTK_FLOAT - 5, RTK_FIXED - 6, STATIC - 7, PPP - 8
	unsigned long long timeUTC; // UTC - GPS
};
struct PayloadInertialInfo // Полезная нагрузка с данными от инерциальной системы координат
{
	float x; // Координата X (по локальной системе координат)
	float y; // Координата Y (по локальной системе координат)
	float z; // Координата высоты (по локальной системе координат)
	float headingDeg; // Текущее направление движения БПЛА относительно севера
	float speed; // скорость БПЛА (полученная не по GPS)
	float roll; // текущий угол крена в градусах
	float pitch; // текущий угол тангажа в градусах
	float yaw; // текущий угол рысканья в градусах
	float rollVel; // Скорость по направлению крена м\с (в направлении оси Y)
	float pitchVel; // Скорость по направлению тангажа м\с (в направлении оси Х)
	float yawVel; // Скорость по направлению рысканья м\с (в направлении оси Z)
	float baroAlt; // Высота в метрах по барометру
};
//Полезная нагрузка сообщения с ответом о получении команды
struct PayloadCommandAck
{
	COMMANDS_NAME commandId;
	FEASIBILITY_CODE_COMMAND status; // 0 - не может быть выполнена (указывается код ошибки), 1 - принята
	ERROR_CODE_COMMAND errorCode;
};
struct PayloadStatusCommand
{
	COMMANDS_NAME commandId;
	EXEC_CODE_COMMAND executionCode; // 0 - ошибка при выполнении ,1 - выполняется ,2 - выполнена успешно.
	ERROR_CODE_COMMAND errorCode;
};
// Полезная нагрузка команды для смены скорости полета
struct PayloadCommandChangeSpeed
{
	float speed;
};
// Полезная нагрузка команды для смены текущей исп. нав. системы.
struct PayloadCommandChangeNav
{
	unsigned char nav_id; // Inertial - 1, GPS = 2, Oprical_Flow = 3
};
// Полезная нагрузка команды для перемещения в точку по глобальным координатам
struct PayloadCommandGoToGlobal
{
	float lat;
	float lon;
	float abs_alt;
	float speed;
};
// Полезная нагрузка команды для перемещения в точку по локальным координатам
struct PayloadCommandGoToLocal
{
	float x;
	float y;
	float z;
	float speed;
};

struct PayloadCountMenuCategories
{
	unsigned char countCategories;
	unsigned char data[0];
};

struct MenuCategori
{
	unsigned char id;
	unsigned char len_name;
	unsigned char count_param;
	char name[0];
};

struct PayloadMenuCategories
{
	unsigned char countCategories;
	unsigned char categories[0];
};

struct PayloadCategoriesParameters
{
	unsigned char cat_id;
	unsigned char param_id;
	unsigned char param_name_len;
	unsigned char param_len;
	DATA_TYPES param_type_code;
	char param_data[0];
};

struct PayloadCommandSetParameter
{
	unsigned char cat_id;
	unsigned char param_id;
	DATA_TYPES param_type_code;
	unsigned char param_len;
	char param_data[0];
};

#pragma pack(pop)
