#include <stdint.h>
#include <fitsio.h>
#include <idl_export.h>

char *get_data(int argc, char *argv[])
{
    fitsfile *fp;
    int status = 0;
    int bitpix, naxis, anynul;
    long naxes[8] = {1,1,1,1,1,1,1,1};
    long npix = 1;
    static char errmsg[81];
    char *filename = (char *) argv[0];
    int *dtype = (int *) argv[1];
    unsigned char *bdat;
    short *hdat;
    unsigned short *uhdat;
    int *idat;
    unsigned int *uidat;
    int64_t *ldat;
    float fnan, *fdat;
    double dnan, *ddat;
    unsigned fnanbits = 0x7fc00000;
    uint64_t dnanbits = 0x7ff8000000000000ull;
    int i;

    fits_open_image(&fp, filename, READONLY, &status);
    fits_get_img_param(fp, 8, &bitpix, &naxis, naxes, &status);

    for (i=0; i<8; ++i)
	npix *= naxes[i];

    switch (*dtype) {
	case 1: 
	    bdat = (unsigned char *) argv[2];
	    fits_read_img(fp, TBYTE, 1, npix, NULL, bdat, &anynul, &status);
	    break;
	case 2: 
	    hdat = (short *) argv[2];
	    fits_read_img(fp, TSHORT, 1, npix, NULL, hdat, &anynul, &status);
	    break;
	case 12: 
	    uhdat = (unsigned short *) argv[2];
	    fits_read_img(fp, TUSHORT, 1, npix, NULL, uhdat, &anynul, &status);
	    break;
	case 3:
	    idat = (int *) argv[2];
	    fits_read_img(fp, TINT, 1, npix, NULL, idat, &anynul, &status);
	    break;
	case 13: 
	    uidat = (unsigned int *) argv[2];
	    fits_read_img(fp, TUINT, 1, npix, NULL, uidat, &anynul, &status);
	    break;
	case 14:
	    ldat = (int64_t *) argv[2];
	    fits_read_img(fp, TLONGLONG, 1, npix, NULL, ldat, &anynul, &status);
	    break;
	case 4:
	    fdat = (float *) argv[2];
	    fnan = *(float *) &fnanbits;
	    fits_read_img(fp, TFLOAT, 1, npix, &fnan, fdat, &anynul, &status);
	    break;
	case 5:
	    ddat = (double *) argv[2];
	    dnan = *(double *) &dnanbits;
	    fits_read_img(fp, TDOUBLE, 1, npix, &dnan, ddat, &anynul, &status);
	    break;
	default:
	    sprintf(errmsg, "Error: unknown data type %d\n", *dtype);
	    return errmsg;
    }

    fits_close_file(fp, &status);

    if (status) {
	fits_get_errstatus(status, errmsg);
	return errmsg;
    } else
	return NULL;
}
