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

   FILLGAPS.C

   This function linearly interpolates across gaps in a
   vector.  It returns the number of gaps filled.
   If the gap is at the beginning or end, it is filled
   with the nearest good value.  The number of gaps filled
   is returned, or n if the situation is hopeless.

*/
#include "common.h"
#include "vector.h"

#if PROTOTYPE_ALLOWED
int fill_gaps(float *f, int n)
#else
int fill_gaps(f, n)
float *f;
int n;
#endif
{
   double fo, df;
   int i;
   int    n0 = 0,
          n1 = 0,
       ngaps = 0;

   while (n0 < n)
   {
      while ((n0 < n) && (good_float(f[n0]))) n0++;
      /* Now n0 is n or the beginning of a bad section. */

      n1 = n0;
      while ((n1 < n) && (!good_float(f[n1]))) n1++;
      /* Now n1 is n or the beginning of a good section. */
      /* If either is n, both should be n */

      /* cases: disaster: n0 = 0 and n1 = n
                bad start: n0 = 0, n1<n-1
                bad end:   0 < n0 < n, n1 = n
                normal gap:  0 < n0 < n, n0 < n1 < n

      */
      if (n0 == 0)                   /* bad start */
      {
         if (n1 == n)  return (n);   /* nothing is good */
         for (i=0; i<n1; i++)        /* something is good */
         {
            f[i] = f[n1];
            ngaps++;
         }
      }
      else if (n1 == n)              /* bad end */
      {
         for (i=n0; i<n; i++)
         {
            f[i] = f[n0-1];
            ngaps ++;
         }
      }
      else                           /* it is in the middle; interpolate */
      {
         fo = f[n0 - 1];
         df = (f[n1] - fo) / (n1 - n0 + 1);
         for (i=n0; i<n1; i++)
         {
            f[i] = fo + (i-n0+1) * df;
            ngaps++;
         }
      } /* finished interpolating */
   }  /* finished looking for bad segments */
   return (ngaps);
}

#ifdef EXE
#include "prtarray.h"  /* print_array_float() */

float ff[1000];
#if PROTOTYPE_ALLOWED
void main(void)
#else
void main()
#endif
{
   int n, ng;

   printf("\n control-Z to end the array input \n");
   n = read_array_float(stdin, ff, 1000, " %f ");
   ng = fill_gaps(ff, n);
   printf("\n %d gaps filled\n", ng);
   print_array_float(stdout, ff, n, 1, " %f ");
}
#endif
