#include "dbhost.h"  /* PROTOTYPE_ALLOWED */
#include "matfile.h" /* MAT_ARRAY_FP_TYPE */
#include "ctd.h"
#define MPS_PER_KT 0.51479


#define TRUE  1
#define FALSE 0
#define sqr(x)  (x)*(x)
#define good_float(x)  ( (x) < ADJ_BADFLOAT )

#define NDMAX 129     /* max number of depths for most ADCP data */
#define NDMAX_NG 200  /* max number of elements in new grid */

#define ADCP_DB 1
#define CTD_DB  2

/* The following are used to index the position statistics arrays;
   they must not be changed.
*/
#define LONGITUDE 0
#define LATITUDE 1
#define DDTIME   2

typedef struct
{
   YMDHMS_TIME_TYPE time;             /* current profile time */
   DOUBLE_LL_TYPE position;   /* by arranging position followed by */
   double ddtime;             /* time, we have an array of lon, lat, time */
   float depth[NDMAX];
   float u[NDMAX];
   float v[NDMAX];
   BYTE  percent_good[NDMAX];
   UBYTE amp[NDMAX];
   UBYTE profile_flags[NDMAX];  /* jr+ */
   int nd,
       nu,
       npg,
       namp;
    ANCILLARY_1_TYPE ancillary_1;
    ANCILLARY_2_TYPE ancillary_2;
    ACCESS_VARIABLES_TYPE access;
} ADCP_PROFILE_TYPE;

typedef struct {
   int method;
   int bin_range[2];
} PROFILE_REF_TYPE;

typedef struct
{
   double lon, lat;
   YMDHMS_TIME_TYPE time;
   int good;
} FIX_TYPE;

typedef struct
{
   float *array;
   float *center_array;
   int ca_allocated;     /* flag: set to 1 if center_array has been
                            dynamically allocated by set_vgrid */
   int increase_down;
   char label[14];
   int precision;
} VERTICAL_GRID_TYPE;

#define   RM_CENTERED_AV  0     /* for interpolation using regrid */
#define   RM_INTEGRATE    1     /* for depth-integral */
#define   RM_AVERAGE      2     /* for depth-average */
#define   RM_TRANSDERIV   3   /* for depth-integral divided by grid increment*/
#define   RM_INTERPOLATE  4   /* for simple linear interpolation */
#define   RM_INTEGRATE_TOP 5  /* for depth integral, with the first
                                 interval starting at the surface. */


/* Regrid variables; these are used for array indexing, so they
   must be numbered consecutively from zero.  An enumerated type
   might be better here. */
#define   RV_NONE        0
#define   RV_DEPTH       1
#define   RV_SVAN        2
#define   RV_POT_SVAN    3
#define   RV_SIGMA_THETA 4
#define   RV_SIGMA_T     5

/*--> variables related to referencing and/or absolute calculations */

/* The following are set up as bit flags so that they can
   be used in a single flag integer to specify that several
   types of ship velocity calculation are to be done, although
   this is not done in ADCPSECT.
*/
#define REF_NONE           0
#define REF_FINAL_SHIP     1
#define REF_NAV_POS        2
#define REF_NAV_VEL        4
#define REF_BOTTOM_TRACK   8
#define REF_DIR_POS        16
#define REF_BINS           32

/* contour position sources: (latitude or longitude) */
#define  CONPS_MIDDLE 0     /* middle of ADCP range */
#define  CONPS_MEAN   1     /* mean of ADCP range */
#define  CONPS_CTD    2

#if PROTOTYPE_ALLOWED
int index_bad_tracking(ADCP_PROFILE_TYPE *p, int agc_limit, double bad_dif);
void initialize_ensemble(void);
void increment_ensemble(void);
void calculate_ensemble(void);
void print_ensemble(void);
void end_ensemble(void);
void print_header(FILE *fp);
int speed_in_range(ADCP_PROFILE_TYPE *p, double ship_u, double ship_v);
void select_good_velocity(ADCP_PROFILE_TYPE *p);
int init_mask(FILE *fp_cnt);

/* VGRID.C */
int init_regrid(FILE *fp_cnt);
void set_vgrid(int ndepth);
void regrid_velocity(ADCP_PROFILE_TYPE *adcp, CTD_PROFILE_TYPE *ctd);
void write_vgrid_params(FILE *fp);
void close_vgrid(void);

/***************************************************************
   FLUX.C
*/
int init_transport(FILE *fp_cnt);
void allocate_transport(int adj_nu);
void calculate_transport(UNISTAT_TYPE *u_stat,
                         UNISTAT_TYPE *v_stat,
                         UNISTAT_TYPE *adcp_pos_stat);
void print_transport(UNISTAT_TYPE *adcp_pos_stat, float *y, char *label,
                                                      int n_zdigits);
void close_transport(void);
void integrate_ds(double *last_ptr, double *now_ptr, int adj_nu,
   double distance, double *inc_ptr, int sign);
void write_transport(FILE *fpt, UNISTAT_TYPE *u, UNISTAT_TYPE *v, double scale,
   float *d, char *d_name, int  nd_prec);
void write_tran_mat(MAT_ARRAY_FP_TYPE *mat_ptr, double *u, double *v, int n);

/***************************************************************
   SEQCOR.C
*/
int init_seqcor(FILE *fp_cnt);
void calc_seqcor(float *adj_u, float *adj_v, int adj_nu, double ddtime);
void close_seqcor(void);
int inner_correlation(float *u0, float *v0, float *u1, float *v1,
                        int n, double *amp, double *phase);
void sequential_correlation(FILE *fp_seqcor, float *u, float *v, double time,
   int n);

/***************************************************************
   SHIPREF.C
*/
int init_ref(FILE *fp_cnt);
int init_nav(FILE *fp_cnt);
int read_bin_range(FILE *fp, char *refc, int code);
void get_ship_velocity(ADCP_PROFILE_TYPE *p, PROFILE_REF_TYPE *ref,
                     FIX_TYPE *last_fix,
                     double *ship_u_ptr, double *ship_v_ptr);
void write_navigation(ADCP_PROFILE_TYPE *p, PROFILE_REF_TYPE *nav);
void close_navigation(void);
/***************************************************************
   CONFILE.C
*/
int init_contour(FILE *fp_cnt);
void write_confile(UNISTAT_TYPE *u_stat, UNISTAT_TYPE *v_stat,
                           float *y, int minus);
void close_contour(void);


/***************************************************************
   DETIDE.C
*/
int init_detide(FILE *fp_cnt);
void subtract_tide(ADCP_PROFILE_TYPE *p);
void write_detide_params(FILE *fp);


#else
int index_bad_tracking();
void increment_ensemble();
void calculate_ensemble();
void print_ensemble();
void print_header();
int speed_in_range();
void select_good_velocity();
int init_mask();

/* VGRID.C */
int init_regrid();
void set_vgrid();
void regrid_velocity();
void write_vgrid_params();
void close_vgrid();

/***************************************************************
   FLUX.C
*/
int init_transport();
void allocate_transport();
void calculate_transport();
void print_transport();
void close_transport();
void integrate_ds();
void write_transport();
void write_tran_mat();

/***************************************************************
   SEQCOR.C
*/
int init_seqcor();
void calc_seqcor();
void close_seqcor();
int inner_correlation();
void sequential_correlation();

/***************************************************************
   SHIPREF.C
*/
int init_ref();
int init_nav();
int read_bin_range();
void get_ship_velocity();
void write_navigation();
void close_navigation();
/***************************************************************
   CONFILE.C
*/
int init_contour();
void write_confile();
void close_contour();
#endif
