# include "addstar.h"
# include "2mass.h"

// 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].fx = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // err_min
  star[0][0].fy = strtod (ptr, NULL);
  ptr = next2MASSfield (ptr); // err_ang
  star[0][0].df = strtod (ptr, NULL);

  star[2][0].fx = star[2][0].fx = star[0][0].fx;
  star[2][0].fy = star[2][0].fy = star[0][0].fy;
  star[2][0].df = star[2][0].df = star[0][0].df;

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

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

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

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

  star[2][0].flags = star[1][0].flags = star[0][0].flags = 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].X = strtod (ptr, NULL);
  star[2][0].X = star[1][0].X = star[0][0].X;

  ptr = next2MASSfield (ptr); // jdate (julian date)
  jd = strtod (ptr, NULL);
  star[0][0].t = ohana_jd_to_sec (jd);
  star[2][0].t = star[1][0].t = star[0][0].t;

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

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

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

  ptr = next2MASSfield (ptr); // k_m_stdap
  star[2][0].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].code  = TM_J;
  star[0][0].found = -1;
  star[0][0].detID   = 0;
  star[0][0].imageID = 0;

  star[1][0].code  = TM_H;
  star[1][0].found = -1;
  star[1][0].detID   = 0;
  star[1][0].imageID = 0;

  star[2][0].code  = TM_K;
  star[2][0].found = -1;
  star[2][0].detID   = 0;
  star[2][0].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 'X': star[0].flags |= 0x0000; break;
    case 'U': star[0].flags |= 0x0001; break;
    case 'F': star[0].flags |= 0x0002; break;
    case 'E': star[0].flags |= 0x0003; break;
    case 'A': star[0].flags |= 0x0004; break;
    case 'B': star[0].flags |= 0x0005; break;
    case 'C': star[0].flags |= 0x0006; break;
    case 'D': star[0].flags |= 0x0007; break;
    default: 
      fprintf (stderr, "error!\n");
      exit (2);
  }      
  return (TRUE);
}

int set2MASS_rd_flag (Stars *star, char qual) {

  switch (qual) {
    case '0': star[0].flags |= 0x0000; break;
    case '1': star[0].flags |= 0x0010; break;
    case '2': star[0].flags |= 0x0020; break;
    case '3': star[0].flags |= 0x0030; break;
    case '4': star[0].flags |= 0x0040; break;
    case '6': star[0].flags |= 0x0050; break;
    case '9': star[0].flags |= 0x0060; break;
    default: 
      fprintf (stderr, "error!\n");
      exit (2);
  }      
  return (TRUE);
}

int set2MASS_cc_flag (Stars *star, char qual) {

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

int set2MASS_bl_flag (Stars *star, char qual) {

  switch (qual) {
    case '0': star[0].flags &= ~0x0008; break;
    case '1': star[0].flags &= ~0x0008; break;
    default:  star[0].flags |=  0x0008; break;
  }      
  return (TRUE);
}

int set2MASS_gal_flag (Stars *star, char qual) {

  switch (qual) {
    case '0': star[0].flags &= ~0x0080; break;
    case '1': star[0].flags &= ~0x0080; break;
    default:  
      star[0].flags |= 0x0080; 
      star[0].extNsigma = 100.0;
      break;
  }      
  return (TRUE);
}

int set2MASS_mp_flag (Stars *star, char qual) {

  switch (qual) {
    case '0': star[0].flags &= ~0x0800; break;
    case '1': star[0].flags &= ~0x0800; break;
    default:  star[0].flags |=  0x0800; break;
  }      
  return (TRUE);
}

int set2MASS_dup_flag (Stars *star, char qual) {

  switch (qual) {
    case '0': star[0].flags &= ~0x1000; break;
    case '1': star[0].flags &= ~0x1000; break;
    default:  star[0].flags |=  0x1000; break;
  }      
  return (TRUE);
}

int set2MASS_use_flag (Stars *star, char qual) {

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

