/*  Tue  08-01-1989  fb:
    The maximum number of segments NSEGMENT is as large as it can
    be for a small memory model.   */

#include "dbhost.h"  /* PROTOTYPE_ALLOWED */

#define TRUE  1
#define FALSE 0

#define NSEGMENTS 200 /* increment for allocation of memory for segment
			 table */
#define NFMAX 500 /* max number of fix intervals within window width */


#define s_per_day 86400L
#define min_per_day 1440
#ifndef sqr
#define sqr(x) ((x)*(x))
#endif

#define GOOD_REFABS TRUE    /* select good ones in read_refabs */
#define ALL_REFABS  FALSE    /* no discrimination */

#define PDEBUG 0

#if PDEBUG
#define pdebug1(s,f,a) if(s) printf(f,a)
#define pdebug2(s,f,a,b) if(s) printf(f,a,b)
#define pdebug3(s,f,a,b,c) if(s) printf(f,a,b,c)
#define pdebug4(s,f,a,b,c,d) if(s) printf(f,a,b,c,d)
#else
#define pdebug1(s,f,a)
#define pdebug2(s,f,a,b)
#define pdebug3(s,f,a,b,c)
#define pdebug4(s,f,a,b,c,d)
#endif

typedef struct
{
   double t, x, y, u, v, dt, gap_u, gap_v, gap_t;
}  REFABS_TYPE;
      /*  t and dt are in decimal days; gap_t is in minutes */

typedef FIX_TYPE POSITION_TYPE;

typedef struct
{
   double t, ru, rv, su, sv, x, y, ff;
} SMOOTHR_OUT_TYPE;

typedef struct
{
   long i0, n;  /* start index, number  of sm records in range */
   double t0, t1,  /* start, end times */
          x0, x1,  /* start, end longitude */
          y0, y1,  /* start, end latitude  */
          ex0, ey0,
          dx, dy,  /* offsets from fixes in segment */
          stdx, stdy;  /* standard deviations of fixes from track */
   int nfix;       /* number of fixes within the segment */
} TRACK_SEGMENT_TYPE;

#if PROTOTYPE_ALLOWED
/* optpos.c */
int is_gap(SMOOTHR_OUT_TYPE *sm, SMOOTHR_OUT_TYPE *prev_sm);
int find_segments(FILE *fp_sm);
void print_segment_tables(FILE *fp_log, TRACK_SEGMENT_TYPE *segment, int nseg);
void adjust_nofix_segments(TRACK_SEGMENT_TYPE *segment, int nseg);
void integrate_segment(FILE *fp_sm, TRACK_SEGMENT_TYPE *segment);
void optimize_positions(FILE *fp_sm, FILE *fp_fix, FILE *fp_log,
                              double fix_to_dr_limit, int iterations);

/* smoothr.c */
void make_bad_record(SMOOTHR_OUT_TYPE *r, VELOCITY_TYPE *s);
void make_record(SMOOTHR_OUT_TYPE *r, VELOCITY_TYPE *ref, VELOCITY_TYPE *ship,
                 POSITION_TYPE *pos, double fraction);
int read_shipref(FILE *fp, VELOCITY_TYPE *ref);
int read_refabs(FILE *fp, REFABS_TYPE *r, int good_only);
int get_refabs(FILE *fp, double *t0, double *t1);
double integrate_filter(double t0, double t1);
int good_ref(REFABS_TYPE *r);
int filter_refabs(double t, double t0, double t1,
                     REFABS_TYPE *r, VELOCITY_TYPE *vel, double *filt_fract);
void do_it(FILE *fp_cnt);

#else

/* optpos.c */
int is_gap();
int find_segments();
void print_segment_tables();
void adjust_nofix_segments();
void integrate_segment();
void optimize_positions();

/* smoothr.c */
void make_bad_record();
void make_record();
int read_shipref();
int read_refabs();
int get_refabs();
double integrate_filter();
int good_ref();
int filter_refabs();
void do_it();

#endif
