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


#include "fitsio.h"

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


 fitsfile *fptr;       /* pointer to the FITS file, defined in fitsio.h */
    int status=0, hdunum, hdutype,  nfound, anynull=0, ii, jj;
    long frow, felem, nelem, longnull, dia[6];
    float floatnull, den[6];
    char strnull[10], *name[6] ; 
    int no_of_cols,value, retval, no_of_rows;
    char *comment ;
    char filename[200];     /* name of existing FITS file   */

    char **valchar ;
    char *uintval ;
    int *intval;
    long int *longval ;
    float *floatval ; 
    double *doubleval ;
  

int main(int argc, char *argv[])
{
/*************************************************************************
   This is a simple main program that calls the following routines:
   readtable     - read columns of data from ASCII and binary tables

**************************************************************************/
   if (argc < 3)
    {
      printf("Error in execution of 'viewtable.c'. Either Filename or hdu number is missing..") ;
      exit(0) ;  
    }  

   if (argc > 3)
    {
      printf("Error in execution of 'viewtable.c'. Extra Arguments found.") ;
      exit(0) ;  
    }    
 
  strcpy(filename, argv[1]) ;
  hdunum = (int)atoi(argv[2]) ;
  retval = tabview() ;
  return(0);
}



int  tabview() 
{
   char **ttype, **tform , c, *form ;
   int ret1, ret2,flag ;
 
   fits_open_file(&fptr, filename, READONLY, &status) ;
   if(status)
      {
        printf("report_error_status:%d\n", status) ;
        exit(0) ; 
      }  

   fits_movabs_hdu(fptr, hdunum, &hdutype, &status) ;
   if(status)
      {
        printf("report_error_status:%d\n", status) ;
        exit(0) ; 
      }  

  /* Finding out number of fields in a table.*/
  fits_read_key(fptr, TINT, "TFIELDS",&no_of_cols,comment, &status ) ;
  if(status)
      {
        printf("report_error_status:%d\n", status) ;
        exit(0) ; 
      }  

  fits_read_key(fptr, TINT, "NAXIS2",&no_of_rows,comment, &status );
  if(status)
      {
        printf("report_error_status:%d\n", status) ;
        exit(0) ; 
      }  

  form = (char *)malloc((no_of_cols+2)*sizeof(char)) ;
 
  /* Finding out ttype of each field. */ 
  ttype = (char **)malloc(no_of_cols * sizeof(char *)) ;
  for (ii = 0; ii < no_of_cols; ii++)      /* allocate space for the column labels */
        ttype[ii] = (char *) malloc(FLEN_VALUE);  /* max label length = 69 */
  
 
 
  ret1 =  fits_read_keys_str(fptr, "TTYPE", 1, no_of_cols, ttype, &nfound, &status) ;
  if(status)
      {
        printf("report_error_status:%d\n", status) ;
        exit(0) ; 
      }  

  tform= (char **)malloc(no_of_cols*sizeof(char *)) ;
  for (ii = 0; ii < no_of_cols; ii++)      /* allocate space for the column labels */
        tform[ii] = (char *) malloc(10);  /* max label length = 69 */

   ret2 =  fits_read_keys_str(fptr, "TFORM", 1, no_of_cols, tform, &nfound, &status);
   if(status)
      {
        printf("report_error_status:%d\n", status) ;
        exit(0) ; 
      }  
  
   for(ii = 0; ii < no_of_cols; ii++)
     {
         if (strstr( tform[ii], "I")|| strstr( tform[ii], "i"))
	   form[ii] = 'I' ;
         if (strstr( tform[ii], "F")|| strstr( tform[ii], "f"))
	   form[ii] = 'F' ;
         if (strstr( tform[ii], "E")|| strstr( tform[ii], "e"))
	   form[ii] = 'E' ;
         if (strstr( tform[ii], "A") || strstr( tform[ii], "a"))
	   form[ii] = 'A' ;
         if (strstr( tform[ii], "J")|| strstr( tform[ii], "j"))
	   form[ii] = 'J' ;
        
         if (strstr( tform[ii], "B")|| strstr( tform[ii], "b"))
	   form[ii] = 'B' ;
         if (strstr( tform[ii], "D")|| strstr( tform[ii], "d"))
	   form[ii] = 'D' ;
         if (strstr( tform[ii], "L")|| strstr( tform[ii], "l"))
	   form[ii] = 'L' ;
         if (strstr( tform[ii], "X")|| strstr( tform[ii], "x"))
	   form[ii] = 'X' ;
     } 


 for(ii=0; ii < no_of_cols; ii++)
    free(tform[ii]) ;

 /*printf("<table align=center border=1>") ;  
 printf("%d\n", no_of_cols) ;
 exit(0) ;*/
 
 for(ii=1; ii <= no_of_cols; ii++)
  {
    
       flag = 0 ;
       if (form[ii-1]== 'I')
      {
         intval = (int *)malloc((no_of_rows)*sizeof(int)) ;
        strcpy(strnull, " ") ;
        fits_read_col(fptr, TINT, ii, 1, 1, no_of_rows, strnull,  intval,
                    &anynull, &status);
        if(status)
        {
          printf("report_error_status:%d\n", status) ;
          exit(0) ; 
        }  
        printf("<tr><td bgcolor='brown'><font color='white' face='Helvetica'><b>%s</b></font></td>", ttype[ii-1]) ; 
        for(jj=0; jj < no_of_rows; jj++)
	 {
             printf("<td><font color='brown' face='Helvetica'>%d</font></td>", intval[jj]) ;
         }

        printf("</tr>") ;
        free(intval) ;
       } 

       if (form[ii-1]== 'J')
      {
         longval = (long *)malloc((no_of_rows)*sizeof(long)) ;
        strcpy(strnull, " ") ;
        fits_read_col(fptr, TLONG, ii, 1, 1, no_of_rows, strnull,  longval,
                    &anynull, &status);
        if(status)
        {
          printf("report_error_status:%d\n", status) ;
          exit(0) ; 
        }  
        printf("<tr><td bgcolor='brown'><font color='white' face='Helvetica'><b>%s</b></font></td>", ttype[ii-1]) ; 
        for(jj=0; jj < no_of_rows; jj++)
	 {
             printf("<td><font color='brown' face='Helvetica'>%ld</font></td>", longval[jj]) ;
         }

        printf("</tr>") ;
        free(longval) ;
       } 
      
      if ( form[ii-1]== 'D')
      {
         doubleval = (double *)malloc((no_of_rows)*sizeof(double)) ;
        strcpy(strnull, " ") ;
        fits_read_col(fptr, TDOUBLE, ii, 1, 1, no_of_rows, strnull,  doubleval,
                    &anynull, &status);
         if(status)
         {
            printf("report_error_status:%d\n", status) ;
            exit(0) ; 
         }  
         printf("<tr><td bgcolor='brown'><font color='white' face='Helvetica'><b>%s</b></font></td>", ttype[ii-1]) ; 
        for(jj=0; jj < no_of_rows; jj++)
	{
          printf("<td><font color='brown' face='Helvetica'>%lf</font></td>", doubleval[jj]) ;
           
        }
	printf("</tr>") ;
        free(doubleval) ;
       } 
    
      if ( form[ii-1]== 'E' || form[ii-1]== 'F' )
      {
	  floatval = (float *)malloc((no_of_rows)*sizeof(float)) ;
          strcpy(strnull, " ") ;  
          fits_read_col(fptr, TFLOAT, ii, 1, 1, no_of_rows, strnull,  floatval,
                    &anynull, &status);  
           if(status)
            {
               printf("report_error_status:%d\n", status) ;
               exit(0) ; 
             }  
           printf("<tr><td bgcolor='brown'><font color='white' face='Helvetica'><b>%s</b></font></td>", ttype[ii-1]) ; 
           for(jj=0; jj < no_of_rows; jj++){
              printf("<td><font color='brown' face='Helvetica'>%f</font></td>", floatval[jj]) ;
	   }
           printf("</tr>") ;
	   free(floatval) ;
       }


      if ( form[ii-1]== 'B' || form[ii-1]== 'X' )
      {
	  uintval = (char*)malloc((no_of_rows)*sizeof(char)) ;
          strcpy(strnull, " ") ;

          if ( form[ii-1]== 'B' )
            fits_read_col(fptr, TBYTE, ii, 1, 1, no_of_rows, strnull,  uintval,
                    &anynull, &status); 
          else
            fits_read_col(fptr, TBIT, ii, 1, 1, no_of_rows, strnull,  uintval,
                    &anynull, &status); 
  
           if(status)
            {
               printf("report_error_status:%d\n", status) ;
               exit(0) ; 
             }  
           printf("<tr><td bgcolor='brown'><font color='white' face='Helvetica'><b>%s</b></font></td>", ttype[ii-1]) ; 
           for(jj=0; jj < no_of_rows; jj++){
              printf("<td><font color='brown' face='Helvetica'>%u</font></td>", uintval[jj]) ;
	   }
           printf("</tr>") ;
	   free(uintval) ;
       }

       if ( form[ii-1]== 'A' || form[ii-1]== 'L' )
       {
	 
           valchar=(char**)malloc((no_of_rows)*sizeof(char*));

	   for(jj = 0; jj < no_of_rows; jj++)  
	      valchar[jj] = (char *)malloc(80); 
        
	   if ( form[ii-1]== 'A')
              fits_read_col(fptr, TSTRING, ii, 1, 1, no_of_rows, strnull,  valchar,
                    &anynull, &status);
            else
              fits_read_col(fptr, TLOGICAL, ii, 1, 1, no_of_rows, strnull,  valchar,
                    &anynull, &status);

             if(status)
            {
               printf("report_error_status:%d\n", status) ;
               exit(0) ; 
             } 
            printf("<tr><td bgcolor='brown'><font color='white' face='Helvetica'><b>%s</b></font></td>", ttype[ii-1]) ; 
             
	    for(jj=0; jj < no_of_rows; jj++){
             
              printf("<td><font color='brown' face='Helvetica'>%s</font></td>", valchar[jj]) ;}
           printf("</tr>") ; 
            for(jj=0; jj < no_of_rows; jj++)
                free(valchar[jj]) ;
           
         } 
  }
  printf("</table>") ;

   for(ii=0; ii < no_of_cols; ii++)
    free(ttype[ii]) ;
  free(form) ;
  
 
  printf("\n\n") ; 
  fits_close_file(fptr, &status) ; 
   if(status)
            {
               printf("report_error_status:%d\n", status) ;
               exit(0) ; 
             } 
 
 
  return(0) ;
}


