/******************************************************************************
*
     PROGRAM:  LAST_85.C
     USAGE:  LAST_85 <dbname>

     This program reduces the last_good_bin field in the ANCILLARY_2 structure
     of the database specified by <dbname> by 15% for those profiles at which
     interference from the ocean bottom has been detected (i.e., those for
     which the last_good_bin has been set to a value less than the original
     number of bins by earlier editing programs).  It turns on bit 10 of the
     data processing mask in each block to indicate that the database has been
     edited in this manner.  It also checks if the last_good_bin field of the
     ACCESS_VARIABLES structure must similarly be reset.

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

     Modified 05/25/89 to skip blocks that have already been processed as
     indicated by the data processing mask--allowing processing of partial
     databases during acquisition.

     Modified 12/21/89 to check if BOTTOM_SOUGHT bit of data processing mask
     has been set (by BOTMPAS3 or a similar routine).  If not set, the
     user is given warning as this probably indicates that no program was
     previously run to set the last good bin field of ANCILLARY_2
     (e.g., BOTMPAS3) and running LAST_85 in that case would set the
     BOTTOM_MGB bit of the mask without taking 15% off anything.

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

#include "geninc.h"
#include <math.h>          /* floor() function */
#include "data_id.h"       /* CODAS variable names and IDs   */
#include "adcp.h"          /* ADCP data structure typedefs   */
#include "use_db.h"        /* db*_cnf(), set_block_dpmask()  */
#include "ioserv.h"        /* error_found()                  */
#include "dbedit.h"        /* update_acc_var()               */
#include "dpmask.h"        /* BOTTOM_MGB, BOTTOM_SOUGHT      */

#define dbname argv[1]

#if PROTOTYPE_ALLOWED
int main(int argc, char *argv[])
#else
int main(argc, argv)
int argc;
char *argv[];
#endif
{
   int                  set;
   ANCILLARY_2_TYPE     anc;
   CONFIGURATION_1_TYPE conf;
   FLOAT                temp;
   int                  iblkprf[2], blksave = -99;
   unsigned int         n;
   char                 answer[2];

   if (argc < 2)
   {
      printf("\n USAGE: last_85 <dbname>");
      exit(-1);
   }

   if (dbopen_cnf(1, dbname, READ_WRITE, DIR_IN_MEMORY)) exit(-1);

   /*-------------------------------------------------------------------------
       LOCATE FIRST BLOCK NOT YET PROCESSED BY CHECKING DATA PROCESSING MASK
     -------------------------------------------------------------------------*/
   iblkprf[0] = -1; iblkprf[1] = 0;
   do
   {
      iblkprf[0]++;
      if (dbsrch_cnf(BLOCK_PROFILE_SEARCH, (char *) iblkprf))
         goto close;
      if (error_found( ((set = check_block_dpmask(BOTTOM_MGB)) == -1),
         "checking data processing mask")) goto close;
   } while (set);

   /*------------------------
       MAIN PROCESSING LOOP
     ------------------------*/
   do
   {
      n = 2 * sizeof(int);
      if (dbget_cnf(BLOCK_PROFILE_INDEX, (char *) iblkprf, &n,
         "getting block-profile index")) goto close;
      if (iblkprf[0] != blksave)  /* new block */
      {
         if (error_found( ((set = check_block_dpmask(BOTTOM_SOUGHT)) == -1),
            "checking data processing mask")) goto close;
         if (!set)
         {
            printf("\n%%%% WARNING: BOTTOM_SOUGHT flag of data processing mask");
            printf("\n            not yet set.  Last good bin field of ");
            printf("\n            ANCILLARY_2 structure may not be set.\n");
            printf("\n   Continue (y/n)? ");
            scanf("%1s", answer);
            if (toupper(answer[0]) != 'Y') goto close;
         }
         n = sizeof(CONFIGURATION_1_TYPE);
         if (dbget_cnf(CONFIGURATION_1, (char *) &conf, &n,
            "getting configuration")) goto close;
         blksave = iblkprf[0];
         if (set_block_dpmask(BOTTOM_MGB)) goto close;
      }

      n = sizeof(ANCILLARY_2_TYPE);
      if (dbget_cnf(ANCILLARY_2, (char *) &anc, &n, "getting ancillary"))
         goto close;

      if ((anc.last_good_bin < conf.num_bins) && (anc.last_good_bin != -1))
      {
         temp = .85 * anc.last_good_bin;
         anc.last_good_bin = floor((double) temp);
         /* if 85% falls within current bin, set to lower bin no. */
         if ((temp - anc.last_good_bin) < 0.5) (anc.last_good_bin)--;

         n = sizeof(ANCILLARY_2_TYPE);
         if (dbput_cnf(ANCILLARY_2, (char *) &anc, &n,
            "storing ancillary data")) goto close;
         if (update_acc_var(anc.last_good_bin)) goto close;
      }
   } while (dbmove_cnf(1) != SEARCH_BEYOND_END);

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

