# include "dvoshell.h"

void dbFreeFields (dbField *fields, int Nfields) {

  int i;

  if (fields == NULL) return;

  for (i = 0; i < Nfields; i++) {
    if (fields[i].name != NULL) free (fields[i].name);
    if (fields[i].photcode != NULL) {
      if (fields[i].photcode[0].type == PHOT_MAG) {
        free (fields[i].photcode);
      }
    }
  }
  free (fields);
}

void dbInitField (dbField *field) {
  field->name = NULL;
  field->extract = FALSE;
  field->table = 0;
  field->ID = 0;
  field->type = OPIHI_FLT;
  field->magMode = 0;
  field->photcode = NULL;
}

int GetMagMode (char *string) {

  if (!strcasecmp (string, "inst"))      return (MAG_INST);
  if (!strcasecmp (string, "cat"))       return (MAG_CAT);
  if (!strcasecmp (string, "sys"))       return (MAG_SYS);
  if (!strcasecmp (string, "rel"))       return (MAG_REL);
  if (!strcasecmp (string, "cal"))       return (MAG_CAL);
  if (!strcasecmp (string, "ave"))       return (MAG_AVE);
  if (!strcasecmp (string, "ref"))       return (MAG_REF);
  if (!strcasecmp (string, "ap"))        return (MAG_APER);
  if (!strcasecmp (string, "aper"))      return (MAG_APER);
  if (!strcasecmp (string, "err"))       return (MAG_ERR);
  if (!strcasecmp (string, "aveerr"))    return (MAG_AVE_ERR);
  if (!strcasecmp (string, "photflags")) return (MAG_PHOT_FLAGS);
  if (!strcasecmp (string, "chisq"))     return (MAG_CHISQ);
  if (!strcasecmp (string, "ncode"))     return (MAG_NCODE);
  if (!strcasecmp (string, "nphot"))     return (MAG_NPHOT);
  return (MAG_NONE);
}

PhotCode *ParsePhotcodeField (char *field, int *mode, int defMode) {

  int useDefault;
  char *tmpstring, *p;
  PhotCode *code;

  *mode = defMode;
  useDefault = TRUE;

  p = strchr (field, ':');
  if (p != NULL) {
    *mode = GetMagMode (p + 1);
    useDefault = FALSE;
    if (*mode == MAG_NONE) return (NULL);
    tmpstring = strncreate (field, p - field);
  } else {
    tmpstring = strcreate (field);
  }
  if (!strcasecmp (tmpstring, "MAG")) {
    ALLOCATE (code, PhotCode, 1);
    code[0].code = 0;
    strcpy (code[0].name, "MAG");
    code[0].type = PHOT_MAG;
    free (tmpstring);
    return (code);
  }
  code = GetPhotcodebyName (tmpstring);
  if (!code) {
      return NULL;
  }

  // enforce compatibility
  if (useDefault) {
    if (code[0].type == PHOT_REF) {
      *mode = MAG_CAT;
    }
    if (code[0].type == PHOT_DEP) {
      *mode = MAG_REL;
    }
  } 
  free (tmpstring);
  return (code);
}

# define ESCAPE(F,M,T) { \
  field->ID = (F); \
  field->magMode = (M); \
  field->type = (T); \
  field->photcode = NULL; \
  return (TRUE); }

