/*===========================================================================
  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 (0 != SCFOPN(filename, FLAMESDATATYPE, 0, F_IMA_TYPE, &fileid) ) {
        /* I could not open the frame */
        return(flames_midas_error(MAREMMA));
    }
    /* is it a 2D image? */
    if (0 != SCDRDI(fileid, "NAXIS", 1, 1, &actvals, &naxis, &unit, &null)) {
        /* 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 (0 != SCDRDD(fileid, "START", 1, naxis, &actvals, start, &unit, &null)) {
        /* something went wrong in SCDRDD */
        return(flames_midas_error(status));
    }
    if (0 != SCDRDD(fileid, "STEP", 1, naxis, &actvals, step, &unit, &null)) {
        /* something went wrong in SCDRDD */
        return(flames_midas_error(status));
    }
    if (0 != SCDRDI(fileid, "NPIX", 1, naxis, &actvals, npix, &unit, &null)) {
        /* 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 (NOERR != allocframe(myframe) ) {
        /* 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 (0 != SCFGET(fileid, 1, myframe->subrows*myframe->subcols,
                    &actsize, (char *)&myframe->frame_array[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 (0 != SCDFND(fileid, "BADPXFRAME", badpxfname, &noelem, &bytelem)) {
        /* 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 (SCFCLO(fileid) != 0) {
        /* problems closing the frame */
        return(flames_midas_error(MAREMMA));
    }
    uves_msg_debug("end initframe");
    return(NOERR);

}

/**@}*/





