# include "addstar.h"
# include "WISE.h"

// XXX check to see if desired output format is PS1_V1 or later?  (use 16bit version if not?)

// fill in the data for a WISE quad star.  takes a pointer to the start of the line the
// RA and DEC have already been set
int getWISE_star_full (Stars **star, char *line, int Nmax) {

  char *ptr;
  double dMfull;
  double jd;

  if (line == NULL) Shutdown ("format error in WISE");

  ptr = skipNbounds (ptr, '|', 3, Nmax); // skip: desig, ra, dec,
  star[0][0].measure.FWx = ToShortPixels(strtod (ptr, NULL));
  ptr = nextWISEfield (ptr); // sig_dec
  star[0][0].measure.FWy = ToShortPixels(strtod (ptr, NULL));
  ptr = nextWISEfield (ptr); // sig_radec
  star[0][0].measure.theta = ToShortPixels(strtod (ptr, NULL));

  star[1][0].measure.FWx   = star[0][0].measure.FWx;
  star[1][0].measure.FWy   = star[0][0].measure.FWy;
  star[1][0].measure.theta = star[0][0].measure.theta;
  star[2][0].measure.FWx   = star[0][0].measure.FWx;
  star[2][0].measure.FWy   = star[0][0].measure.FWy;
  star[2][0].measure.theta = star[0][0].measure.theta;
  star[3][0].measure.FWx   = star[0][0].measure.FWx;
  star[3][0].measure.FWy   = star[0][0].measure.FWy;
  star[3][0].measure.theta = star[0][0].measure.theta;

  ptr = skipNbounds (ptr, '|', 10, Nmax); // skip: glon, glat, elon, elat, wx, wy, cntr, source_id, coadd_id, src

  // W1
  star[0][0].measure.M  = strtod (ptr, NULL);
  ptr = nextWISEfield (ptr); // j_cmsig
  star[0][0].measure.dM = strtod (ptr, NULL);
  ptr = skipNbounds (ptr, '|', 2, Nmax); // skip: w1snr, w1rchi2

  // W2
  star[1][0].measure.M  = strtod (ptr, NULL);
  ptr = nextWISEfield (ptr); // j_cmsig
  star[1][0].measure.dM = strtod (ptr, NULL);
  ptr = skipNbounds (ptr, '|', 2, Nmax); // skip: w2snr, w2rchi2

  // W3
  star[2][0].measure.M  = strtod (ptr, NULL);
  ptr = nextWISEfield (ptr); // j_cmsig
  star[2][0].measure.dM = strtod (ptr, NULL);
  ptr = skipNbounds (ptr, '|', 2, Nmax); // skip: w3snr, w3rchi2

  // W4
  star[3][0].measure.M  = strtod (ptr, NULL);
  ptr = nextWISEfield (ptr); // j_cmsig
  star[3][0].measure.dM = strtod (ptr, NULL);
  ptr = skipNbounds (ptr, '|', 2, Nmax); // skip: w4snr, w4rchi2

  star[0][0].measure.photFlags = 0;
  star[1][0].measure.photFlags = 0;
  star[2][0].measure.photFlags = 0;
  star[3][0].measure.photFlags = 0;
  ptr = skipNbounds (ptr, '|', 8, Nmax); // skip fields

  setWISE_cc_flag (star[0], ptr[0]); // cc_flg
  setWISE_cc_flag (star[1], ptr[1]); // cc_flg
  setWISE_cc_flag (star[2], ptr[2]); // cc_flg
  setWISE_cc_flag (star[3], ptr[2]); // cc_flg
  ptr = skipNbounds (ptr, '|', 2, Nmax); // skip: ext_flg, var_flg

  setWISE_ph_qual (star[0], ptr[0]); // ph_qual
  setWISE_ph_qual (star[1], ptr[1]); // ph_qual
  setWISE_ph_qual (star[2], ptr[2]); // ph_qual
  setWISE_ph_qual (star[3], ptr[3]); // ph_qual
  ptr = skipNbounds (ptr, '|', 2, Nmax); // skip: ext_flg, var_flg

  // setWISE_rd_flag (star[0], ptr[0]);
  // setWISE_bl_flag (star[0], ptr[0]);
  // setWISE_gal_flag (star[0], ptr[0]);
  // setWISE_mp_flag (star[0], ptr[0]);

  // ptr = nextWISEfield (ptr); // x_scan
  // star[0][0].measure.Xccd = strtod (ptr, NULL);
  // star[2][0].measure.Xccd = star[1][0].measure.Xccd = star[0][0].measure.Xccd;
  // ptr = nextWISEfield (ptr); // jdate (julian date)

  jd = 2455263.0; // NOTE : WISE prelim release does not contain per-detection time info. 
  // the release is based on data taken in the period 14 January 2010 to 29 April 2010
  star[0][0].measure.t = ohana_jd_to_sec (jd);
  star[1][0].measure.t = star[0][0].measure.t;
  star[2][0].measure.t = star[0][0].measure.t;
  star[3][0].measure.t = star[0][0].measure.t;

  // ptr = nextWISEfield (ptr); // j_psfchi
  // star[0][0].measure.psfChisq = strtod (ptr, NULL);
  // ptr = nextWISEfield (ptr); // h_psfchi
  // star[1][0].measure.psfChisq = strtod (ptr, NULL);
  // ptr = nextWISEfield (ptr); // k_psfchi
  // star[2][0].measure.psfChisq = strtod (ptr, NULL);
  // 
  // ptr = nextWISEfield (ptr); // j_m_stdap
  // star[0][0].measure.Map = strtod (ptr, NULL);
  // ptr = nextWISEfield (ptr); // j_msig_stdap (skip?)
  // 
  // ptr = nextWISEfield (ptr); // h_m_stdap
  // star[1][0].measure.Map = strtod (ptr, NULL);
  // ptr = nextWISEfield (ptr); // h_msig_stdap (skip?)
  // 
  // ptr = nextWISEfield (ptr); // k_m_stdap
  // star[2][0].measure.Map = strtod (ptr, NULL);
  // ptr = nextWISEfield (ptr); // k_msig_stdap (skip?)
  // 
  // ptr = nextWISEfield (ptr); // dist_edge_ns (skip)
  // ptr = nextWISEfield (ptr); // dist_edge_ew (skip)
  // ptr = nextWISEfield (ptr); // dist_edge_flg (skip)
  // 
  // ptr = nextWISEfield (ptr); // dup_src (one flag for all filters)
  // setWISE_dup_flag (star[0], ptr[0]);
  // setWISE_dup_flag (star[1], ptr[0]);
  // setWISE_dup_flag (star[2], ptr[0]);
  // 
  // ptr = nextWISEfield (ptr); // use_src (one flag for all filters)
  // setWISE_use_flag (star[0], ptr[0]);
  // setWISE_use_flag (star[1], ptr[0]);
  // setWISE_use_flag (star[2], ptr[0]);

  star[0][0].measure.photcode  = TM_J;
  star[0][0].measure.detID   = 0;
  star[0][0].measure.imageID = 0;

  star[1][0].measure.photcode  = TM_H;
  star[1][0].measure.detID   = 0;
  star[1][0].measure.imageID = 0;

  star[2][0].measure.photcode  = TM_K;
  star[2][0].measure.detID   = 0;
  star[2][0].measure.imageID = 0;

  return TRUE;
}