int ParseMeasureField (dbField *field, char *fieldName) {

  int mode;
  PhotCode *code;

  field->table = DVO_TABLE_MEASURE;
  field->name  = strcreate (fieldName);

  if (!strcasecmp (fieldName, "GLON"))       {
    dbExtractMeasuresInitTransform (COORD_GALACTIC);
    ESCAPE (MEAS_GLON, MAG_NONE, OPIHI_FLT);
  }
  if (!strcasecmp (fieldName, "GLAT")) {
    dbExtractMeasuresInitTransform (COORD_GALACTIC);
    ESCAPE (MEAS_GLAT, MAG_NONE, OPIHI_FLT);
  }
  if (!strcasecmp (fieldName, "GLON:AVE")) {
    dbExtractMeasuresInitTransform (COORD_GALACTIC);
    ESCAPE (MEAS_GLON_AVE, MAG_NONE, OPIHI_FLT);
  }
  if (!strcasecmp (fieldName, "GLAT:AVE")) {
    dbExtractMeasuresInitTransform (COORD_GALACTIC);
    ESCAPE (MEAS_GLAT_AVE, MAG_NONE, OPIHI_FLT);
  }

  if (!strcasecmp (fieldName, "ELON"))       {
    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
    ESCAPE (MEAS_ELON, MAG_NONE, OPIHI_FLT);
  }
  if (!strcasecmp (fieldName, "ELAT")) {
    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
    ESCAPE (MEAS_ELAT, MAG_NONE, OPIHI_FLT);
  }
  if (!strcasecmp (fieldName, "ELON:AVE")) {
    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
    ESCAPE (MEAS_ELON_AVE, MAG_NONE, OPIHI_FLT);
  }
  if (!strcasecmp (fieldName, "ELAT:AVE")) {
    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
    ESCAPE (MEAS_ELAT_AVE, MAG_NONE, OPIHI_FLT);
  }

  if (!strcasecmp (fieldName, "RA"))         	 ESCAPE (MEAS_RA,             MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "DEC"))        	 ESCAPE (MEAS_DEC,            MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "RA:AVE"))     	 ESCAPE (MEAS_RA_AVE,         MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "DEC:AVE"))    	 ESCAPE (MEAS_DEC_AVE,        MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "RA:ERR"))     	 ESCAPE (MEAS_RA_AVE_ERR,     MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "DEC:ERR"))    	 ESCAPE (MEAS_DEC_AVE_ERR,    MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "uRA"))        	 ESCAPE (MEAS_U_RA,           MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "uDEC"))       	 ESCAPE (MEAS_U_DEC,          MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "duRA"))       	 ESCAPE (MEAS_U_RA_ERR,       MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "duDEC"))      	 ESCAPE (MEAS_U_DEC_ERR,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "PAR"))        	 ESCAPE (MEAS_PAR,            MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dPAR"))       	 ESCAPE (MEAS_PAR_ERR,        MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dR"))         	 ESCAPE (MEAS_RA_OFFSET,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dD"))         	 ESCAPE (MEAS_DEC_OFFSET,     MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dR:FIT"))     	 ESCAPE (MEAS_RA_FIT_OFFSET,  MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dD:FIT"))     	 ESCAPE (MEAS_DEC_FIT_OFFSET, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dR:ERR"))     	 ESCAPE (MEAS_RA_OFFSET_ERR,  MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dD:ERR"))     	 ESCAPE (MEAS_DEC_OFFSET_ERR, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "ChiSqPos"))       ESCAPE (MEAS_CHISQ_POS,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "ChiSqPM"))        ESCAPE (MEAS_CHISQ_PM,       MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "ChiSqPar"))       ESCAPE (MEAS_CHISQ_PAR,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Tmean"))          ESCAPE (MEAS_TMEAN,          MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Trange"))         ESCAPE (MEAS_TRANGE,         MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "nmeas"))      	 ESCAPE (MEAS_NMEAS,          MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "nmiss"))      	 ESCAPE (MEAS_NMISS,          MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "npos"))      	 ESCAPE (MEAS_NPOS,           MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "OBJFLAGS"))   	 ESCAPE (MEAS_OBJ_FLAGS,      MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "OBJ_FLAGS"))   	 ESCAPE (MEAS_OBJ_FLAGS,      MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "DB_FLAGS"))   	 ESCAPE (MEAS_DB_FLAGS,       MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "PHOT_FLAGS")) 	 ESCAPE (MEAS_PHOT_FLAGS,     MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "DBFLAGS"))   	 ESCAPE (MEAS_DB_FLAGS,       MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "PHOTFLAGS")) 	 ESCAPE (MEAS_PHOT_FLAGS,     MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "AIRMASS"))    	 ESCAPE (MEAS_AIRMASS,        MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "ALT"))        	 ESCAPE (MEAS_ALT,            MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "AZ"))         	 ESCAPE (MEAS_AZ,             MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "EXPTIME"))    	 ESCAPE (MEAS_EXPTIME,        MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "PHOTCODE"))   	 ESCAPE (MEAS_PHOTCODE,       MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "PHOTCODE:EQUIV")) ESCAPE (MEAS_PHOTCODE_EQUIV, MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "TIME"))       	 ESCAPE (MEAS_TIME,           MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "FWHM"))       	 ESCAPE (MEAS_FWHM,           MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "FWHM_MAJ"))   	 ESCAPE (MEAS_FWHM_MAJ,       MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "FWHM_MIN"))   	 ESCAPE (MEAS_FWHM_MIN,       MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "THETA"))      	 ESCAPE (MEAS_THETA,          MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "POSANGLE"))     	 ESCAPE (MEAS_POSANGLE,       MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "PLATESCALE"))   	 ESCAPE (MEAS_PLATESCALE,     MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "MXX"))       	 ESCAPE (MEAS_MXX,            MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "MYY"))       	 ESCAPE (MEAS_MYY,            MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "MXY"))       	 ESCAPE (MEAS_MXY,            MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "DOPHOT"))     	 ESCAPE (MEAS_DOPHOT,         MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "XCCD"))       	 ESCAPE (MEAS_XCCD,           MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "YCCD"))       	 ESCAPE (MEAS_YCCD,           MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "XCCD:ERR"))   	 ESCAPE (MEAS_XCCD_ERR,       MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "YCCD:ERR"))   	 ESCAPE (MEAS_YCCD_ERR,       MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "XMOSAIC"))    	 ESCAPE (MEAS_XMOSAIC,        MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "YMOSAIC"))    	 ESCAPE (MEAS_YMOSAIC,        MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "XCHIP"))      	 ESCAPE (MEAS_XCCD,           MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "YCHIP"))      	 ESCAPE (MEAS_YCCD,           MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "XFPA"))       	 ESCAPE (MEAS_XMOSAIC,        MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "YFPA"))       	 ESCAPE (MEAS_YMOSAIC,        MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "DETID"))      	 ESCAPE (MEAS_DET_ID,         MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "OBJID"))      	 ESCAPE (MEAS_OBJ_ID,         MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "CATID"))      	 ESCAPE (MEAS_CAT_ID,         MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "IMAGEID"))    	 ESCAPE (MEAS_IMAGE_ID,       MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "PSF_QF"))     	 ESCAPE (MEAS_PSF_QF,         MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "PSF_CHISQ"))  	 ESCAPE (MEAS_PSF_CHISQ,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "PSF_NDOF"))  	 ESCAPE (MEAS_PSF_NDOF,       MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "PSF_NPIX"))  	 ESCAPE (MEAS_PSF_NPIX,       MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "CR_NSIGMA"))  	 ESCAPE (MEAS_CR_NSIGMA,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "EXT_NSIGMA")) 	 ESCAPE (MEAS_EXT_NSIGMA,     MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "SKY"))        	 ESCAPE (MEAS_SKY,            MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "SKY_ERR"))    	 ESCAPE (MEAS_dSKY,           MAG_NONE, OPIHI_FLT);

  // for words that don't parse, try a photcode

  // check for code:mode in photcode name 
  code = ParsePhotcodeField (fieldName, &mode, MAG_REL);
  if (code == NULL) {
    gprint (GP_ERR, "unknown field '%s' for measurement table in DVO database\n", fieldName);
    return (FALSE);
  }

  field->ID = MEAS_MAG;
  field->magMode = mode;
  switch (mode) {
    case MAG_NCODE:
    case MAG_NPHOT:
    case MAG_PHOT_FLAGS:
      field->type = OPIHI_INT;
      break;
    default:
      field->type = OPIHI_FLT;
      break;
  }
  field->photcode = code;
  return (TRUE);
}
  
