/*  Hipparcos ASCII CD-ROM load and search routines Release 1.1 June 1997
    William O'Mullane 
    Astrophysics Division, ESTEC, Noordwijk, The Netherlands. 
    See the readme.pdf file for more information */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "utils.h" 
#include "hipdmcom.h" 

int read_hipdmcom (FILE* fp, hipdmcom* entry) 
{
/* Routine to read one record from the datafile into the structure 
 * hipdmcom - this structure should already exist and be alloced
 * in the calling routine. The file should be positioned at the correct
 * place
 */
   char buffer[hipdmcom_REC_LEN+3];
   char delimiter[3]="|\r\0"; 
   char *token;
   if (entry == NULL) 
   {
      fprintf (stderr,"read_hipdmcom NULL pointer for entry\n");
      return (-1);
   } 
	if (fgets ((char *)&buffer,hipdmcom_REC_LEN+2,fp) == NULL)
		return -1;
	token=strtok((char *)&buffer,(char *)&delimiter); 
	read_ccdm(token,&entry->DC1);
	token=strtok(NULL,delimiter);
	strAsINT(token,&entry->DC2);
	token=strtok(NULL,delimiter);
	strcpy((char *)&entry->DC3,token);
	token=strtok(NULL,delimiter);
	strcpy((char *)&entry->DC4,token);
	token=strtok(NULL,delimiter);
	strcpy((char *)&entry->DC5,token);
	token=strtok(NULL,delimiter);
	strcpy((char *)&entry->DC6,token);
	token=strtok(NULL,delimiter);
	strAsINT(token,&entry->DCM1);
	token=strtok(NULL,delimiter);
	strAsINT(token,&entry->DCM2);
	token=strtok(NULL,delimiter);
	strAsINT(token,&entry->DCM3);
	token=strtok(NULL,delimiter);
	strAsINT(token,&entry->DCM4);
	token=strtok(NULL,delimiter);
	strcpy((char *)&entry->DCM5,token);
	token=strtok(NULL,delimiter);
	strAsINT(token,&entry->DCM6);
	token=strtok(NULL,delimiter);
	strcpy((char *)&entry->DC7,token);
	token=strtok(NULL,delimiter);
	strAsINT(token,&entry->DC8);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC9);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC10);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC11);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC12);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC13);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC14);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC15);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC16);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC17);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC18);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC19);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC20);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC21);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC22);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC23);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC24);
	token=strtok(NULL,delimiter);
	strcpy((char *)&entry->DC25,token);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC26);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC27);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC28);
	token=strtok(NULL,delimiter);
	strAsFLOAT(token,&entry->DC29);
	token=strtok(NULL,delimiter);
	strAsINT(token,&entry->DCM7);
	token=strtok(NULL,delimiter);
	strcpy((char *)&entry->DCM8,token);
	if (entry->DC6[0]=='D' || entry->DC6[0]=='W' || 
	    entry->DC6[0]=='X' || entry->DC6[0]=='Z' )
	   search_hd_notes(&entry->DC8,&entry->HDNOTES);
	else
	   entry->HDNOTES.no_entries=0;
	if (entry->DC6[0]=='G' || entry->DC6[0]=='Y' || 
	    entry->DC6[0]=='X' || entry->DC6[0]=='Z' )
	   search_hg_notes(&entry->DC8,&entry->HGNOTES);
	else
	   entry->HGNOTES.no_entries=0;
	if (entry->DC6[0]=='P' || entry->DC6[0]=='W' || 
	    entry->DC6[0]=='Y' || entry->DC6[0]=='Z' )
	   search_hp_notes(&entry->DC8,&entry->HPNOTES);
	else
	   entry->HPNOTES.no_entries=0;
   return 0;
} /* End of read_hipdmcom */ 

