/********************************************************
* Routines used in both the DI calibration interpolation
* routines.
********************************************************/

#include <stdio.h>
#include "idl_export.h"
#include "dical_interptools.h"

/********************************************************
* isValidPix
*
* Identifies if a pixel has valid information
*
* bad - pointer to an array specifying the bad pixels
* badCnt - how many bad pixels there are
* idx - index of pixel to test
* maxIdx - the maximum index in the image
*
* RETURNS - 1 if it is valid, 0 otherwise
********************************************************/
int isValidPix(IDL_LONG *bad, int badCnt, int idx, int maxIdx){
  int i;
  int top,bot,mid;  //The current search range

  // Make sure we're not out of the image
  if (idx > maxIdx || idx < 0)
    return 0;

  // See if the index is in the bad pixel list
  top = badCnt-1;
  bot = 0;
  while(top>(bot+1)){
    mid = (top+bot)/2;
    if(idx>bad[mid])
      bot = mid;
    else
      top = mid;
  }
  return (bad[top] != idx) && (bad[bot] != idx);
}

/********************************************************
* interpCheckParams
*
* Checks all the parameteres coming in to an interpolation
* routine and modify variables to allow interpolation to
* occur
*
* imgIn - idl structure specifying the input image
* imgOut - pointer to an IDL structure that specifies the output image
* toInterp - idl structure of array of indices to interpolate over
* badPixs - idl structure of array of indices that are invalid
* in - Pointer to a pointer to the begining of the input image
* out - Pointer to a pointer to the begining of the image to output
* imgWid - Pointer to an integer that stores the image width
* toDo - Pointer to the pointer of the begining of the array of interpolation
*       indices
* doCnt - POinter to the an integer specifying how many pixels to interpolate
* bad - Pointer to the pointer of the begining of the array of bad pixs
* badCnt - pointer to an integer specifying how many bad pixels exist
*
* RETURNS - 0 if sucessful
********************************************************/
int interpCheckParams(IDL_VPTR imgIn, IDL_VPTR* imgOut, IDL_VPTR toInterp,
  IDL_VPTR badPixs,double** in, double** out, int* imgWid, IDL_LONG** toDo,
  int* doCnt, IDL_LONG** bad, int* badCnt){

    // Make sure the input is valid
  IDL_ENSURE_SIMPLE(imgIn);
  IDL_ENSURE_ARRAY(imgIn);
  IDL_ENSURE_SIMPLE(toInterp);
  IDL_ENSURE_SIMPLE(badPixs);

  // Convert the image to double if it isn't already
  if (imgIn->type != IDL_TYP_DOUBLE){
    *imgOut = IDL_CvtDbl(1,&imgIn);
    imgIn = *imgOut;
  }
  if (toInterp->type != IDL_TYP_LONG)
    toInterp = IDL_CvtLng(1,&toInterp);
  if (badPixs->type != IDL_TYP_LONG)
    badPixs = IDL_CvtLng(1,&badPixs);

  // Get the info about all the input
  *in = *out = (double *)imgIn->value.arr->data;
  *imgWid = imgIn->value.arr->dim[0];
  if (toInterp->flags & IDL_V_ARR)
  {
    *toDo = (IDL_LONG *)toInterp->value.arr->data;
    *doCnt = toInterp->value.arr->dim[0];
  }
  else
  {
    *toDo = &(toInterp->value.l);
    // If there's nothing to interpolate, stop now
    if (**toDo == -1)
      return 1;
    *doCnt = 1;
  }
   if (badPixs->flags & IDL_V_ARR)
  {
    *bad = (IDL_LONG *)badPixs->value.arr->data;
    *badCnt = badPixs->value.arr->dim[0];
  }
  else
  {
    *bad = &(badPixs->value.l);
    *badCnt = 1;
  }

  // Make sure the output is tempoarary so that we can write to it
  if (!(imgIn->flags & IDL_V_TEMP))
    *out = (double*) IDL_VarMakeTempFromTemplate(
      imgIn, IDL_TYP_DOUBLE, NULL, imgOut, FALSE);

  return 0;
}