/*
 *  Functions for reading tape and work unit headers
 *
 *  This file currently assumes that the reciever is at Arecibo.
 *
 * $Id: readheader.C,v 1.5 2006/11/14 02:19:01 vonkorff Exp $
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <ctype.h>
#include <string.h>

#include "splitparms.h"
#include "splittypes.h"
#include "timecvt.h"
#include "coordcvt.h"

int read_tape_header(unsigned char *buffer, tapeheader_t *header);

/* Read a tape header at buffer into a tapeheader_t */
int read_tape_header(unsigned char *buf, tapeheader_t *header)
{
  static char *receivers[]={"","synthetic","ao1420"};
  int done=0,len;
  int pos=0,i;
  char tmpstr[256];
  double dummy;
  unsigned int firstdata;
  char *buffer=reinterpret_cast<char *>(buf);

  do {
    len=strlen(buffer+pos)+1;
    if (!strncmp(buffer+pos,"EOH=",4)) {
      done=1;
    } else if (!strncmp(buffer+pos,"NAME=",5)) {
       strncpy(tmpstr,buffer+pos+5,36);
       i=0;
       while(!isalnum(tmpstr[i])) i++;
       strncpy(header->name,tmpstr+i,36);
    } else if (!strncmp(buffer+pos,"RCDTYPE=",8)) {
       sscanf(buffer+pos+8,"%d",&(header->rcdtype));
    } else if (!strncmp(buffer+pos,"FRAMESEQ=",9)) {
       sscanf(buffer+pos+9,"%lu",&(header->frameseq));
    } else if (!strncmp(buffer+pos,"DATASEQ=",8)) {
       sscanf(buffer+pos+8,"%lu",&(header->dataseq));
    } else if (!strncmp(buffer+pos,"NUMRINGBUFS=",12)) {
       sscanf(buffer+pos+12,"%d",&(header->numringbufs));
    } else if (!strncmp(buffer+pos,"NUMDISKBUFS=",12)) {
       sscanf(buffer+pos+12,"%d",&(header->numdiskbufs));
    } else if (!strncmp(buffer+pos,"MISSED=",7)) {
       sscanf(buffer+pos+7,"%d",&(header->missed));
    } else if (!strncmp(buffer+pos,"AST=",4)) {
       sscanf(buffer+pos+4,"%2d%3d%2d%2d%2d%2d",
	 &(header->st.y), &(header->st.d), &(header->st.h),
	 &(header->st.m), &(header->st.s), &(header->st.c));
	 header->st.tz=-4.0;
    } else if (!strncmp(buffer+pos,"TELSTR=",7)) {
       sscanf(buffer+pos+7,"%2d%3d%2d%2d%2d %lf %lf %lf",
	 &(header->telstr.st.y), &(header->telstr.st.d), 
	 &(header->telstr.st.h), &(header->telstr.st.m), 
	 &(header->telstr.st.s), &(header->telstr.az), &dummy,
	 &(header->telstr.alt));
	 header->telstr.alt=90.0-header->telstr.alt;
	 header->telstr.st.tz=-4.0;
	 header->telstr.st.c=0;
    } else if (!strncmp(buffer+pos,"RECEIVER=",9)) {
       i=1;
       while ((!strstr(buffer+pos+9,receivers[i])) && (++i<NUM_SRCS)) ;
       if (i==NUM_SRCS) {
          printf("Unknown receiver:");
	  printf("%s",buffer+pos+9);
	  printf("\n");
	  header->source=0;
       } else {
	  header->source=i;
       }
    } else if (!strncmp(buffer+pos,"CENTERFREQ=",11)) {
       sscanf(buffer+pos+11,"%lf",&(header->centerfreq));
       header->centerfreq*=1e6;
    } else if (!strncmp(buffer+pos,"SAMPLERATE=",11)) {
       sscanf(buffer+pos+11,"%lf",&(header->samplerate));
       header->samplerate*=1e6;
    } else if (!strncmp(buffer+pos,"VER=",4)) {
       strncpy(&(header->version[0]),&(buffer[pos+4]),16);
    } else if (len>1) {
       sprintf(tmpstr,"Unknown header field: %40s\n",buffer+pos);
       printf("%s",tmpstr);
    }
    pos+=len;
  } while (!done && (pos<TAPE_HEADER_SIZE));
/* Right now were only doing this for one observatory. (Arecibo)
 * May want to change list later to a switch statement on the reciever 
 */

  st_time_convert(&(header->st));
  header->st.jd-=(float)RECORDER_BUFFER_SAMPLES/header->samplerate/86400;
  st_time_convert(&(header->telstr.st));
  telstr_coord_convert(&(header->telstr),ARECIBO_LAT,ARECIBO_LON);

/*
 * Fix a bug in recorder versions prior to 1.30
 */

 if (atof(&(header->version[0]))<1.299) {
   header->centerfreq-=2.0;
 }

/*
 * Check for blank tape

  firstdata=*(unsigned int *)(buffer+TAPE_HEADER_SIZE);
  if (!(firstdata & 0x55555555) || !(firstdata & 0xaaaaaaaa) ||
       ((firstdata & 0x55555555) == 0x55555555) ||
       ((firstdata & 0xaaaaaaaa) == 0xaaaaaaaa)) {
    header->missed++;
    sprintf(tmpstr,"Possible data problem...data[0] = 0x%x\n",firstdata);
    printf("%s",tmpstr);
  }
*/

  return(1);
}

/* Read a work unit header from a FILE into a wuheader_t */
int read_wu_header(FILE *file, wuheader_t *header) {
/* to be implemented. Don't need it yet. */
  return(0);
}

/* comment out for pulse search */
/* int parse_tape_headers(char *tapebuffer, tapeheader_t *tapeheaders) {
 int i;

 for (i=0;i<TAPE_FRAMES_IN_BUFFER;i++) {
   read_tape_header(tapebuffer+i*TAPE_FRAME_SIZE, &(tapeheaders[i]));
 }
 return(1);
} */