FILE* jump_hipdmcom (long recNum) 
{
   static int init=0;
   static FILE* dataFile;
   if (init==0)
   {
      if ((dataFile = fopen ("hipdmcom.dat","r")) == NULL)
      {
         fprintf(stderr,"Could not open hipdmcom.dat \n");
         return NULL;
      }
      init=1;
   }
   if ( fseek (dataFile, (recNum - 1) * hipdmcom_REC_LEN, 0) == 0)
     return dataFile;
   else
     return NULL;
}


int print_hipdmcom (hipdmcom* entry, int decode) 
{
/*  Just print out each attribute with its value  */
   char outputStr[50];
   if (entry == NULL) 
   {
      fprintf (stderr,"print_hipdmcom NULL pointer for entry\n");
      return (-1);
   }

	printf("DC1   : ");
	print_ccdm_cols(&entry->DC1  ,decode);
	printf("           System identifier (CCDM number) \n");
	INTasStr((char *)&outputStr,"%8d",&entry->DC2  );
	printf("DC2   : %s             Solution identifier, S (1 to N_S) \n",outputStr);
	printf("DC3   : %1.1s                    Type of solution (F, I, L)\n",entry->DC3  );
	printf("DC4   : %1.1s                    Source of solution (C, F, N) \n",entry->DC4  );
	printf("DC5   : %1.1s                    Quality of solution (A, B, C, D) \n",entry->DC5  );
	printf("DC6   : %1.1s                    Flag indicating a note at the end of relevant volume \n",entry->DC6  );
	INTasStr((char *)&outputStr,"%8d",&entry->DCM1 );
	printf("DCM1  : %s             Number of solutions pertaining to the system, N_S \n",outputStr);
	INTasStr((char *)&outputStr,"%8d",&entry->DCM2 );
	printf("DCM2  : %s             Number of components in this solution, N_C \n",outputStr);
	INTasStr((char *)&outputStr,"%8d",&entry->DCM3 );
	printf("DCM3  : %s             Number of free parameters in this solution, N_P \n",outputStr);
	INTasStr((char *)&outputStr,"%8d",&entry->DCM4 );
	printf("DCM4  : %s             Number of correlation records in this solution, N_R \n",outputStr);
	printf("DCM5  : %4.4s                 This field contains the word `COMP' \n",entry->DCM5 );
	INTasStr((char *)&outputStr,"%8d",&entry->DCM6 );
	printf("DCM6  : %s             Sequential component number in this solution (1 to N_C) \n",outputStr);
	printf("DC7   : %1.1s                    Component identifier (A, B, C, dots) \n",entry->DC7  );
	INTasStr((char *)&outputStr,"%8d",&entry->DC8  );
	printf("DC8   : %s             Hipparcos Catalogue (HIP) identifier \n",outputStr);
	FLOATasStr((char *)&outputStr,"%12.3f",&entry->DC9  );
	printf("DC9   : %s         Magnitude of component, Hp (mag) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%12.3f",&entry->DC10 );
	printf("DC10  : %s         Standard error of Hp magnitude, sigma_Hp (mag) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%12.3f",&entry->DC11 );
	printf("DC11  : %s         Magnitude of component, B_T (mag) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%12.3f",&entry->DC12 );
	printf("DC12  : %s         Standard error of B_T magnitude, sigma_B_T (mag) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%12.3f",&entry->DC13 );
	printf("DC13  : %s         Magnitude of component, V_T (mag) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%12.3f",&entry->DC14 );
	printf("DC14  : %s         Standard error of V_T magnitude, sigma_B_T (mag) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%17.8f",&entry->DC15 );
	printf("DC15  : %s    Right ascension, alpha (deg) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%17.8f",&entry->DC16 );
	printf("DC16  : %s    Declination, delta (deg) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%11.2f",&entry->DC17 );
	printf("DC17  : %s          Trigonometric parallax, pi (mas) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%11.2f",&entry->DC18 );
	printf("DC18  : %s          Proper motion in right ascension, mu_alpha* (mas/yr) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%11.2f",&entry->DC19 );
	printf("DC19  : %s          Proper motion in declination, mu_delta (mas/yr) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%11.2f",&entry->DC20 );
	printf("DC20  : %s          Standard error of alpha, sigma_alpha* (mas) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%11.2f",&entry->DC21 );
	printf("DC21  : %s          Standard error of delta, sigma_delta (mas) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%11.2f",&entry->DC22 );
	printf("DC22  : %s          Standard error of pi, sigma_pi (mas) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%11.2f",&entry->DC23 );
	printf("DC23  : %s          Standard error of mu_alpha*, sigma_mu_alpha* (mas/yr) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%11.2f",&entry->DC24 );
	printf("DC24  : %s          Standard error of mu_delta, sigma_mu_delta (mas/yr) \n",outputStr);
	printf("DC25  : %1.1s                    Reference component for the data in Fields DC26-29 \n",entry->DC25 );
	FLOATasStr((char *)&outputStr,"%12.3f",&entry->DC26 );
	printf("DC26  : %s         Position angle relative to reference component, theta (deg) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%12.3f",&entry->DC27 );
	printf("DC27  : %s         Separation from reference component, varrho (arcsec) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%12.3f",&entry->DC28 );
	printf("DC28  : %s         Rate of change of theta, dtheta/dt (deg/yr) \n",outputStr);
	FLOATasStr((char *)&outputStr,"%12.3f",&entry->DC29 );
	printf("DC29  : %s         Rate of change of varrho, dvarrho/dt (arcsec/yr) \n",outputStr);
	INTasStr((char *)&outputStr,"%8d",&entry->DCM7 );
	printf("DCM7  : %s             Sequential record number for the  reference component in Field DC25 \n",outputStr);
	printf("DCM8  : %6.6s               Status flags for Hp, alpha, delta, pi, mu_alpha* and mu_delta  1= estimated    0= constrained to the value for the first component \n",entry->DCM8 );
	if (decode == ARRAYVERBOSE || 
	    decode ==(ARRAYVERBOSE+PRINTSUBRECS) || 
	    decode ==(DECODEBITS+ARRAYVERBOSE) || 
	    decode ==(ARRAYVERBOSE+EXTRACTCOEFF) ||
	    decode ==(PRINTSUBRECS+ARRAYVERBOSE+EXTRACTCOEFF) || 
	    decode ==(DECODEBITS+ARRAYVERBOSE+EXTRACTCOEFF) || 
	    decode ==(DECODEBITS+ARRAYVERBOSE+PRINTSUBRECS) || 
	    decode == DOALL )
	   print_array_hg_notes(&entry->HGNOTES,decode);
	else
	{
	   printf("HGNOTES\n");
	   print_array_hg_notes_cols(&entry->HGNOTES,decode);
	}
	if (decode == ARRAYVERBOSE || 
	    decode ==(ARRAYVERBOSE+PRINTSUBRECS) || 
	    decode ==(DECODEBITS+ARRAYVERBOSE) || 
	    decode ==(ARRAYVERBOSE+EXTRACTCOEFF) ||
	    decode ==(PRINTSUBRECS+ARRAYVERBOSE+EXTRACTCOEFF) || 
	    decode ==(DECODEBITS+ARRAYVERBOSE+EXTRACTCOEFF) || 
	    decode ==(DECODEBITS+ARRAYVERBOSE+PRINTSUBRECS) || 
	    decode == DOALL )
	   print_array_hd_notes(&entry->HDNOTES,decode);
	else
	{
	   printf("HDNOTES\n");
	   print_array_hd_notes_cols(&entry->HDNOTES,decode);
	}
	if (decode == ARRAYVERBOSE || 
	    decode ==(ARRAYVERBOSE+PRINTSUBRECS) || 
	    decode ==(DECODEBITS+ARRAYVERBOSE) || 
	    decode ==(ARRAYVERBOSE+EXTRACTCOEFF) ||
	    decode ==(PRINTSUBRECS+ARRAYVERBOSE+EXTRACTCOEFF) || 
	    decode ==(DECODEBITS+ARRAYVERBOSE+EXTRACTCOEFF) || 
	    decode ==(DECODEBITS+ARRAYVERBOSE+PRINTSUBRECS) || 
	    decode == DOALL )
	   print_array_hp_notes(&entry->HPNOTES,decode);
	else
	{
	   printf("HPNOTES\n");
	   print_array_hp_notes_cols(&entry->HPNOTES,decode);
	}
   return (0);
} /* End of print_hipdmcom */