/* return a pointer to the first char after the next field separator (|) */
char *nextWISEfield (char *line) {

  char *p, *q;

  p = line;
  q = strchr (p, '|');
  if (q == NULL) return (NULL);
  p = q + 1;
  if (*p == 0) return (NULL);
  return (p);
}

int setWISE_cc_flag (Stars *star, char qual) {

  switch (qual) {
    case 'p': star[0].measure.photFlags |= 0x00010000; break;
    case 'P': star[0].measure.photFlags |= 0x00010000; break;
    case 'h': star[0].measure.photFlags |= 0x00020000; break;
    case 'H': star[0].measure.photFlags |= 0x00020000; break;
    case 'd': star[0].measure.photFlags |= 0x00040000; break;
    case 'D': star[0].measure.photFlags |= 0x00040000; break;
    case 'o': star[0].measure.photFlags |= 0x00020000; break;
    case 'O': star[0].measure.photFlags |= 0x00020000; break;
    case '0': break;
    default: 
      fprintf (stderr, "error!\n");
      exit (2);
  }      
  return (TRUE);
}

int setWISE_ph_qual (Stars *star, char qual) {

  switch (qual) {
    case 'A': star[0].measure.photFlags |= 0x00000001; break; // was: 0x0004
    case 'B': star[0].measure.photFlags |= 0x00000002; break; // was: 0x0005
    case 'C': star[0].measure.photFlags |= 0x00000004; break; // was: 0x0006
    case 'U': star[0].measure.photFlags |= 0x00000040; break; // was: 0x0001
    case 'X': star[0].measure.photFlags |= 0x00000080; break; // was: 0x0000
    default: 
      fprintf (stderr, "error!\n");
      exit (2);
  }      
  return (TRUE);
}

