# include <stdio.h>
# include <math.h>

# define NZONE 24

int SPDzone[] = {
  0, 75, 450, 375, 1500, 1650, 300, 1425, 1725, 525, 1275, 225, 
  675, 150, 600, 1575, 750, 975, 900, 1050, 1125, 1200, 825, 1350};

int USNOdisk[] = {
  1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10};

# ifndef ALLOCATE
# define ALLOCATE(X,T,S)  \
  X=(T *)malloc((unsigned) ((S)*sizeof(T)));\
  if(X==NULL) \
    { \
      fprintf(stderr,"failed to malloc X\n");\
        exit(0);\
    } 
# define REALLOCATE(X,T,S) \
  X=(T *)realloc(X,(unsigned) ((S)*sizeof(T))); \
  if(X==NULL) \
    { \
       fprintf(stderr,"failed to realloc X\n"); \
       exit(0); \
    }
# endif /* ALLOCATE */

main (argc, argv)
int argc;
char **argv;
{

  long int offset;
  int i, bin, first, last, Nstars, nitems, Nitems, Nbins;
  float hours[100];
  int start[100], number[100], *buffer, *buf;
  char filename[128], c;
  FILE *f;
  float r, b;
  double RA0, DEC0, RA1, DEC1, tmp;
  int iDEC0, iDEC1, iRA0, iRA1;
  int spd, spd_start, spd_end, disk;
  double atof();

  if (argc != 6) {
    fprintf (stderr, "USAGE: addusno RA DEC dRA dDEC (mnt)\n");
    exit (0);
  }

  RA0 = atof (argv[1]);
  DEC0 = atof (argv[2]);
  RA1 = RA0 + atof (argv[3]);
  DEC1 = DEC0 + atof (argv[4]);
  iRA0 = RA0 * 360000.0;
  iRA1 = RA1 * 360000.0;
  iDEC0 = (DEC0 + 90.0) * 360000.0;
  iDEC1 = (DEC1 + 90.0) * 360000.0;
  
  spd_start = (int)((DEC0 + 90) / 7.5) * 75.0;
  tmp = (DEC1 + 90) / 7.5;
  if (tmp > (int)(tmp)) {
    spd_end =   (int)(1 + (DEC1 + 90) / 7.5) * 75.0;
  } else {
    spd_end =   (int)(0 + (DEC1 + 90) / 7.5) * 75.0;
  }

  for (spd = spd_start; spd < spd_end; spd += 75) {
    disk = -1;
    for (i = 0; i < NZONE; i++) {
      if (spd == SPDzone[i]) 
	disk = USNOdisk[i];
    }
    if (disk < 0) {
      fprintf (stderr, "ERROR: can't find cdrom for spd %d\n",  spd);
      exit (0);
    }
    
    /* load accelerator file */
    sprintf (filename, "%s/zone%04d.acc\0", argv[5], spd);
    fprintf (stderr, "reading from %s\n", filename);
    f = fopen (filename, "r");
    if (f == (FILE *) NULL) {
      fprintf (stderr, "can't open file %s, is cdrom %d in drive?\n", filename, disk);
      fprintf (stderr, "press return when ready to continue: ");
      fscanf (stdin, "%c", &c);
      fprintf (stderr, "trying again...\n");
      f = fopen (filename, "r");
      if (f == (FILE *) NULL) {
	fprintf (stderr, "still can't open file %s, is cdrom %d in drive?\n", filename, disk);
	exit (0);  
      }
    }
    for (i = 0; fscanf (f, "%f %d %d", &hours[i], &start[i], &number[i]) != EOF; i++);
    Nbins = i;
    fclose (f);
    
    first = RA0 / 3.75;
    last  = RA1 / 3.75;
    if ((first >= Nbins) || (last >= Nbins)) {
      fprintf (stderr, "RA out of range\n");
      exit (0);
    }
    
    /* open data file */
    sprintf (filename, "%s/zone%04d.cat\0", argv[5], spd);
    fprintf (stderr, "reading from %s\n", filename);
    f = fopen (filename, "r");
    if (f == (FILE *) NULL) {
      fprintf (stderr, "can't open file %s\n", filename);
      exit (0);
    }
    /* advance file pointer to first slice */
    offset = 3*sizeof(int)*(start[first] - 1);
    fseek (f, offset, SEEK_SET);
    /* on each loop, load data from an RA slice of the catalog */
    for (bin = first; bin < last + 1; bin++) {
      Nitems = 3*number[bin];
      ALLOCATE (buffer, int, Nitems);
      nitems = Fread (buffer, sizeof(int), Nitems, f, "int");
      if (nitems != Nitems) {
	fprintf (stderr, "error reading data from file %s (%d, %d, %d)\n", 
		 filename, start[bin], number[bin], nitems);
	exit (0);
      }
      buf = buffer;
      /* print out data from slice within RA and DEC range */
      for (i = 0; i < number[bin]; i++, buf+=3) {
	if ((buf[0] > iRA0) && (buf[0] < iRA1) &&
	    (buf[1] > iDEC0) && (buf[1] < iDEC1)) {
	  r = 0.1*(buf[2] - 1000*((int)(buf[2]/1000)));
	  b = 0.1*((int)(buf[2] - 1000000*((int)(buf[2]/1000000))) / 1000);
	  fprintf (stdout, "%f %f %d %f %f\n", 
		   buf[0]/360000.0, buf[1]/360000.0 - 90.0, buf[2], r, b);
	}
      }
      free (buffer);
    }
    fclose (f);
  }
}


