# include "addstar.h"
# include "2mass.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 JHK triplet star.  takes a pointer to the start of the line the
// RA and DEC have already been set
int get2mass_3star_full (Stars **star, char *line, int Nmax) {

  char *ptr;
  double dMfull;
  double jd;

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

  ptr = line;		      // ra  (assumed to be already set)
  ptr = next2MASSfield (ptr); // dec (assumed to be already set)
  ptr = next2MASSfield (ptr); // err_maj
  star[0][0].measure.FWx = ShortPixels(strtod (ptr, NULL));
  ptr = next2MASSfield (ptr); // err_min
  star[0][0].measure.FWy = ShortPixels(strtod (ptr, NULL));
  ptr = next2MASSfield (ptr); // err_ang
  star[0][0].measure.theta = ShortPixels(strtod (ptr, NULL));

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

  ptr = next2MASSfield (ptr); // designation (skip)

  ptr = next2MASSfield (ptr); // j_m
  star[0][0].measure.M  = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // j_cmsig
  star[0][0].measure.dM = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // j_msigcom
  dMfull = strtod (ptr, NULL);
  star[0][0].measure.dMcal = sqrt (SQ(dMfull) - SQ(star[0][0].measure.dM));
  ptr = next2MASSfield (ptr); // j_snr (skip)

  ptr = next2MASSfield (ptr); // h_m
  star[1][0].measure.M  = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // h_cmsig
  star[1][0].measure.dM = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // h_msigcom
  dMfull = strtod (ptr, NULL);
  star[1][0].measure.dMcal = sqrt (SQ(dMfull) - SQ(star[1][0].measure.dM));
  ptr = next2MASSfield (ptr); // h_snr (skip)

  ptr = next2MASSfield (ptr); // k_m
  star[2][0].measure.M  = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // k_cmsig
  star[2][0].measure.dM = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // k_msigcom
  dMfull = strtod (ptr, NULL);
  star[2][0].measure.dMcal = sqrt (SQ(dMfull) - SQ(star[2][0].measure.dM));
  ptr = next2MASSfield (ptr); // k_snr (skip)

  star[2][0].measure.photFlags = star[1][0].measure.photFlags = star[0][0].measure.photFlags = 0;

  ptr = next2MASSfield (ptr); // ph_qual
  set2MASS_ph_qual (star[0], ptr[0]);
  set2MASS_ph_qual (star[1], ptr[1]);
  set2MASS_ph_qual (star[2], ptr[2]);

  ptr = next2MASSfield (ptr); // rd_flg
  set2MASS_rd_flag (star[0], ptr[0]);
  set2MASS_rd_flag (star[1], ptr[1]);
  set2MASS_rd_flag (star[2], ptr[2]);

  ptr = next2MASSfield (ptr); // bl_flg
  set2MASS_bl_flag (star[0], ptr[0]);
  set2MASS_bl_flag (star[1], ptr[1]);
  set2MASS_bl_flag (star[2], ptr[2]);

  ptr = next2MASSfield (ptr); // cc_flg
  set2MASS_cc_flag (star[0], ptr[0]);
  set2MASS_cc_flag (star[1], ptr[1]);
  set2MASS_cc_flag (star[2], ptr[2]);

  ptr = next2MASSfield (ptr); // ndet (skip for now, XXX use somehow?)
  ptr = next2MASSfield (ptr); // prox (skip)
  ptr = next2MASSfield (ptr); // pxpa (skip)
  ptr = next2MASSfield (ptr); // pxcntr (skip)

  ptr = next2MASSfield (ptr); // gal_contam (one flag for all filters)
  set2MASS_gal_flag (star[0], ptr[0]);
  set2MASS_gal_flag (star[1], ptr[0]);
  set2MASS_gal_flag (star[2], ptr[0]);

  ptr = next2MASSfield (ptr); // mp_flg (one flag for all filters)
  set2MASS_mp_flag (star[0], ptr[0]);
  set2MASS_mp_flag (star[1], ptr[0]);
  set2MASS_mp_flag (star[2], ptr[0]);

  ptr = next2MASSfield (ptr); // pts_key (skip for now, XXX use somehow?)
  ptr = next2MASSfield (ptr); // hemis (skip)
  ptr = next2MASSfield (ptr); // date (skip)
  ptr = next2MASSfield (ptr); // scan (skip)
  ptr = next2MASSfield (ptr); // glon (skip)
  ptr = next2MASSfield (ptr); // glat (skip)

  ptr = next2MASSfield (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 = next2MASSfield (ptr); // jdate (julian date)
  jd = strtod (ptr, NULL);
  star[0][0].measure.t = ohana_jd_to_sec (jd);
  star[2][0].measure.t = star[1][0].measure.t = star[0][0].measure.t;

  ptr = next2MASSfield (ptr); // j_psfchi
  star[0][0].measure.psfChisq = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // h_psfchi
  star[1][0].measure.psfChisq = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // k_psfchi
  star[2][0].measure.psfChisq = strtod (ptr, NULL);

  ptr = next2MASSfield (ptr); // j_m_stdap
  star[0][0].measure.Map = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // j_msig_stdap (skip?)

  ptr = next2MASSfield (ptr); // h_m_stdap
  star[1][0].measure.Map = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // h_msig_stdap (skip?)

  ptr = next2MASSfield (ptr); // k_m_stdap
  star[2][0].measure.Map = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // k_msig_stdap (skip?)

  ptr = next2MASSfield (ptr); // dist_edge_ns (skip)
  ptr = next2MASSfield (ptr); // dist_edge_ew (skip)
  ptr = next2MASSfield (ptr); // dist_edge_flg (skip)

  ptr = next2MASSfield (ptr); // dup_src (one flag for all filters)
  set2MASS_dup_flag (star[0], ptr[0]);
  set2MASS_dup_flag (star[1], ptr[0]);
  set2MASS_dup_flag (star[2], ptr[0]);

  ptr = next2MASSfield (ptr); // use_src (one flag for all filters)
  set2MASS_use_flag (star[0], ptr[0]);
  set2MASS_use_flag (star[1], ptr[0]);
  set2MASS_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 *next2MASSfield (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 set2MASS_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 'D': star[0].measure.photFlags |= 0x00000008; break; // was: 0x0007
    case 'E': star[0].measure.photFlags |= 0x00000010; break; // was: 0x0003
    case 'F': star[0].measure.photFlags |= 0x00000020; break; // was: 0x0002
    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 set2MASS_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 set2MASS_cc_flag (Stars *star, char qual) {

  switch (qual) {
    case 'p': star[0].measure.photFlags |= 0x00010000; break; // was: 0x0000
    case 'c': star[0].measure.photFlags |= 0x00020000; break; // was: 0x0100
    case 'd': star[0].measure.photFlags |= 0x00040000; break; // was: 0x0200
    case 's': star[0].measure.photFlags |= 0x00080000; break; // was: 0x0300
    case 'b': star[0].measure.photFlags |= 0x00010000; break; // was: 0x0400
    case '0': star[0].measure.photFlags |= 0x00020000; break; // was: 0x0500
    default: 
      fprintf (stderr, "error!\n");
      exit (2);
  }      
  return (TRUE);
}

int set2MASS_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 set2MASS_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 set2MASS_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 set2MASS_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 set2MASS_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
