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

   FILE:  DELBLK.C
   USAGE: DELBLK

          This program deletes a block, profile, or sequence of profiles
          from a CODAS database.  It provides the user with four options:

             1. Delete block range
             2. Delete block-profile range
             3. Delete time range
             4. Exit program

                             Hui Zhu
                             87-03-10

89/05/23 - JR - Added compiler-switchable modifications to permit use
                with CODAS3. Improved error-handling (will abort on
                error). Modified option to delete range of
                block-profiles to handle ranges that cross block
                boundaries.

91/09/11 - JR - Reduced from 6 to 4 options.  Modified to 'dbmove' only
                if the end of the user range has not been reached
                (otherwise, can cause error messages when range ends
                exactly at database end).

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

#include "geninc.h"     /* YMDHMS_TIME_TYPE, DBDELPRF(), DBDELBLK(), ... */
#include "use_db.h"     /* check_db*(), db*_cnf() */

#if PROTOTYPE_ALLOWED
void main(int argc, char *argv[])
#else
void main(argc, argv)
int argc;
char *argv[];
#endif
{
   BLKPRF_INDEX_TYPE    bpfrom, bpto, curr_bp;
   YMDHMS_TIME_TYPE timefrom, timeto, curr_time;
   FILE_NAME_TYPE   dbname;
   int choice, count = 0, ier = 0;
   char answer = 'N';
   unsigned int nt = sizeof(YMDHMS_TIME_TYPE), nbp = sizeof(BLKPRF_INDEX_TYPE);
   char buff[80];

   if (argc < 2)
   {
      printf("\n ENTER DATABASE NAME: ");
      gets(dbname);
   }
   else
      strcpy(dbname, argv[1]);

   if (dbopen_cnf(1, dbname, READ_WRITE, DIR_IN_MEMORY)) return;

   do
   {
      printf("\n Enter one of the following numbers : \n\n");
      printf("  1.  Delete block(s)\n");
      printf("  2.  Delete block-profile range\n");
      printf("  3.  Delete time range\n");
      printf("  4.  Exit program\n");
      printf("\n ==> ");
      gets(buff);
   } while (sscanf(buff, " %d", &choice) != 1 && (choice < 1 || choice > 4));

   switch(choice)
   {
      case 1:
         do
         {
            printf("\n\n Enter block range ==> (B# to B#) ");
            gets(buff);
         } while (sscanf(buff, " %d to %d", &bpfrom.block, &bpto.block) != 2);
         bpfrom.profile = bpto.profile = 0;
         ier = dbsrch_cnf(BLOCK_PROFILE_SEARCH, (char *) &bpto);
         if (DBERROR(&ier, "searching for end block-profile"))
            goto close_db;
         if (dbget_cnf(TIME, (char *) &timeto, &nt, "getting end time"))
            goto close_db;
         ier = dbsrch_cnf(BLOCK_PROFILE_SEARCH, (char *) &bpfrom);
         if (DBERROR(&ier, "searching for start block-profile"))
            goto close_db;
         if (dbget_cnf(TIME, (char *) &timefrom, &nt, "getting start time"))
            goto close_db;
         if (dbget_cnf(BLOCK_PROFILE_INDEX, (char *) &curr_bp, &nbp,
            "getting current block-profile index")) goto close_db;
         break;
      case 2:
         do
         {
            printf("\n\n Enter block-profile range ==> (B# P# to B# P#) ");
            gets(buff);
         }
         while (sscanf(buff, " %d %d to %d %d", &bpfrom.block, &bpfrom.profile,
            &bpto.block, &bpto.profile) != 4);
         ier = dbsrch_cnf(BLOCK_PROFILE_SEARCH, (char *) &bpto);
         if (DBERROR(&ier, "searching for end block-profile"))
            goto close_db;
         if (dbget_cnf(TIME, (char *) &timeto, &nt, "getting end time"))
            goto close_db;
         ier = dbsrch_cnf(BLOCK_PROFILE_SEARCH, (char *) &bpfrom);
         if (DBERROR(&ier, "searching for start block-profile"))
            goto close_db;
         if (dbget_cnf(TIME, (char *) &timefrom, &nt, "getting start time"))
            goto close_db;
         break;
      case 3:
         do
         {
            printf("\n\n Enter time range ==> (Y M D H M S  to  Y M D H M S) ");
            gets(buff);
         } while (sscanf(buff,
            " %hd %hd %hd %hd %hd %hd to %hd %hd %hd %hd %hd %hd",
            &timefrom.year, &timefrom.month, &timefrom.day,
            &timefrom.hour, &timefrom.minute, &timefrom.second,
            &timeto.year, &timeto.month, &timeto.day,
            &timeto.hour, &timeto.minute, &timeto.second) != 12);
         ier = dbsrch_cnf(TIME_SEARCH, (char *) &timeto);
	 if (ier && ier != SEARCH_BEYOND_END)
	 {
	    DBERROR(&ier, "searching for end time");
	    goto close_db;
         }
         if (dbget_cnf(TIME, (char *) &curr_time, &nt, "getting current time"))
            goto close_db;
         if (TIMCMP(&curr_time, &timeto) == 2)   /* since time search  */
            if (dbmove_cnf(-1)) goto close_db;   /* positions at time >= key */
         if (dbget_cnf(BLOCK_PROFILE_INDEX, (char *) &bpto, &nbp,
            "getting block-profile index")) goto close_db;
         ier = dbsrch_cnf(TIME_SEARCH, (char *) &timefrom);
	 if (ier && ier != SEARCH_BEFORE_BEGINNING)
	 {
            DBERROR(&ier, "searching for start time");
	    goto close_db;
         }
         if (dbget_cnf(BLOCK_PROFILE_INDEX, (char *) &bpfrom, &nbp,
            "getting block-profile index")) goto close_db;
         break;
      case 4:
         goto close_db;
   }

   print_time_range(stdout, &timefrom, &timeto);
   do
   {
      printf("\n Delete? (Y/N) ==> ");
      gets(buff);
      sscanf(buff, " %c", &answer);
   } while (answer != 'Y' && answer != 'y' && answer != 'N' && answer != 'n');

   if (answer == 'Y' || answer == 'y')
   {
      printf("\n Deleting ");
      switch(choice)
      {
         case 1:  /* delete block range */
	    printf("block");
            while (curr_bp.block >= bpfrom.block && curr_bp.block <= bpto.block)
            {
               DBDELBLK(&ier);
               if (DBERROR(&ier, "in DELBLK")) goto close_db;
               printf(" %d", curr_bp.block);
               count++;
               if (curr_bp.block == bpto.block) break;
               if (dbmove_cnf(1)) goto close_db;
               if (dbget_cnf(BLOCK_PROFILE_INDEX, (char *) &curr_bp, &nbp,
                  "getting current block-profile index")) goto close_db;
            }
            printf("\n %d block(s) deleted\n\n", count);
            break;
         case 2: /* delete block-profile range */
         case 3: /* delete time range */
            curr_bp = bpfrom;
            while (BPCMP(&curr_bp, &bpfrom) >= 0 && BPCMP(&curr_bp, &bpto) <= 0)
            {
               DBDELPRF(&ier);
               if (DBERROR(&ier, "in DBDELPRF")) goto close_db;
               printf(".");
               count++;
               if (curr_bp.block == bpto.block &&
                  curr_bp.profile == bpto.profile) break;
               if (dbmove_cnf(1)) goto close_db;
               if (dbget_cnf(BLOCK_PROFILE_INDEX, (char *) &curr_bp, &nbp,
                  "getting current block-profile index")) goto close_db;
            }
            printf("\n %d profile(s) deleted\n\n", count);
            break;
      }
   }

   close_db:
      dbclose_cnf();
}