int print_hipdmcom_cols (hipdmcom* entry, int decode) 
{
   char outputStr[200];
/*  print attributes accross screen as in datafile - 
    decode fields depending on the value of decode (values defined in utils.h */
   if (entry == NULL) 
   {
      fprintf (stderr,"print_hipdmcom_cols NULL pointer for entry\n");
      return (-1);
   }

	   print_ccdm_cols(&entry->DC1 ,decode);
	INTasStr((char *)&outputStr,"%1d",&entry->DC2 );
	printf("|%s",outputStr);
	printf("|%1s",entry->DC3 );
	printf("|%1s",entry->DC4 );
	printf("|%1s",entry->DC5 );
	printf("|%1s",entry->DC6 );
	INTasStr((char *)&outputStr,"%1d",&entry->DCM1 );
	printf("|%s",outputStr);
	INTasStr((char *)&outputStr,"%2d",&entry->DCM2 );
	printf("|%s",outputStr);
	INTasStr((char *)&outputStr,"%2d",&entry->DCM3 );
	printf("|%s",outputStr);
	INTasStr((char *)&outputStr,"%2d",&entry->DCM4 );
	printf("|%s",outputStr);
	printf("|%4s",entry->DCM5 );
	INTasStr((char *)&outputStr,"%2d",&entry->DCM6 );
	printf("|%s",outputStr);
	printf("|%1s",entry->DC7 );
	INTasStr((char *)&outputStr,"%6d",&entry->DC8 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%6.3f",&entry->DC9 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%5.3f",&entry->DC10 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%6.3f",&entry->DC11 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%5.3f",&entry->DC12 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%6.3f",&entry->DC13 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%5.3f",&entry->DC14 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%12.8f",&entry->DC15 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%+12.8f",&entry->DC16 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%7.2f",&entry->DC17 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%8.2f",&entry->DC18 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%8.2f",&entry->DC19 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%6.2f",&entry->DC20 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%6.2f",&entry->DC21 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%6.2f",&entry->DC22 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%6.2f",&entry->DC23 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%6.2f",&entry->DC24 );
	printf("|%s",outputStr);
	printf("|%1s",entry->DC25 );
	FLOATasStr((char *)&outputStr,"%7.3f",&entry->DC26 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%8.3f",&entry->DC27 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%+8.3f",&entry->DC28 );
	printf("|%s",outputStr);
	FLOATasStr((char *)&outputStr,"%+6.3f",&entry->DC29 );
	printf("|%s",outputStr);
	INTasStr((char *)&outputStr,"%2d",&entry->DCM7 );
	printf("|%s",outputStr);
	printf("|%24s",entry->DCM8 );
	if ((entry->HGNOTES.no_entries > 0 )&&
	    (decode == PRINTSUBRECS ||
	     decode ==(EXTRACTCOEFF+PRINTSUBRECS) || 
	     decode ==(DECODEBITS+PRINTSUBRECS) ||
	     decode ==(ARRAYVERBOSE+PRINTSUBRECS) ||
	     decode ==(DECODEBITS+EXTRACTCOEFF+PRINTSUBRECS) ||
	     decode ==(ARRAYVERBOSE+DECODEBITS+PRINTSUBRECS) ||
	     decode ==(ARRAYVERBOSE+EXTRACTCOEFF+PRINTSUBRECS) || 
	     decode == DOALL ) ) 
	{
	   printf("\n");
	   print_array_hg_notes_cols(&entry->HGNOTES,decode);
	}
	if ((entry->HDNOTES.no_entries > 0 )&&
	    (decode == PRINTSUBRECS ||
	     decode ==(EXTRACTCOEFF+PRINTSUBRECS) || 
	     decode ==(DECODEBITS+PRINTSUBRECS) ||
	     decode ==(ARRAYVERBOSE+PRINTSUBRECS) ||
	     decode ==(DECODEBITS+EXTRACTCOEFF+PRINTSUBRECS) ||
	     decode ==(ARRAYVERBOSE+DECODEBITS+PRINTSUBRECS) ||
	     decode ==(ARRAYVERBOSE+EXTRACTCOEFF+PRINTSUBRECS) || 
	     decode == DOALL ) ) 
	{
	   printf("\n");
	   print_array_hd_notes_cols(&entry->HDNOTES,decode);
	}
	if ((entry->HPNOTES.no_entries > 0 )&&
	    (decode == PRINTSUBRECS ||
	     decode ==(EXTRACTCOEFF+PRINTSUBRECS) || 
	     decode ==(DECODEBITS+PRINTSUBRECS) ||
	     decode ==(ARRAYVERBOSE+PRINTSUBRECS) ||
	     decode ==(DECODEBITS+EXTRACTCOEFF+PRINTSUBRECS) ||
	     decode ==(ARRAYVERBOSE+DECODEBITS+PRINTSUBRECS) ||
	     decode ==(ARRAYVERBOSE+EXTRACTCOEFF+PRINTSUBRECS) || 
	     decode == DOALL ) ) 
	{
	   printf("\n");
	   print_array_hp_notes_cols(&entry->HPNOTES,decode);
	}
	printf("\r\n");
	return (0);
} /* End of print_hipdmcom_cols */

