#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 writeimage(char filename[], int dim1, int dim2, int datatype, int flag, char extname[] );
void printerror( int status) ;
int main(int argc, char *argv[])
{
    int dim1, dim2, datatype,flag;
    if(argc != 7)
    {
      printf("\n This Program requires 6 command line arguments..\n") ;
      exit(0) ;
    }
    dim1 = (int)atoi(argv[2]) ;
    dim2 = (int)atoi(argv[3]) ;
    datatype = (int)atoi(argv[4]) ;
    flag = (int)atoi(argv[5] ) ;
    writeimage(argv[1], dim1, dim2, datatype, flag, argv[6]);
    printf("\nWriteImage routine working properly..\n");
    return(0);
}
/*--------------------------------------------------------------------------*/
 void writeimage(char filename[], int dim1, int dim2, int datatype, int flag, char extname[] )

    /******************************************************/
    /* Create a FITS primary array containing a 2-D image */
    /******************************************************/
{
   fitsfile *fptr;       /* pointer to the FITS file, defined in fitsio.h */
    int status, ii, jj;
    long  fpixel, nelements, exposure;
    unsigned short *array[200];
    short *array2[200] ;
    unsigned long *array3[200];
    long *array4[200] ;
    float *array5[200];
    double *array6[200] ;

    /* initialize FITS image parameters */
           /* name for new FITS file */
    int bitpix ; /* 16-bit unsigned short pixel values       */
    long naxis    =   2;  /* 2-dimensional image                            */   
    char buf[128];
    long naxes[2]; 
   
    if (datatype == 1)
      bitpix = USHORT_IMG ;
    
    if (datatype == 2)
      bitpix= SHORT_IMG ;

    if (datatype == 3)
      bitpix = ULONG_IMG ;
    
    if (datatype == 4)
      bitpix= LONG_IMG ;

    if (datatype == 5)
      bitpix = FLOAT_IMG ;
    
    if (datatype == 6)
      bitpix= DOUBLE_IMG ;
    
    naxes[0] = dim1 ;
    naxes[1] = dim2 ;
    /* allocate memory for the whole image */ 
    
    if (datatype == 1) 
       array[0] = (unsigned short *)malloc( dim1 * dim2
                                        * sizeof( unsigned short ) );
    
    if (datatype == 2)
        array2[0] = (short *)malloc( dim1 * dim2
                                        * sizeof( short ) );

   if (datatype == 3) 
       array3[0] = (unsigned long *)malloc( dim1 * dim2
                                        * sizeof( unsigned long ) );
    
    if (datatype == 4)
        array4[0] = (long *)malloc( dim1 * dim2
                                        * sizeof( long ) );

    if (datatype == 5) 
       array5[0] = (float *)malloc( dim1 * dim2
                                        * sizeof(float ) );
    
    if (datatype == 6)
        array6[0] = (double *)malloc( dim1 * dim2
                                        * sizeof( double ) );
    
   /* initialize pointers to the start of each row of the image */
    if(datatype == 1)
      {
	for( ii=1; ii<naxes[1]; ii++ )
	  array[ii] = array[ii-1] + dim1;
      }

    if(datatype == 2)
      {
	for( ii=1; ii<naxes[1]; ii++ )
	  array2[ii] = array2[ii-1] + dim1;
      } 

    if(datatype == 3)
      {
	for( ii=1; ii<naxes[1]; ii++ )
	  array3[ii] = array3[ii-1] + dim1;
      }

    if(datatype == 4)
      {
	for( ii=1; ii<naxes[1]; ii++ )
	  array4[ii] = array4[ii-1] + dim1;
      } 

    if(datatype == 5)
      {
	for( ii=1; ii<naxes[1]; ii++ )
	  array5[ii] = array5[ii-1] + dim1;
      }

    if(datatype == 6)
      {
	for( ii=1; ii<naxes[1]; ii++ )
	  array6[ii] = array6[ii-1] + dim1;
      } 


                /* Delete old file if it already exists */

    status = 0;         /* initialize status before calling fitsio routines */
   
    if (flag == 1)
    {
      remove(filename);
      if (fits_create_file(&fptr, filename, &status)) /* create new FITS file */
       printerror( status );           /* call printerror if error occurs */
    }

    if (flag == 2)
      {
         if ( fits_open_file(&fptr, filename, READWRITE, &status) ) 
           printerror( status );

      } 

    /* write the required keywords for the primary array image.     */
    /* Since bitpix = USHORT_IMG, this will cause cfitsio to create */
    /* a FITS image with BITPIX = 16 (signed short integers) with   */
    /* BSCALE = 1.0 and BZERO = 32768.  This is the convention that */
    /* FITS uses to store unsigned integers.  Note that the BSCALE  */
    /* and BZERO keywords will be automatically written by cfitsio  */
    /* in this case.                                                */

    if ( fits_create_img(fptr,  bitpix, naxis, naxes, &status) )
         printerror( status );          

    if (flag == 2)
      {
        fits_write_key(fptr, TSTRING, "EXTNAME",extname,"Name of the Extension", &status ) ;
      } 

    /* initialize the values in the image with a linear ramp function */
    if (datatype == 1)
    {
      for (jj = 0; jj < naxes[1]; jj++)
	{   for (ii = 0; ii < naxes[0]; ii++) /*naxes with lower index varies more rapidly than naxes with higher index.*/
	  {
              array[jj][ii] = ii + jj;
          }
        }
    }

    if (datatype == 2)
    {
      for (jj = 0; jj < naxes[1]; jj++)
	{  
          for (ii = 0; ii < naxes[0]; ii++) /*naxes with lower index varies more rapidly than naxes with higher index.*/
	  {
              array2[jj][ii] = ii + jj;
          }
     }
    }

     if (datatype == 3)
    {
      for (jj = 0; jj < naxes[1]; jj++)
	{   for (ii = 0; ii < naxes[0]; ii++) /*naxes with lower index varies more rapidly than naxes with higher index.*/
	  {
              array3[jj][ii] = ii + jj;
          }
        }
    }

    if (datatype == 4)
    {
      for (jj = 0; jj < naxes[1]; jj++)
	{  
          for (ii = 0; ii < naxes[0]; ii++) /*naxes with lower index varies more rapidly than naxes with higher index.*/
	  {
              array4[jj][ii] = ii + jj;
          }
     }
    }

     if (datatype == 5)
    {
      for (jj = 0; jj < naxes[1]; jj++)
	{   for (ii = 0; ii < naxes[0]; ii++) /*naxes with lower index varies more rapidly than naxes with higher index.*/
	  {
              array5[jj][ii] = ii + jj;
          }
        }
    }

    if (datatype == 6)
    {
      for (jj = 0; jj < naxes[1]; jj++)
	{  
          for (ii = 0; ii < naxes[0]; ii++) /*naxes with lower index varies more rapidly than naxes with higher index.*/
	  {
              array6[jj][ii] = ii + jj;
          }
     }
    }
    fpixel = 1;                               /* first pixel to write      */
    nelements = naxes[0] * naxes[1];          /* number of pixels to write */

    /* write the array of unsigned integers to the FITS file */
    if(datatype == 1)
    {
      if ( fits_write_img(fptr, TUSHORT, fpixel, nelements, array[0], &status) )
         printerror( status );

     }

    if(datatype == 2)
    {
      if ( fits_write_img(fptr, TSHORT, fpixel, nelements, array2[0], &status) )
         printerror( status );

     }

     if(datatype == 3)
    {
      if ( fits_write_img(fptr, TULONG, fpixel, nelements, array3[0], &status) )
         printerror( status );

     }

    if(datatype == 4)
    {
      if ( fits_write_img(fptr, TLONG, fpixel, nelements, array4[0], &status) )
         printerror( status );
    }

    if(datatype == 5)
    {
      if ( fits_write_img(fptr, TFLOAT, fpixel, nelements, array5[0], &status) )
         printerror( status );

     }

    if(datatype == 6)
    {
      if ( fits_write_img(fptr, TDOUBLE, fpixel, nelements, array6[0], &status) )
         printerror( status );
    }
    
    if(datatype == 1)
      free( array[0] );  /* free previously allocated memory */ 

    if(datatype == 2)
      free( array2[0] );  /* free previously allocated memory */ 

    if(datatype == 3)
      free( array3[0] );  /* free previously allocated memory */ 

    if(datatype == 4)
      free( array4[0] );  /* free previously allocated memory */ 

    if(datatype == 5)
      free( array5[0] );  /* free previously allocated memory */ 

    if(datatype == 6)
      free( array6[0] );  /* free previously allocated memory */ 
 

    
    /* write another optional keyword to the header */
    /* Note that the ADDRESS of the value is passed in the routine */
    exposure = 1500.;
    if ( fits_update_key(fptr, TLONG, "EXPOSURE", &exposure,
         "Total Exposure Time", &status) )
         printerror( status );           

    if ( fits_close_file(fptr, &status) )                /* close the file */
         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;
}