int ParseAverageField (dbField *field, char *fieldName) {

  int mode;
  PhotCode *code;

  field->table = DVO_TABLE_AVERAGE;
  field->name  = strcreate (fieldName);

  // if either GLON or GLAT is requested, we set up a static tranformation 
  // at prepare to calculate the values only once for each row
  if (!strcasecmp (fieldName, "GLON"))  { 
    dbExtractAveragesInitTransform (COORD_GALACTIC);
    ESCAPE (AVE_GLON, MAG_NONE, OPIHI_FLT);
  }
  if (!strcasecmp (fieldName, "GLAT"))  {
    dbExtractAveragesInitTransform (COORD_GALACTIC);
    ESCAPE (AVE_GLAT, MAG_NONE, OPIHI_FLT);
  }

  // if either ELON or ELAT is requested, we set up a static tranformation 
  // at prepare to calculate the values only once for each row
  if (!strcasecmp (fieldName, "ELON"))  { 
    dbExtractAveragesInitTransform (COORD_ECLIPTIC);
    ESCAPE (AVE_ELON, MAG_NONE, OPIHI_FLT);
  }
  if (!strcasecmp (fieldName, "ELAT"))  {
    dbExtractAveragesInitTransform (COORD_ECLIPTIC);
    ESCAPE (AVE_ELAT, MAG_NONE, OPIHI_FLT);
  }

  if (!strcasecmp (fieldName, "RA"))        ESCAPE (AVE_RA,        MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "DEC"))       ESCAPE (AVE_DEC,       MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "GLON"))      ESCAPE (AVE_GLON,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "GLAT"))      ESCAPE (AVE_GLAT,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "ELON"))      ESCAPE (AVE_ELON,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "ELAT"))      ESCAPE (AVE_ELAT,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dRA"))       ESCAPE (AVE_RA_ERR,    MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dDEC"))      ESCAPE (AVE_DEC_ERR,   MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "uRA"))       ESCAPE (AVE_U_RA,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "uDEC"))      ESCAPE (AVE_U_DEC,     MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "duRA"))      ESCAPE (AVE_U_RA_ERR,  MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "duDEC"))     ESCAPE (AVE_U_DEC_ERR, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "PAR"))       ESCAPE (AVE_PAR,       MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dPAR"))      ESCAPE (AVE_PAR_ERR,   MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "ChiSqPos"))  ESCAPE (AVE_CHISQ_POS, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "ChiSqPM"))   ESCAPE (AVE_CHISQ_PM, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "ChiSqPar"))  ESCAPE (AVE_CHISQ_PAR, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Tmean"))     ESCAPE (AVE_TMEAN,     MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Trange"))    ESCAPE (AVE_TRANGE,    MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "NMEAS"))     ESCAPE (AVE_NMEAS,     MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "NMISS"))     ESCAPE (AVE_NMISS,     MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "NPOS"))      ESCAPE (AVE_NPOS,      MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "NASTROM"))   ESCAPE (AVE_NPOS,      MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "FLAGS"))     ESCAPE (AVE_OBJ_FLAGS, MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "OBJ_FLAGS")) ESCAPE (AVE_OBJ_FLAGS, MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "OBJFLAGS"))  ESCAPE (AVE_OBJ_FLAGS, MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "OBJID"))     ESCAPE (AVE_OBJID,     MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "CATID"))     ESCAPE (AVE_CATID,     MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "EXTID_HI"))  ESCAPE (AVE_EXTID_HI,  MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "EXTID_LO"))  ESCAPE (AVE_EXTID_LO,  MAG_NONE, OPIHI_INT);

  // if (!strcasecmp (fieldName, "Xp"))      ESCAPE (AVE_Xp,        MAG_NONE, OPIHI_FLT);
  // if (!strcasecmp (fieldName, "TYPE"))    ESCAPE (AVE_TYPE,      MAG_NONE, OPIHI_INT);
  // for words that don't parse, try a photcode

  // check for code:mode in photcode name 
  code = ParsePhotcodeField (fieldName, &mode, MAG_AVE);
  if (code == NULL) {
    gprint (GP_ERR, "unknown field '%s' for average table in DVO database\n", fieldName);
    return (FALSE);
  }

  if (code[0].type == PHOT_MAG) {
    gprint (GP_ERR, "'mag' is ambiguous for avextract\n");
    free (code);
    return (FALSE);
  }

  field->ID = AVE_MAG;
  field->magMode = mode;
  switch (mode) {
    case MAG_NCODE:
    case MAG_NPHOT:
    case MAG_PHOT_FLAGS:
      field->type = OPIHI_INT;
      break;
    default:
      field->type = OPIHI_FLT;
      break;
  }
  field->photcode = code;
  return (TRUE);
}

