/***************************************************************

   detide module for ADCPSECT;
   2000/02/22 EF
   This is for subtracting a predicted tide from each profile
   before gridding and averaging.

*/
#include "geninc.h"
#include "ioserv.h"
#include "vector.h"
#include "use_db.h"
#include "vstat.h"
#include "ocean.h"
#include "pos_to_m.h"
#include "adcp.h"
#include "adcpsect.h"       /* includes ctd.h */
#include "data_id.h"

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

#define TIDE_BLOCK 1000

#define DDTOL 1e-5

         int   detide = FALSE;
static   FILE_NAME_TYPE  tide_filename;

static struct
{
   int n, n_open, i;
   double *dday;
   float *u, *v;
}  tide;

int init_detide(FILE *fp_cnt)
{
   FILE *fp;
   int finished = 0;
   int count;

   detide = TRUE;
   check_error( (fscanf(fp_cnt," filename: %79s", tide_filename) != 1),
                                 "Can't read detide filename");
   fp = check_fopen(tide_filename, "r");

   tide.n = 0; tide.n_open = 0; tide.i = 0;
   tide.dday = NULL; tide.u = NULL; tide.v = NULL;

   while (!finished)
   {
      if (tide.n_open == 0)
      {
         tide.dday = realloc(tide.dday, (tide.n + TIDE_BLOCK) * sizeof(double));
         tide.u = realloc(tide.u, (tide.n + TIDE_BLOCK) * sizeof(float));
         tide.v = realloc(tide.v, (tide.n + TIDE_BLOCK) * sizeof(float));
         check_error((tide.dday == NULL || tide.u == NULL || tide.v == NULL),
            "Can't allocate memory for tide file\n");
         tide.n_open = TIDE_BLOCK;
      }

      count = fscanf(fp, "%lf %*f %*f %f %f %*f\n", tide.dday + tide.n,
               tide.u + tide.n, tide.v + tide.n);
      /* input in mm/s converted to m/s */
      tide.u[tide.n] /= 1000.0;
      tide.v[tide.n] /= 1000.0;
      if (count == 3)
      {
         tide.n++;
         tide.n_open--;
      }
      else
      {
         finished = 1;
      }
   }
   fclose(fp);
   return(0);
}

void write_detide_params(FILE *fp)
{
   fprintf(fp, "\n Tide file: %s", tide_filename);
   fprintf(fp, "\n    %d lines read", tide.n);
   fprintf(fp, "\n    decimal day range is %f to %f\n",
                     tide.dday[0], tide.dday[tide.n-1]);
}

void subtract_tide(ADCP_PROFILE_TYPE *p)
{
   int i;

   while ( (tide.i < tide.n) &&
            (p->ddtime - DDTOL > tide.dday[tide.i]) )
   {
      tide.i++;
   }

   while ( (tide.i > 0) &&
            (p->ddtime + DDTOL < tide.dday[tide.i]) )
   {
      tide.i--;
   }

   if ( abs(p->ddtime - tide.dday[tide.i]) > DDTOL )
   {
      printf("Warning: no matching tide found for profile at %f\n", p->ddtime);
      return;
   }

   for (i = 0; i < p->nu; i++)
   {
      if (p->u[i] < ADJ_BADFLOAT)
      {
         p->u[i] -= tide.u[tide.i];
         p->v[i] -= tide.v[tide.i];
      }
   }

}