int print_hipdmcom_header () 
{
/*  print col names accross screen as in datafile */

	printf("DC1       | | | | | | |2 |3 |4 |CM5 |6 | |DC8   |DC9   |DC10 |DC11  |DC12 |DC13  |DC14 |DC15        |DC16        |DC17   |DC18    |DC19    |DC20  |DC21  |DC22  |DC23  |DC24  | |DC26   |DC27    |DC28    |DC29  |7 |DCM8                    \n");
   return (0);
} /* End of print_hipdmcom_headre */


/*  array routines  */ 
int read_array_hipdmcom (FILE* fp,int no_entries, array_hipdmcom* array) 
{
/* Read no_entries entries from the file into the array provided
   use read routine to achive this.
 */
   int i;
   /* First rec already loaded by read_array_hip_dm_c */
   array->no_entries=0;
   for (i=1; i<no_entries; i++)
   {
	if (read_hipdmcom (fp,&array->data[i]) == -1) 
	   break;
	
	if (array_hipdmcom_size == i) 
	{
	    fprintf(stderr," array_hipdmcom not big enough - all elements not loaded\n");
	    break;
	}
   }
   array->no_entries = i;
   return 0;
} /* End of read_array_hipdmcom */

int print_array_hipdmcom_cols (array_hipdmcom* array, int decode) 
{
   int i;
   if (array == NULL) 
   {
      fprintf (stderr,"print_array_hipdmcom NULL pointer for entry\n");
      return (-1);
   }
/*   printf("Array array_hipdmcom contains %d entries :\n",array->no_entries);*/
      if (array->no_entries > 0)
      {
         print_hipdmcom_header();
      }
      for (i=0; i<array->no_entries; i++)
      {
	 print_hipdmcom_cols (&array->data[i],decode) ;
      }
      return (0);
} /* End of print_array_hipdmcom_cols */

int print_array_hipdmcom (array_hipdmcom* array, int decode) 
{
   int i;
   if (array == NULL) 
   {
      fprintf (stderr,"print_array_hipdmcom NULL pointer for entry\n");
      return (-1);
   }
/*   printf("Array array_hipdmcom contains %d entries :\n",array->no_entries);*/
      for (i=0; i<array->no_entries; i++)
      {
	 print_hipdmcom (&array->data[i],decode) ;
      }
      return (0);
} /* End of print_array_hipdmcom */

