/*===========================================================================
  Copyright (C) 2001 European Southern Observatory (ESO)
 
  This program 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 2 of 
  the License, or (at your option) any later version.
 
  This program 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 this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding concerning ESO-MIDAS should be addressed as follows:
  Internet e-mail: midas@eso.org
  Postal address: European Southern Observatory
  Data Management Division 
  Karl-Schwarzschild-Strasse 2
  D 85748 Garching bei Muenchen 
  GERMANY
  ===========================================================================*/
/*-------------------------------------------------------------------------*/
/**
 * @defgroup flames_initframe   Substep: initialize frm  
 *
 */
/*-------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------
  Includes
  --------------------------------------------------------------------------*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <flames_midas_def.h>
#include <flames_uves.h>
#include <flames_initframe.h>
#include <flames_dfs.h>
#include <flames_newmatrix.h>
#include <flames_allocframe.h>
#include <flames_mergebadpixels.h>
#include <uves_msg.h>

/**@{*/

/*---------------------------------------------------------------------------
  Implementation
  ---------------------------------------------------------------------------*/
/**
   @name  flames_checksize()  
   @short initialize frm
   @author G. Mulas  -  ITAL_FLAMES Consortium. Ported to CPL by A. Modigliani

   @param myframe 
   @param filename 
   @param template
   @param satfilterswitch 
   @param satthres


   @return success or failure code

   DRS Functions called:          
   none                                         
                                                                         
   Pseudocode:                                                             

   @note
*/