int setWISE_rd_flag (Stars *star, char qual) {

  switch (qual) {
    case '0': star[0].measure.photFlags |= 0x00000100; break; // was: 0x0000 
    case '1': star[0].measure.photFlags |= 0x00000200; break; // was: 0x0010 
    case '2': star[0].measure.photFlags |= 0x00000400; break; // was: 0x0020 
    case '3': star[0].measure.photFlags |= 0x00000800; break; // was: 0x0030 
    case '4': star[0].measure.photFlags |= 0x00001000; break; // was: 0x0040 
    case '6': star[0].measure.photFlags |= 0x00002000; break; // was: 0x0050 
    case '9': star[0].measure.photFlags |= 0x00004000; break; // was: 0x0060 
    default: 
      fprintf (stderr, "error!\n");
      exit (2);
  }      
  return (TRUE);
}

int setWISE_bl_flag (Stars *star, char qual) {

  switch (qual) {
    case '0': star[0].measure.photFlags &= ~0x00300000; break; // was: ~0x0008
    case '1': star[0].measure.photFlags |=  0x00100000; break; // was: ~0x0008
    default:  star[0].measure.photFlags |=  0x00200000; break; // was:  0x0008
  }      
  return (TRUE);
}

int setWISE_gal_flag (Stars *star, char qual) {

  switch (qual) {
    case '0': star[0].measure.photFlags &= ~0x00c00000; break; // was: ~0x0080 
    case '1': star[0].measure.photFlags |=  0x00400000; break; // was: ~0x0080 
    default:  star[0].measure.photFlags |=  0x00800000;	       // was:  0x0080
      star[0].measure.extNsigma = 100.0;
      break;
  }      
  return (TRUE);
}

int setWISE_mp_flag (Stars *star, char qual) {

  switch (qual) {
    case '0': star[0].measure.photFlags &= ~0x03000000; break; // was: ~0x0800
    case '1': star[0].measure.photFlags |=  0x01000000; break; // was: ~0x0800
    default:  star[0].measure.photFlags |=  0x02000000; break; // was:  0x0800
  }      
  return (TRUE);
}

int setWISE_dup_flag (Stars *star, char qual) {

  switch (qual) {
    case '0': star[0].measure.photFlags &= ~0x0c000000; break; // was: ~0x1000
    case '1': star[0].measure.photFlags |=  0x04000000; break; // was: ~0x1000
    default:  star[0].measure.photFlags |=  0x08000000; break; // was:  0x1000
  }      
  return (TRUE);
}

int setWISE_use_flag (Stars *star, char qual) {

  switch (qual) {
    case '0': star[0].measure.photFlags &= ~0x10000000; break; // was: ~0x2000
    case '1': star[0].measure.photFlags |=  0x10000000; break; // was:  0x2000
    default:  abort();
  }      
  return (TRUE);
}

// unused photFlags:
// 0x0000.8000
// 0x0004.0000
// 0x0008.0000
// 0x2000.0000
// 0x4000.0000
// 0x8000.0000
