#include <string.h>
#include <stdio.h>
#include <stdlib.h>


/*
  Every program which uses the CFITSIO interface must include the
  the fitsio.h header file.  This contains the prototypes for all
  the routines and defines the error status values and other symbolic
  constants used in the interface.  
*/
#include "fitsio.h"

int main( int argc, char *argv[] );

void readheader( int argc, char *argv[] );
void printerror( int status);

int main(int argc, char *argv[])
{
/*************************************************************************
   This is a simple main program that calls the following routines:

   
   
    readheader    - read and print the header keywords in every extension
    

**************************************************************************/

   
    readheader(argc, argv);
    printf("\n\n");
    return(0);
}

/*--------------------------------------------------------------------------*/
void readheader ( int argc, char *argv[])

    /**********************************************************************/
    /* Print out all the header keywords in all extensions of a FITS file */
    /**********************************************************************/
{
    fitsfile *fptr;       /* pointer to the FITS file, defined in fitsio.h */

    int status, nkeys, keypos, hdutype, ii, jj, tableflag;
    char filename[80] ;
     /* name of existing FITS file   */
    char card[FLEN_CARD];   /* standard string lengths defined in fitsioc.h */
    char cardline[FLEN_CARD] ;
    char dimension[80]  = "" ;
    char  noofnaxis1[10], dimensionval[10],line[80] ;
    int i, j, noofnaxis, naxiskeyword=0 , naxiscount, dimensionval1,flag=0  ;
    strcpy(filename , argv[1]); 
    status = 0;

    if ( fits_open_file(&fptr, filename, READONLY, &status) ) 
         printerror( status );
    /*    printf("\n\tIndex\tType\t\tExtension\tDimension\n") ;*/
     
    /* attempt to move to next HDU, until we get an EOF error */
    for (ii = 1; !(fits_movabs_hdu(fptr, ii, &hdutype, &status) ); ii++) 
    {  
      naxiskeyword = 0 ; 
      tableflag = 0 ;
      strcpy (dimension, " ")  ;
        if (ii == 1)   /*If it is a primary header. */
	{
	     printf("\n\t0") ;
             printf("\n\tImage") ;
        }
        else
	{
	  printf("\n\t%d", (ii-1)) ; /*print the index of the header. ii -1 because index starts at zero.*/
        }
 
        /* get no. of keywords */
        if (fits_get_hdrpos(fptr, &nkeys, &keypos, &status) )
            printerror( status );

	/* printf("Header listing for HDU #%d:\n", ii); */
        for (jj = 1; jj <= nkeys; jj++)  {
            if ( fits_read_record(fptr, jj, card, &status) )
                 printerror( status );

	 strcpy(cardline, card) ;  
          if (ii > 1) /*It is not a primary HDU. SO read the extension and type from keywords. */
           {

               if (strstr(cardline , "XTENSION"))  /*read the value of keyword XTENSION.*/
                 {
                  
		  
                      i= 0 ;   
                      while (cardline[i]     != '=')
                          i++ ;
                      i++ ;  
                      while (cardline[i] == ' ' || cardline[i] == '\'' ) 
                        i++ ;
                      j = 0 ;
                      while (cardline[i] != ' '  && cardline[i] != '\'')
                      {
		          line[j] = cardline[i] ;
                          i++, j++ ;
		      } 
                      line[j] = '\0' ;
                      printf("\n\t%s", line) ;
                      if (strstr(line, "TABLE"))
		      {
			tableflag = 1 ;
                       
                      }
                 }
	     }

	     if (tableflag == 1) /*In case the extension is a table, retrieve the values of keywords NAXIS2 and TFIELDS  */
	      {
		
                  if (strstr(cardline , "NAXIS2"))  /*read the value of keyword XTENSION.*/
		 {
                  
		 
                      i= 0 ;   
                      while (cardline[i]     != '=')
                          i++ ;
                      i++ ;  
                      while (cardline[i] == ' '  || cardline[i] == '\'') 
                        i++ ;
                      j = 0 ;
                      while (cardline[i] != ' ' && cardline[i] != '\'')
                      {
		          line[j] = cardline[i] ;
                          i++, j++ ;
		      } 
                      line[j] = '\0' ;
                      strcat(dimension , line) ;
                     
		 }

                  if (strstr(cardline , "TFIELDS"))  /*read the value of keyword XTENSION.*/
		 {
                  
		  
                      i= 0 ;   
                      while (cardline[i]     != '=')
                          i++ ;
                      i++ ;  
                      while (cardline[i] == ' '  || cardline[i] == '\'') 
                        i++ ;
                      j = 0 ;
                      while (cardline[i] != ' '  && cardline[i] != '\'')
                      {
		          line[j] = cardline[i] ;
                          i++, j++ ;
		      } 
                      line[j] = '\0' ;
                      strcat(dimension, "*") ;  
                      strcat(dimension , line) ;
                      printf("\n\t%s", dimension) ;
		 }
		 
                 
	      }    
	     else  /* It is an image or some different data. */
	   {  
	    
               if (strstr(cardline , "NAXIS"))
		 {
                   if (naxiskeyword == 0) /*naxiskeyword is used to indicate the first keyword with NAXIS as it's substring*/
		    {
		  
                      i= 0 ;    /*This loop retrieves the value of NAXIS i.e. no of axes*/
                      while (cardline[i]     != '=')
                          i++ ;
                      i++ ;  
                      while (cardline[i] == ' '  || cardline[i] == '\'') 
                        i++ ;
                      j = 0 ;
                      while (cardline[i] != ' '  && cardline[i] != '\'')
                      {
		          noofnaxis1[j] = cardline[i] ;
                          i++, j++ ;
		      } 
                      noofnaxis1[j] = '\0' ;
                    
                      noofnaxis = (int)atoi(noofnaxis1) ; 
                      naxiscount = noofnaxis ;
                      naxiskeyword ++ ;
                    } /* end of if naxiskeyword = 0 */
		   else /* find out the dimensions. */
		      {
                          i= 0 ;  
                          while (cardline[i]     != '=')
                              i++ ;
                          i++ ;  
                          while (cardline[i] == ' '  || cardline[i]== '\'') 
                              i++ ;
                          j = 0 ;
                          while (cardline[i] != ' '  && cardline[i] != '\'')
                         {
		             dimensionval[j] = cardline[i] ;
                             i++, j++ ;
		         } 
                          dimensionval[j] = '\0' ;
                        
		          if (naxiscount == noofnaxis)
			     strcat(dimension , dimensionval) ; 
                          else
                            {
			       strcat(dimension, "*") ;    
                               strcat(dimension , dimensionval) ;
			     }
			  naxiscount-- ;
                          
                       
                      }
		   if (naxiscount == 0)
		     {
                           printf("\n\t%s", dimension) ;
                           flag = 1 ;
		     }
                     
                 } /* end of if cardline & naxis. */            
	   }
        
         if (ii > 1) /*It is not a primary HDU. SO read the extension and type from keywords. */
           {
	     if (strstr(cardline , "EXTNAME"))  /*read the value of keyword EXTNAME.*/
                 {
                  
		  
                      i= 0 ;   
                      while (cardline[i]     != '=')
                          i++ ;
                      i++ ;  
                      while (cardline[i] == ' ' || cardline[i]== '\'') /*to compare with single quote character constant, you have to compare with '''' */
                        i++ ;
                      j = 0 ;
                      while (cardline[i] != ' ' && cardline[i] != '\'')
                      {
		          line[j] = cardline[i] ;
                          i++, j++ ;
		      } 
                      line[j] = '\0' ;
                      printf("\n\t%s", line) ;
                 }
	   }
	 if (ii== 1 && flag == 1)
	 {
	  printf("\n\tprimary") ;  
	   flag++ ;
	 }
        
              
          

            /*printf("%s\n", card); print the keyword card */
        } /* End of for jj loop */
	/*  printf("END\n\n");   terminate listing with END */
    } /* End of for ii loop*/

    if (status == END_OF_FILE)   /* status values are defined in fitsioc.h */
        status = 0;              /* got the expected EOF error; reset = 0  */
    else
       printerror( status );     /* got an unexpected error                */

    if ( fits_close_file(fptr, &status) )
         printerror( status );

    return;
}


void printerror( int status)
{
    /*****************************************************/
    /* Print out cfitsio error messages and exit program */
    /*****************************************************/


    if (status)
    {
       fits_report_error(stderr, status); /* print error report */

       exit( status );    /* terminate the program, returning error status */
    }
    return;
}

