/******************************************************************************
*
    PROGRAM:  badbin.c
    USAGE:    badbin < dbname > < infile >

       This program is used to flag individual bins within a profile.

       The infile should contain the time (yy/mm/dd hh:mm:ss),
       block number, and profile number of the profiles containing bad bins,
       followed by the number of bins to be flagged, and the actual
       bin numbers to flag.  It then searches the database specified
       by < dbname > for those profiles.  If the PROFILE_FLAGS variable
       has been loaded, it performs the flagging by turning on the
       appropriate bit (GLITCH_BIT) in the PROFILE_FLAGS.  It also
       turns on bit 7 (GLITCHES_REMOVED) of the data processing mask.
       If the PROFILE_FLAGS variable is not available, the program
       actually changes the U, V, W, and E velocity values at those bins
       to BADSHORT (i.e., the original values are lost).  All databases
       loaded with loadping version dated 11/05/90 and later should
       have the PROFILE_FLAGS variable in the database.

       J. Ranada - 03/15/88 - University of Hawaii JIMAR

       9/22/89 - JR - modified to also reset error velocity to BAD,
                      if present

       8/16/90 - JR - modified to use PROFILE_FLAGS if available

       2000/09/20 - EF - removed get_time() function; the new one in
                   use_db/time_io.c can be used instead.
                                                                              *
******************************************************************************/

#include "geninc.h"
#define MAX_NBINS 128

#include "data_id.h"    /* U, V, W definitions */
#include "ioserv.h"     /* check_fopen(), error_found(), report_msg() */
#include "use_db.h"     /* db*_cnf(), set_db_dpmask() */
#include "dpmask.h"     /* GLITCHES_REMOVED */
#include "adcpflag.h"   /* GLITCH_BIT */

#define dbname argv[1]
#define ascname argv[2]

#if PROTOTYPE_ALLOWED
int main(int argc, char *argv[])
#else
int main(argc, argv)
int argc;
char *argv[];
#endif
{
   unsigned int n, n_ev, npf;
   int badcount, badbin, i, ierr, use_profile_flags;
   SHORT u_vel[MAX_NBINS], v_vel[MAX_NBINS], w_vel[MAX_NBINS], e_vel[MAX_NBINS];
   UBYTE profile_flags[MAX_NBINS];
   YMDHMS_TIME_TYPE time;
   FILE *fpin, *fplog;
   FILE_NAME_TYPE logname;
   char buff[255];

   if (argc != 3)
   {
      printf("\n ERROR: Invalid no. of arguments on command line.");
      printf("\n USAGE: badbin <dbname> <badbin.asc>\n\n");
      exit(-1);
   }

   fpin = check_fopen(ascname, "r");
   if (dbopen_cnf(1, dbname, READ_WRITE, 0)) exit(-1);

   strcat(strcpy(logname, dbname), ".bbn");
   fplog = check_fopen(logname, "at");
   set_msg_file(fplog);

   while (!get_time(fpin, &time))
   {
      report_msg("\n...Processing ");
      write_ymdhms_time(stdout, &time);
      write_ymdhms_time(fplog, &time);

      if (dbsrch_cnf(TIME_SEARCH, (char *) &time)) goto close;

      npf = MAX_NBINS * sizeof(UBYTE);
      if (dbget_cnf(PROFILE_FLAGS, (char *) profile_flags, &npf,
         "getting profile flags")) goto close;

      use_profile_flags = (npf > 0);
      if (! use_profile_flags)
      {
         n = n_ev = MAX_NBINS * sizeof(SHORT);
         if (dbget_cnf(U, (char *) u_vel, &n, "getting u velocity")) goto close;
         if (dbget_cnf(V, (char *) v_vel, &n, "getting v velocity")) goto close;
         if (dbget_cnf(W, (char *) w_vel, &n, "getting w velocity")) goto close;
         if ( ((ierr = dbget_cnf(ERROR_VEL, (char *) e_vel, &n_ev,
            "getting error velocity")) != 0) && (ierr != INVALID_TYPE_REQUEST) )
            goto close;   /* error velocity may not always be present */
      }
      else
         n = npf;

      if (error_found( (fscanf(fpin, "%*d %*d %d", &badcount) < 1),
         "reading no. of bad bins")) goto close;
      sprintf(buff, "...badcount = %2d", badcount);
      report_msg(buff);

      for (i = 0; i < badcount; i++)
      {
         if ( (fscanf(fpin, "%d", &badbin) != 1) || badbin < 1 || badbin > n )
         {
            sprintf(buff, "\n%%%% ERROR: Reading bad bin no. %d\n\n", i+1);
            report_msg(buff);
            goto close;
         }
         sprintf(buff, " %3d", badbin);
         report_msg(buff);
         badbin--;                     /* adjust for C array indexing from 0 */
         if (use_profile_flags)
            profile_flags[badbin] |= GLITCH_BIT;
         else
         {
            u_vel[badbin] = v_vel[badbin] = w_vel[badbin] = BADSHORT;
            if (n_ev == n) e_vel[badbin] = BADSHORT;
         }
      }
      if (use_profile_flags)
      {
         if (dbput_cnf(PROFILE_FLAGS, (char *) profile_flags, &npf,
            "storing profile flags")) goto close;
      }
      else
      {
         if (dbput_cnf(U, (char *) u_vel, &n, "storing u velocity")) goto close;
         if (dbput_cnf(V, (char *) v_vel, &n, "storing v velocity")) goto close;
         if (dbput_cnf(W, (char *) w_vel, &n, "storing w velocity")) goto close;
         if (n_ev > 0)
            if (dbput_cnf(ERROR_VEL, (char *) e_vel, &n_ev, "storing error velocity"))
               goto close;
      }
   }

   error_found(set_db_dpmask(GLITCHES_REMOVED), "setting data processing mask");

   close:
      fclose(fpin);
      dbclose_cnf();
      return(0);
}

