/*
    ac.h - aircraft trace
    Copyright (C) 2012-2023 Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#include "header.h"

#include "qsodb.h"

#ifndef __AC_H
#define __AC_H

struct band;
struct qso;
struct subwin;
struct qso;
struct zhttp;
struct qrv_item;

enum acs_provider {
	AC_OSN,
	AC_FILE,
	AC_ADSBONE,
	AC_AIRSCATTER_DK
};

struct ac_result{
	int crossing; // next valid only when crossing == 1
    int under;
	double startkx, startky, stopkx, stopky;
	time_t start, stop;
	// for testing
	time_t now;
	double angle; 
};

#define ACZO_LOWALT 0
#define ACZO_NORMAL 1
#define ACZO_CROSSING 2
#define ACZO_CURSOR 3

#define AC_ID_MAXLEN 7
#define AC_ICAOTYPE_MAXLEN 7
#define AC_CALLSIGN_MAXLEN 10 // FAA/NAS limit is 7 characters

struct ac{
	char id[AC_ID_MAXLEN]; // ICAO 24-bit address
	char callsign[AC_CALLSIGN_MAXLEN];
	double w, h; // radians
	double qtfdir; // radians
	int feets;
	int asl; // meters
	int knots;
	int speed; // km/h
	int icon;
	time_t when; 
	
    // state
	int is_computed;
    double kx, ky; // actual position
	double pakx, paky; // predicted path after 10 minutes
	double qtf; // from me
	int flyingdutchman; // data is too old

	struct ac_result tmpres, infores, qrvres; 
	int zorder;
	gchar icaotype[AC_ICAOTYPE_MAXLEN];
	int wingspan; // feets
};

struct acs_shared{
	char *data; // http in main thread -> acs_thread
	char *filename;
	GPtrArray *acs;
	double myh, myw;

    double tmpctpqrb, tmpctpqtf;
    int new_tmpctp;

    double infoctpqrb, infoctpqtf;
    int new_infoctp;

	char tracked[AC_ID_MAXLEN];
	int rotnr;
};

struct acs_thread{
	double myh, myw;
	GPtrArray *acs;
};

struct ac_counterpart{
    double qrb;
    double qtfrad; 
    double minqrb, maxqrb;
    double arm1kx, arm1ky, arm2kx, arm2ky; // middle of area
	double arkx[4], arky[4]; // area visible from both stations
	int path_valid;
    
};

struct acs{
	// only main thread
//	struct subwin *sw;
    int normal, active;
	GThread *thread;
	struct qso infolocqso;
    time_t validity;

	int osn_http_timer;
	struct zhttp *osn_http;
	int osn_requests_remaining;
	char* osn_http_error;

	int adsbone_http_timer;
	struct zhttp* adsbone_http;
	char* adsbone_http_error;

	int airdk_http_timer;
	struct zhttp* airdk_http;
	char* airdk_http_error;


#ifdef Z_HAVE_SDL
	void (*plot_info)(struct subwin* sw, SDL_Rect* area, struct acs* acs);
#endif

	// shared without lock
	int thread_break;
	int dead_minutes;

    struct ac_counterpart tmpqso;// TODO -> th
    struct ac_counterpart infoqso;// TODO -> th
    struct ac_counterpart qrvqso;// TODO -> th
	
	// shared
	struct acs_shared sh;
	MUTEX_DEFINE(sh);

	// only thread
	struct acs_thread th;
	GPtrArray *infos; // of ac_info
	void (*load_from_main_thread)(struct acs* acs, const char* data);
	void (*load_from_thread)(struct acs* acs);
	GHashTable* unknownids;
	MUTEX_DEFINE(unknownids);
};

struct ac_info{
	gchar icaotype[AC_ICAOTYPE_MAXLEN];
	int wingspan;
};

extern struct acs *gacs;

struct acs *init_acs(void);
void free_acs(struct acs *acs);
void ac_compute(struct acs *acs, struct ac *ac, struct ac_counterpart *ctp, struct ac_result *res); // called in thread
#ifdef Z_HAVE_SDL
void plot_path(struct subwin *sw, SDL_Surface *surface, struct band *band, struct qso *qso, struct ac_counterpart *ctp);
void plot_ac(struct subwin *sw, struct ac *ac);
void plot_info_ac(struct subwin *sw, SDL_Surface *surface, struct ac *ac);

void acs_redraw(struct subwin *sw, struct acs *acs);
#endif
void ac_redraw(void);

double acs_min_asl(struct acs *acs, double qrb, struct band *b, double elev_rad);
double acs_max_qrb(struct acs *acs, double asl, struct band *b, double elev_rad);
//void acs_goturl(struct zhttp *http);
gpointer acs_thread(gpointer arg);
void acs_update_qth(struct acs *acs);
void ac_update_tmpctp(char *wwl);
void ac_update_infoctp(char *wwl);
void ac_format(struct qrv_item *qi, char *acstart, char *acint, int flags);

void init_acs_infos(struct acs *acs);
void free_acs_infos(struct acs *acs);
//int acs_get_wingspan(struct acs *acs, char *icao);
void ac_fill_wingspan(struct acs* acs, struct ac* ac);

struct ac *ac_under(struct acs *acs, struct subwin *sw);
void ac_track(struct acs *acs, char *id, int rotnr);

//openskynetwork
int acs_osn_init(struct acs* acs);
void acs_osn_free(struct acs* acs);
void acs_osn_http_timer(void *arg);
void acs_osn_downloaded_callback(struct zhttp *http);
void acs_osn_load_from_main_thread(struct acs* acs, const char* data);
#ifdef Z_HAVE_SDL
void acs_osn_plot_info(struct subwin* sw, SDL_Rect* area, struct acs* acs);
#endif

//file
int acs_file_init(struct acs* acs);
void acs_file_free(struct acs* acs);
void acs_file_read_feed(struct acs* acs);

//adsb.one
int acs_adsbone_init(struct acs* acs);
void acs_adsbone_free(struct acs* acs);
void acs_adsbone_http_timer(void* arg);
void acs_adsbone_downloaded_callback(struct zhttp* http);
void acs_adsbone_load_from_main_thread(struct acs* acs, const char* data);
#ifdef Z_HAVE_SDL
void acs_adsbone_plot_info(struct subwin* sw, SDL_Rect* area, struct acs* acs);
#endif

//airscatter.dk
int acs_airdk_init(struct acs* acs);
void acs_airdk_free(struct acs* acs);
void acs_airdk_http_timer(void* arg);
void acs_airdk_downloaded_callback(struct zhttp* http);
void acs_airdk_load_from_main_thread(struct acs* acs, const char* data);
#ifdef Z_HAVE_SDL
void acs_airdk_plot_info(struct subwin* sw, SDL_Rect* area, struct acs* acs);
#endif


#endif
