#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <jni.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"
#include "WriteImage.h"

/*int main( void );*/
JNIEXPORT void JNICALL Java_WriteImage_writeimage(JNIEnv *env, jobject obj,jstring jfilename, jint dim1, jint dim2, jint datatype );
void printerror( int status) ;
/*int main()
{
    writeimage("pck.fit", 10,10,1);
    printf("\nWriteImage routine working properly..\n");
    return(0);
}*/
/*--------------------------------------------------------------------------*/
JNIEXPORT void JNICALL Java_WriteImage_writeimage(JNIEnv *env, jobject obj,jstring jfilename, jint dim1, jint dim2, jint datatype )

    /******************************************************/
    /* 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];

    /* initialize FITS image parameters */
           /* name for new FITS file */
    int bitpix   =  USHORT_IMG; /* 16-bit unsigned short pixel values       */
    long naxis    =   2;  /* 2-dimensional image                            */     char buf[128];
    long naxes[2]; 
    const char *filename = (*env)->GetStringUTFChars(env, jfilename, 0);
    naxes[0] = dim1 ;
    naxes[1] = dim2 ;
    /* allocate memory for the whole image */ 
    array[0] = (unsigned short *)malloc( dim1 * dim2
                                        * sizeof( unsigned short ) );
    
   
    


    /* initialize pointers to the start of each row of the image */
    for( ii=1; ii<naxes[1]; ii++ )
      array[ii] = array[ii-1] + dim1;

    remove(filename);               /* Delete old file if it already exists */

    status = 0;         /* initialize status before calling fitsio routines */

    if (fits_create_file(&fptr, filename, &status)) /* create new FITS file */
         printerror( status );           /* call printerror if error occurs */

    /* 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 );          

    /* initialize the values in the image with a linear ramp function */
    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;
        }
    }

    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 ( fits_write_img(fptr, TUSHORT, fpixel, nelements, array[0], &status) )
        printerror( status );
      
    free( array[0] );  /* free previously allocated memory */
    (*env)->ReleaseStringUTFChars(env, jfilename, filename);
    /* 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;
}
