#ifndef RADAR_4G_H
#define RADAR_4G_H

#include <stdio.h>
#include <stdint.h>

#define SPOKES (4096)
#define SPOKELEN (1024)
#define DEGREES_PER_ROTATION (360)  // Classical math
#define SCALE_RAW_TO_DEGREES(raw) ((raw) * (double)DEGREES_PER_ROTATION / SPOKES)
#define SCALE_DEGREES_TO_RAW(angle) ((int)((angle) * (double)SPOKES / DEGREES_PER_ROTATION))

#define CH_UNKNOWN 0
#define CH_A_DATA 1
#define CH_B_DATA 2
#define CH_A_REPORT 3
#define CH_B_REPORT 4

#define CH_A_DATA_SRC_PORT 6678
#define CH_B_DATA_SRC_PORT 6657
#define CH_A_DATA_DEST_IP 0x080706EC //236.6.7.8 in network byte order
#define CH_B_DATA_DEST_IP 0x0D0706EC //236.6.7.13 in network byte order

#define CH_A_REPORT_SRC_PORT 6679
#define CH_B_REPORT_SRC_PORT 6659
#define CH_A_REPORT_DEST_IP 0x090706EC //236.6.7.9 in network byte order
#define CH_B_REPORT_DEST_IP 0x0F0706EC //236.6.7.15 in network byte order

#define SCANS_PER_FRAME 32

struct br4g_header {
  uint8_t headerLen;       // 1 bytes
  uint8_t status;          // 1 bytes
  uint16_t scan_number;  // 2 bytes, 0-4095
  uint8_t u00[2];          // Always 0x4400 (integer)
  uint8_t largerange[2];   // 2 bytes or -1
  uint8_t angle[2];        // 2 bytes
  uint8_t heading[2];      // 2 bytes heading with RI-10/11 or -1. See bitmask explanation above.
  uint8_t smallrange[2];   // 2 bytes or -1
  uint8_t rotation[2];     // 2 bytes, rotation/angle
  uint8_t u02[4];          // 4 bytes signed integer, always -1
  uint8_t u03[4];          // 4 bytes signed integer, mostly -1 (0x80 in last byte) or 0xa0 in last byte
};                         /* total size = 24 */

struct radar_line {
  struct br4g_header br4g;
  uint8_t data[SPOKELEN / 2];
};

struct radar_frame_pkt {
  uint8_t frame_hdr[8];
  struct radar_line lines[SCANS_PER_FRAME];
};

//snippet from OpenCPN Project: 
struct __attribute__((__packed__)) RadarReport_02C4_99 {       // length 99
  uint8_t what;                    // 0   0x02
  uint8_t command;                 // 1 0xC4
  uint32_t range;                  //  2-3   0x06 0x09
  uint16_t field4;                 // 6-7    0
  uint32_t field8;                 // 8-11   1
  uint8_t gain;                    // 12
  uint8_t sea_auto;                // 13  0 = off, 1 = harbour, 2 = offshore
  uint8_t field14;                 // 14
  uint16_t field15;                // 15-16
  uint32_t sea;                    // 17-20   sea state (17)
  uint8_t field21;                 // 21
  uint8_t rain;                    // 22   rain clutter
  uint8_t field23;                 // 23
  uint32_t field24;                // 24-27
  uint32_t field28;                // 28-31
  uint8_t field32;                 // 32
  uint8_t field33;                 // 33
  uint8_t interference_rejection;  // 34
  uint8_t field35;                 // 35
  uint8_t field36;                 // 36
  uint8_t field37;                 // 37
  uint8_t target_expansion;        // 38
  uint8_t field39;                 // 39
  uint8_t field40;                 // 40
  uint8_t field41;                 // 41
  uint8_t target_boost;            // 42
};
typedef struct RadarReport_02C4_99 RadarReport_02C4_99_t;

int line_range(struct radar_line *);
int line_angle(struct radar_line *);
short int line_heading(struct radar_line *);
int line_angle(struct radar_line * );
double line_angle_degrees(struct radar_line *);
#endif