/*--------------------------------------------------------------------------*/
void readtable( char *hduno)

    /************************************************************/
    /* read and print data values from an ASCII or binary table */
    /************************************************************/
{
   
    char  *ttype[3];
  
    for (ii = 0; ii < 3; ii++)      /* allocate space for the column labels */
        ttype[ii] = (char *) malloc(FLEN_VALUE);  /* max label length = 69 */

    for (ii = 0; ii < 6; ii++)    /* allocate space for string column value */
        name[ii] = (char *) malloc(10);   

   
      /* move to the HDU */
    fits_movabs_hdu(fptr, hdunum, &hdutype, &status) ;
       if(status)
            {
               printf("report_error_status:%d\n", status) ;
               exit(0) ; 
             } 

      if (hdutype == ASCII_TBL)
          printf("\n<center>Reading ASCII table in HDU %d:</center>\n",  hdunum);
      else if (hdutype == BINARY_TBL)
          printf("\n<center>Reading binary table in HDU %d:</center>\n", hdunum);
      else
      {
          printf("Error: this HDU is not an ASCII or binary table\n");
          printf("report_error_status:%d\n", status) ;
          exit(0) ;
      }

      /* read the column names from the TTYPEn keywords */
      fits_read_keys_str(fptr, "TTYPE", 1, 3, ttype, &nfound, &status);
      if(status)
            {
               printf("report_error_status:%d\n", status) ;
               exit(0) ; 
             } 
      printf("<table align=center border=1><tr>") ;
      printf("<td><font color=brown size=+2 face=Helvetica>Row</font></td>") ;
      printf("<td><font color=brown size=+2 face=Helvetica>%10s</font></td>",  ttype[0]) ;
      printf("<td><font color=brown size=+2 face=Helvetica> %10s</font></td>", ttype[1]) ;
      printf("<td><font color=brown size=+2 face=Helvetica>%10s</font></td></tr>\n", ttype[2]);

      frow      = 1;
      felem     = 1;
      nelem     = 6;
      strcpy(strnull, " ");
      longnull  = 0;
      floatnull = 0.;

      /*  read the columns */  
      fits_read_col(fptr, TSTRING, 1, frow, felem, nelem, strnull,  name,
                    &anynull, &status);
      if(status)
            {
               printf("report_error_status:%d\n", status) ;
               exit(0) ; 
             } 
      fits_read_col(fptr, TLONG, 2, frow, felem, nelem, &longnull,  dia,
                    &anynull, &status);
      if(status)
            {
               printf("report_error_status:%d\n", status) ;
               exit(0) ; 
             } 
      fits_read_col(fptr, TFLOAT, 3, frow, felem, nelem, &floatnull, den,
                    &anynull, &status);
      if(status)
            {
               printf("report_error_status:%d\n", status) ;
               exit(0) ; 
             } 

      for (ii = 0; ii < 6; ii++)
	{
          printf("<tr>") ;
          printf("<td><font color=brown size=+2 face=Helvetica>%5d</font></td> ", ii + 1);
          printf("<td><font color=brown size=+2 face=Helvetica>%10s</font></td>",  name[ii]) ;
          printf("<td><font color=brown size=+2 face=Helvetica>%10ld</font></td>", dia[ii]) ;
          printf("<td><font color=brown size=+2 face=Helvetica>%10.2f</font></td>\n",den[ii]) ; 
          printf("</tr>") ;
        }
      printf("</table>") ;
    for (ii = 0; ii < 3; ii++)      /* free the memory for the column labels */
        free( ttype[ii] );

    for (ii = 0; ii < 6; ii++)      /* free the memory for the string column */
        free( name[ii] );

    fits_close_file(fptr, &status) ;
    if(status)
            {
               printf("report_error_status:%d\n", status) ;
               exit(0) ; 
             } 

    return;
}


int  allocatemem()
{
  int k=0;
  printf("\n no. of rows = %d",no_of_rows);
 
}