flames_err 
initframe(
          flames_frame *myframe, 
          char *filename, 
          flames_frame *template, 
          char satfilterswitch, 
          frame_data *satthres)
{

  int status=0;
  int fileid=0;
  int actvals=0;
  int naxis=0;
  int unit=0;
  int null=0;
  int actsize=0;
  int noelem=0;
  int bytelem=0;
  int32_t ix=0;
  int32_t iyixlimit=0;
  char badpxfname[CATREC_LEN+1];
  double start[2]={0,0};
  double step[2]={0,0};
  int npix[2]={0,0};
  char* fixed_name=NULL;

  frame_data *fdvecbuf1=0;
  frame_data *fdvecbuf2=0;
  frame_mask *fmvecbuf1=0;
  frame_mask *fmvecbuf2=0;

  memset(badpxfname, '\0', CATREC_LEN+1);

  /* try to open the frame */
  if ((status = SCFOPN(filename, FLAMESDATATYPE, 0, F_IMA_TYPE, &fileid)) 
      != 0) {
    /* I could not open the frame */
    return(flames_midas_error(MAREMMA));
  }
  /* is it a 2D image? */
  if ((status = SCDRDI(fileid, "NAXIS", 1, 1, &actvals, &naxis, &unit, 
		       &null)) != 0) {
    /* something went wrong in SCDRDI */
    return(flames_midas_error(MAREMMA));
  }
  if (naxis != 2) {
    /* wrong dimensions, wrong frames, I suppose... */
    return(flames_midas_error(MAREMMA));
  }

  /* read all relevant scalar descriptors */
  /* read start, step and npix from the frame */
  if ((status=SCDRDD(fileid, "START", 1, naxis, &actvals, start, &unit, 
		     &null)) != 0) {
    /* something went wrong in SCDRDD */
    return(flames_midas_error(status));
  }
  if ((status=SCDRDD(fileid, "STEP", 1, naxis, &actvals, step, &unit, 
		     &null)) != 0) {
    /* something went wrong in SCDRDD */
    return(flames_midas_error(status));
  }
  if ((status=SCDRDI(fileid, "NPIX", 1, naxis, &actvals, npix, &unit, 
		     &null)) != 0) {
    /* something went wrong in SCDRDI */
    return(flames_midas_error(status));
  }
  /* compare start, step and npix of the current frame with those of 
     the template */
  if ((start[0] != template->substartx) || 
      (start[1] != template->substarty) ||
      (step[0] != template->substepx) || 
      (step[1] != template->substepy) || 
      (npix[0] != template->subcols) ||
      (npix[1] != template->subrows)) {
    /* frame size mismatch! */
    return(flames_midas_error(MAREMMA));
  }
  
  /* the frames match, copy the scalars from the template */
  myframe->subcols = template->subcols;
  myframe->subrows = template->subrows;
  myframe->subfirstrow = 0;
  myframe->subfirstcol = 0;
  myframe->maxfibres = template->maxfibres;
  myframe->substartx = template->substartx;
  myframe->substarty = template->substarty;
  myframe->substepx = template->substepx;
  myframe->substepy = template->substepy;
  myframe->chipchoice = template->chipchoice;
  myframe->ron = template->ron;
  myframe->gain = template->gain;
  myframe->nflats = 0;
  myframe->firstorder = template->firstorder;
  myframe->lastorder = template->lastorder;
  myframe->tab_io_oshift = template->tab_io_oshift;
  /* unless I have a better option, initialise back.Window_Number to 0 to
     avoid problems. Pasquale, any comments? */
  myframe->back.Window_Number = 0;
  /* allocate dynamic submembers here */
  if ((status = allocframe(myframe)) != NOERR) {
    /* allocframe returned an error */
    return(flames_midas_error(MAREMMA));
  }

  iyixlimit = (myframe->subrows*myframe->subcols)-1;
  fdvecbuf1 = myframe->frame_array[0];
  fdvecbuf2 = myframe->frame_sigma[0];
  fmvecbuf1 = myframe->badpixel[0];
  fmvecbuf2 = template->badpixel[0];

  /* now read the actual frame itself */
  if ((status = SCFGET(fileid, 1, myframe->subrows*myframe->subcols, 
		       &actsize, (char *)&myframe->frame_array[0][0])) != 0) {
    /* something went wrong in SCFGET */
    return(flames_midas_error(status));
  }
  /* did I get all the elements I asked for? */
  if(actsize != myframe->subrows*myframe->subcols) {
    /* some elements were lost: protest... */
    return(flames_midas_error(MAREMMA));
  }
  /* copy the bad pixel mask from the template */
  for(ix=0; ix<=iyixlimit; ix++) {
    fmvecbuf1[ix] = fmvecbuf2[ix];
  }
  /* should I look for and mask saturated pixels? */
  if (satfilterswitch == TRUE) {
    /* compare the pixel values with the cut levels */
    for (ix=0; ix<=iyixlimit; ix++) {
      if ((fdvecbuf1[ix]<satthres[0]) || (fdvecbuf1[ix]>satthres[1])) {
	/* this pixel is either saturated or contains garbage anyway, 
	   mark it as bad */
	fmvecbuf1[ix] = 1;
      }
    }
  }

  /* is there a frame-specific bad pixel mask to be used? */
  if ((status = SCDFND(fileid, "BADPXFRAME", badpxfname, 
		       &noelem, &bytelem)) != 0) {
    /* I could not find any information about the descriptor, bad... */
    return(flames_midas_error(MAREMMA));
  }
  switch(badpxfname[0]) {
  case ' ':
    uves_msg_warning("the descriptor is undefined, no frame-specific bad pixel mask");
    /* the descriptor is undefined, no frame-specific bad pixel mask */
    break;
  case 'C':
    uves_msg_warning("this descriptor does contain a string, read it");
    /* this descriptor does contain a string, read it */
    if ((status = SCDGETC(fileid, "BADPXFRAME", 1, 79, 
			  &actvals, badpxfname)) != 0) {
      /* I could not read the descriptor, should never happen... */
      return(flames_midas_error(MAREMMA));
    }

    //AMo: we fix possible .bdf estention
    fixed_name=flames_fix_estention(badpxfname);
    strcpy(badpxfname,fixed_name);
    cpl_free(fixed_name);

    uves_msg_warning("try to merge the bad pixels in badpxfname %s",badpxfname);
    /* try to merge the bad pixels in badpxfname */
    if ((status = mergebadpixels(myframe, badpxfname)) 
	!= NOERR) {
      /* something wrong happened, bail out */
      return(flames_midas_error(status));
    }
    break;
  default:
    uves_msg_warning("this descriptor exists but it cannot contain a filename");
    /* this descriptor exists but it cannot contain a filename */
    SCTPUT("The BADPXFRAME descriptor is of the wrong type");
    break;
  }
  /* compute the variance of the frame */
  uves_msg("compute the variance of the frame");
  for (ix=0; ix<=iyixlimit; ix++) {
    if(fmvecbuf1[ix] == 0) {
      /* this is a good pixel */
      if(fdvecbuf1[ix] > 0) {
	fdvecbuf2[ix] = 
	  myframe->gain*(fdvecbuf1[ix]+myframe->gain*myframe->ron);
      }
      else {
	fdvecbuf2[ix] = myframe->gain*myframe->gain*myframe->ron;
      }
    }
  }
  /* close the frame */
  if ((status = SCFCLO(fileid)) != 0) {
    /* problems closing the frame */
    return(flames_midas_error(MAREMMA));
  }
  uves_msg_debug("end initframe");
  return(NOERR);

}

/**@}*/





