#ifndef GPS_APP_H
#define GPS_APP_H

#include <time.h>
#include <stdbool.h>
#include "exo_types.h"
#include "oem7_gps.h"

#define GPS_SCS 0
#define GPS_FAIL 1

#define  GPS_MIN_NTFY_PRDCTY 1
#define  GPS_MIN_SYNC_TIME_PRDCTY 1*60 //Minutes for 1 hours


typedef struct
{
    uint32_t time;    //time status of the position in epoch
    bool valid;
    float latitude;
    float longitude;
    float altitude;   //Antenna altitude above/below mean sealevel in meters
    float height;   //the relationship between the geoid and the WGS84 ellipsoid in meters
    float speed;    //The speed of the GPS receiver over the ground, measured in knots.
    int satellites_tracked;

}__attribute__((__packed__)) gps_loc_info;

typedef struct
{
    uint32_t time;    //in epoch
    double position_x;
    double position_y;
    double position_z;
    double velocity_x;
    double velocity_y;
    double velocity_z;

}__attribute__((__packed__)) gps_tle_data;



typedef struct orbit_s {
    /*Add the epoch time if required. */
    uint16_t ep_year; /* Year of epoch, e.g. 94 for 1994, 100 for 2000AD */
    double ep_day; /*Day of epoch from 00:00 Jan 1st ( = 1.0 ) */
    double rev; /*Mean motion, revolutions per day */
    double bstar; /*Drag term */
    double eqinc; /*Equatorial inclination, radians */
    double ecc; /*Eccentricity */
    double mnan; /*Mean anomaly at epoch from elements, radians */
    double argp; /*Argument of perigee, radians */
    double ascn; /*Right ascension (ascending node), radians */
    double smjaxs; /*Semi-major axis, km */
    uint32_t norb; /*Orbit number, for elements */
    uint16_t satno; /*Satellite number */
}__attribute__((__packed__)) orbit_tle_t;


void gps_time_sync_tmr_cb(void* args);
void gps_tle_ntfy_tmr_cb(void* args);
void gps_loc_ntfy_tmr_cb(void* args);
void gps_hdlr_thread(void* args);
void gps_init(void);
void gps_set_loc_ntfy_prdcty(uint16_t prdcty);
void gps_set_tle_data_ntfy_prdcty(uint16_t prdcty);
uint8_t gps_get_location_info(gps_loc_info* gps_loc);
uint8_t gps_get_cartesian_pos_velcty(gps_tle_data* gps_tle);
uint8_t gps_compute_orbital_elements(orbit_tle_t* orbital_info);
time_t gps_get_time_epoch();

/**
 * @brief This function sync the gps time to RTC time
 *
 * @param[in] recv_epoch : pointer to GPS time in epoch
 * @param[in] timer_flag : periodical timer call(0) or
 * force to update(1)
 *
 * @return status of sync time
 * @retval SYNC_SUCCESS - 0, SYNC_FAIL - 1
 */
uint8_t gps_sync_time(uint8_t* recv_epoch, uint8_t timer_flag);

/**
 * @brief This function NVM write the sync timer periodicity in minutes
 *
 * @param[in] prdcty : Timer periodicity
 *
 * @return void
 */
void gps_set_sync_time_prdcty(uint32_t prdcty);

/**
 * @brief This function read the sync timer periodicity in NVM
 *
 * @param[in] void
 *
 * @return Timer periodicity of Sync time
 * @retval Timer periodicity
 */
uint32_t gps_get_sync_time_prdcty(void);
uint8_t gps_get_time_date(gps_time_data* loc_data);

time_t convert_to_epoch_time(gps_time_data *gps_data);

#endif
