/*

  dark -  prepares darks
  Copyright (C) 2015, 2018  Filip Hroch, Masaryk University, Brno, CZ

  Rawtran is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  Rawtran is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with Rawtran.  If not, see <http://www.gnu.org/licenses/>.

*/

#define _DEFAULT_SOURCE

#include "pixmap.h"
#include "rawtran.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fitsio.h>

#include <assert.h>

/* convenience function, darkframe by a RAW photo */
char *darksh(char *fullfilename)
{
  const char *dcraw_command = "dcraw -D -4 -j -t 0 ";
  char *com, *pgmname, *ppmname, *filename;
  int linked;
  int status;

  /* symlink to current directory, if it is somewhere else */
  filename = basename(fullfilename);
  if( strcmp(fullfilename,filename) != 0 ) {
    symlink(fullfilename,filename);
    linked = 1;
  }
  else
    linked = 0;

  com = malloc(strlen(dcraw_command)+strlen(filename)+1);
  strcpy(com,dcraw_command);
  strcat(com,filename);
  status = system(com);
  if( status != 0 ) {
    fprintf(stderr,"Error: Darkframe command `%s' failed.\n",com);
    free(com);
    free(filename);
    return(NULL);
  }
  free(com);
  if( linked )
    unlink(filename);

  /*
    Also .pam file can be created by dcraw.
    The alternative is unimplemented, test data are unavailable.
  */

  pgmname = fitspath(filename,".pgm",0);
  if( access(pgmname,R_OK) != 0 ) {
    /* looks like PPM has been created */

    ppmname = fitspath(filename,".ppm",0);
    if( pixmap_ppm2pgm(ppmname,pgmname) != 0 ) {
      free(pgmname);
      pgmname = NULL;
    }
    unlink(ppmname);
    free(ppmname);
  }

  free(filename);
  return(pgmname);
}



/* convenience function to get darkframe from a FITS file */
char *darkfits(char *filename)
{
  /* converts FITS to PGM */

  fitsfile *fits;
  int status, npixels, naxis, i,j;
  int fpixel = 1;
  float nullval = 0.0;
  long *naxes = NULL;
  float *image = NULL;
  float *fdata;
  unsigned short int *pdata;
  char *pgmname = NULL;
  PIXMAP *pgm;

  /* FITS read */
  status = 0;
  fits_open_image(&fits,filename,READONLY,&status);
  if( status )
    goto finish;

  fits_get_img_dim(fits,&naxis,&status);
  naxes = malloc(naxis*sizeof(long));
  fits_get_img_size(fits,naxis,naxes,&status);
  npixels = 1;
  for( i = 0; i < naxis; i++)
    npixels = npixels*naxes[i];

  image = malloc(npixels*sizeof(float));
  if( image == NULL ) {
    perror("darkfits()");
    goto finish;
  }
  fits_read_img(fits,TFLOAT,fpixel,npixels,&nullval,image,&i,&status);
  fits_close_file(fits, &status);
  if( status )
    goto finish;

  /* form PGM */
  pgm = pixmap_init(naxes[0],naxes[1],65535,1);

  for( j = 0; j < naxes[1]; j++) {
    pdata = pgm->data + naxes[0] * j;
    fdata = image + naxes[0] * (naxes[1] - j - 1);
    for( i = 0; i < naxes[0]; i++) {

      /* As the manual of PGM emphasizes, the gamma function
         must be applied on output data to get correct PGM.
	 I leaves the data untouched in 'linear' form, to be
         compatible with -4 option of dcraw.
      */
      if( fdata[i] >= pgm->maxval )
	pdata[i] = pgm->maxval;
      else if( fdata[i] < 0 )
	pdata[i] = 0;
      else
	pdata[i] = fdata[i] + 0.5;
    }
  }

  pgmname = fitspath(filename,".pgm",0);
  pixmap_save(pgm,pgmname);
  pixmap_free(pgm);

 finish:
  fits_report_error(stderr, status);

  free(naxes);
  free(image);

  if( status ) {
    free(pgmname);
    pgmname = NULL;
  }

  return(pgmname);
}