int ParseImageField (dbField *field, char *fieldName) {

  field->table = DVO_TABLE_IMAGE;
  field->name  = strcreate (fieldName);

  // if either GLON or GLAT is requested, we set up a static tranformation 
  // at prepare to calculate the values only once for each row
  if (!strcasecmp (fieldName, "GLON"))  { 
    dbExtractImagesInitTransform (COORD_GALACTIC);
    ESCAPE (IMAGE_GLON, MAG_NONE, OPIHI_FLT);
  }
  if (!strcasecmp (fieldName, "GLAT"))  {
    dbExtractImagesInitTransform (COORD_GALACTIC);
    ESCAPE (IMAGE_GLAT, MAG_NONE, OPIHI_FLT);
  }

  // if either ELON or ELAT is requested, we set up a static tranformation 
  // at prepare to calculate the values only once for each row
  if (!strcasecmp (fieldName, "ELON"))  { 
    dbExtractImagesInitTransform (COORD_ECLIPTIC);
    ESCAPE (IMAGE_ELON, MAG_NONE, OPIHI_FLT);
  }
  if (!strcasecmp (fieldName, "ELAT"))  {
    dbExtractImagesInitTransform (COORD_ECLIPTIC);
    ESCAPE (IMAGE_ELAT, MAG_NONE, OPIHI_FLT);
  }

  if (!strcasecmp (fieldName, "RA"       )) ESCAPE (IMAGE_RA,        MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "DEC"      )) ESCAPE (IMAGE_DEC,       MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "GLON"     )) ESCAPE (IMAGE_GLON,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "GLAT"     )) ESCAPE (IMAGE_GLAT,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "ELON"     )) ESCAPE (IMAGE_ELON,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "ELAT"     )) ESCAPE (IMAGE_ELAT,      MAG_NONE, OPIHI_FLT);

  if (!strcasecmp (fieldName, "theta"    )) ESCAPE (IMAGE_THETA,     MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "skew"     )) ESCAPE (IMAGE_SKEW,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "scale"    )) ESCAPE (IMAGE_SCALE,     MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dscale"   )) ESCAPE (IMAGE_DSCALE,    MAG_NONE, OPIHI_FLT);

  if (!strcasecmp (fieldName, "time"     )) ESCAPE (IMAGE_TIME,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "nstar"    )) ESCAPE (IMAGE_NSTAR,     MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "airmass"  )) ESCAPE (IMAGE_AIRMASS,   MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "NX"       )) ESCAPE (IMAGE_NX_PIX,    MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "NY"       )) ESCAPE (IMAGE_NY_PIX,    MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "apresid"  )) ESCAPE (IMAGE_APRESID,   MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dapresid" )) ESCAPE (IMAGE_DAPRESID,  MAG_NONE, OPIHI_FLT);

  if (!strcasecmp (fieldName, "Mcal"     )) ESCAPE (IMAGE_MCAL,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "dMcal"    )) ESCAPE (IMAGE_dMCAL,     MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Xm"       )) ESCAPE (IMAGE_XM,        MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "photcode" )) ESCAPE (IMAGE_PHOTCODE,  MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "exptime"  )) ESCAPE (IMAGE_EXPTIME,   MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "sidtime"  )) ESCAPE (IMAGE_SIDTIME,   MAG_NONE, OPIHI_FLT);

  if (!strcasecmp (fieldName, "latitude" )) ESCAPE (IMAGE_LATITUDE,  MAG_NONE, OPIHI_FLT);

  if (!strcasecmp (fieldName, "detlimit" )) ESCAPE (IMAGE_DET_LIMIT, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "satlimit" )) ESCAPE (IMAGE_SAT_LIMIT, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "cerror"   )) ESCAPE (IMAGE_CERROR,    MAG_NONE, OPIHI_FLT);

  if (!strcasecmp (fieldName, "FWHM"     )) ESCAPE (IMAGE_FWHM,      MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "FWHM_MAJ" )) ESCAPE (IMAGE_FWHM_MAJ,  MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "FWHM_MIN" )) ESCAPE (IMAGE_FWHM_MIN,  MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "trate"    )) ESCAPE (IMAGE_TRATE,     MAG_NONE, OPIHI_FLT);

  // XXX : these are mapped to ridiculous things: Myyyy + 0x8000 and Mxxxx
  if (!strcasecmp (fieldName, "ncal"     )) ESCAPE (IMAGE_NCAL,      MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "sky"      )) ESCAPE (IMAGE_SKY,       MAG_NONE, OPIHI_FLT);

  if (!strcasecmp (fieldName, "imflags"  )) ESCAPE (IMAGE_FLAGS,     MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "flags"    )) ESCAPE (IMAGE_FLAGS,     MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "ccdnum"   )) ESCAPE (IMAGE_CCDNUM,    MAG_NONE, OPIHI_INT);

  if (!strcasecmp (fieldName, "imageID"  )) ESCAPE (IMAGE_IMAGE_ID,  MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "externID" )) ESCAPE (IMAGE_EXTERN_ID, MAG_NONE, OPIHI_INT);
  if (!strcasecmp (fieldName, "sourceID" )) ESCAPE (IMAGE_SOURCE_ID, MAG_NONE, OPIHI_INT);

  if (!strcasecmp (fieldName, "X_LL_CHIP")) ESCAPE (IMAGE_X_LL_CHIP, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "X_LR_CHIP")) ESCAPE (IMAGE_X_LR_CHIP, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "X_UL_CHIP")) ESCAPE (IMAGE_X_UL_CHIP, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "X_UR_CHIP")) ESCAPE (IMAGE_X_UR_CHIP, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Y_LL_CHIP")) ESCAPE (IMAGE_Y_LL_CHIP, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Y_LR_CHIP")) ESCAPE (IMAGE_Y_LR_CHIP, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Y_UL_CHIP")) ESCAPE (IMAGE_Y_UL_CHIP, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Y_UR_CHIP")) ESCAPE (IMAGE_Y_UR_CHIP, MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "X_LL_FP"  )) ESCAPE (IMAGE_X_LL_FP,   MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "X_LR_FP"  )) ESCAPE (IMAGE_X_LR_FP,   MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "X_UL_FP"  )) ESCAPE (IMAGE_X_UL_FP,   MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "X_UR_FP"  )) ESCAPE (IMAGE_X_UR_FP,   MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Y_LL_FP"  )) ESCAPE (IMAGE_Y_LL_FP,   MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Y_LR_FP"  )) ESCAPE (IMAGE_Y_LR_FP,   MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Y_UL_FP"  )) ESCAPE (IMAGE_Y_UL_FP,   MAG_NONE, OPIHI_FLT);
  if (!strcasecmp (fieldName, "Y_UR_FP"  )) ESCAPE (IMAGE_Y_UR_FP,   MAG_NONE, OPIHI_FLT);

  // for words that don't parse, try a photcode
  gprint (GP_ERR, "unknown field '%s' for image table in DVO database\n", fieldName);
  return (FALSE);
}
