/*===========================================================================
  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
===========================================================================*/
/* Program  : readframe.c                                                  */
/* Author   : G. Mulas  -  ITAL_FLAMES Consortium                          */
/* Date     :                                                              */
/*                                                                         */
/* Purpose  : Missing                                                      */
/*                                                                         */
/*                                                                         */
/* Input:  see interface                                                   */ 
/*                                                                      */
/* Output:                                                              */
/*                                                                         */
/* DRS Functions called:                                                   */
/* none                                                                    */ 
/*                                                                         */ 
/* Pseudocode:                                                             */
/* Missing                                                                 */ 
/*                                                                         */ 
/* Version  :                                                              */
/* Last modification date: 2002/08/05                                      */
/* Who     When        Why                Where                            */
/* AMo     02-08-05   Add header         header                            */
/*-------------------------------------------------------------------------*/

#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_readframe.h>
#include <flames_newmatrix.h>
#include <flames_allocframe.h>


flames_err readframe(flames_frame *myframe, char *filename)
{
    int status=0;
    int actvals=0;
    int naxis=0;
    int unit=0;
    int null=0;
    int actsize=0;
    int fileid=0;
    int badid=0;
    int sigmaid=0;
    int i=0;
    char messagebuffer[CATREC_LEN+1];
    int *fibremask=0;
    double start[2]={0,0};
    double step[2]={0,0};
    int npix[2]={0,0};
    int maxfibres=0;
    int firstorder=0;
    int lastorder=0;
    int tab_io_oshift=0;
    int nflats=0;
    char chipchoice=0;
    double ron=0;
    double gain=0;

    memset(messagebuffer, '\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(MAREMMA);
    }
    /* is it a 2D image? */
    if ((status = SCDRDI(fileid, "NAXIS", 1, 1, &actvals, &naxis, &unit,
                    &null)) != 0) {
        /* something went wrong in SCDRDI */
        return(MAREMMA);
    }
    if (naxis != 2) {
        /* wrong dimensions, wrong frames, I suppose... */
        return(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(status);
    }
    if ((status=SCDRDD(fileid, "STEP", 1, naxis, &actvals, step, &unit,
                    &null)) != 0) {
        /* something went wrong in SCDRDD */
        return(status);
    }
    if ((status=SCDRDI(fileid, "NPIX", 1, naxis, &actvals, npix, &unit,
                    &null)) != 0) {
        /* something went wrong in SCDRDI */
        return(status);
    }
    if ((status=SCDRDI(fileid, "MAXFIBRES", 1, 1, &actvals, &maxfibres, &unit,
                    &null)) != 0) {
        /* something went wrong in SCDRDI */
        return(status);
    }
    if ((status=SCDRDI(fileid, "NFLATS", 1, 1, &actvals, &nflats, &unit,
                    &null)) != 0) {
        /* something went wrong in SCDRDI */
        return(status);
    }
    if ((status=SCDRDC(fileid, "CHIPCHOICE", 1, 1, 1, &actvals, &chipchoice,
                    &unit, &null)) != 0) {
        /* something went wrong in SCDRDI */
        return(status);
    }
    if ((status=SCDRDD(fileid, "RON", 1, 1, &actvals, &ron, &unit,
                    &null)) != 0) {
        /* something went wrong in SCDRDD */
        return(status);
    }
    if ((status=SCDRDD(fileid, "GAIN", 1, 1, &actvals, &gain, &unit,
                    &null)) != 0) {
        /* something went wrong in SCDRDD */
        return(status);
    }
    if ((status=SCDRDI(fileid, "ORDERLIM", 1, 1, &actvals, &firstorder, &unit,
                    &null)) != 0) {
        /* something went wrong in SCDRDI */
        return(status);
    }
    if ((status=SCDRDI(fileid, "ORDERLIM", 2, 1, &actvals, &lastorder, &unit,
                    &null)) != 0) {
        /* something went wrong in SCDRDI */
        return(status);
    }
    if ((status=SCDRDI(fileid, "TAB_IN_OUT_OSHIFT", 1, 1, &actvals,
                    &tab_io_oshift, &unit, &null)) != 0) {
        /* something went wrong in SCDRDI */
        return(status);
    }

    myframe->substartx = start[0];
    myframe->substarty = start[1];
    myframe->substepx = step[0];
    myframe->substepy = step[1];
    myframe->subcols = (int32_t) npix[0];
    myframe->subrows = (int32_t) npix[1];
    myframe->maxfibres = maxfibres;
    myframe->nflats = (int32_t) nflats;
    myframe->chipchoice = chipchoice;
    myframe->ron = ron;
    myframe->gain = gain;
    myframe->firstorder = firstorder;
    myframe->lastorder = lastorder;
    myframe->tab_io_oshift = tab_io_oshift;

    /* allocate dynamic submembers here */
    if ((status = allocframe(myframe)) != NOERR) {
        /* allocframe returned an error */
        return(MAREMMA);
    }

    /* allocate the fibremask buffer */
    fibremask = ivector(0, maxfibres-1);
    /* read the fibremask */
    if ((status=SCDRDI(fileid, "FIBREMASK", 1, myframe->maxfibres, &actvals,
                    fibremask, &unit, &null)) != 0) {
        /* something went wrong in SCDRDI */
        return(status);
    }
    for (i=0; i<=myframe->maxfibres-1; i++) {
        myframe->fibremask[i] = (char) fibremask[i];
    }
    /* free the fibremask buffer */
    free_ivector(fibremask, 0, (int32_t)maxfibres-1);

    /* copy the frame name */
    strcpy(myframe->framename, filename);

    /* 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(status);
    }
    /* did I get all the elements I asked for? */
    if(actsize != myframe->subrows*myframe->subcols) {
        /* some elements were lost: protest... */
        return(MAREMMA);
    }

    /* are yshifts defined already? */
    if (myframe->nflats > 0) {
        /* nflats is defined > 0, read yshifts */
        if ((status = SCDRDD(fileid, "YSHIFT", 1, myframe->nflats, &actvals,
                        myframe->yshift, &unit, &null)) != 0) {
            /* something went wrong in SCDRDD */
            return(status);
        }
    }

    /* when read by this function, a frame is assumed to have all the
     related members defined and existing, such as bad pixel mask and
     variance frame */
    /* read the name of the sigma frame */
    if ((status = SCDGETC(fileid, "SIGMAFRAME", 1, 79,
                    &actvals, myframe->sigmaname)) != 0) {
        /* I could not read the descriptor, should never happen... */
        return(MAREMMA);
    }
    /* read the name of the badpixel frame */
    if ((status = SCDGETC(fileid, "BADPXFRAME", 1, 79,
                    &actvals, myframe->badname)) != 0) {
        /* I could not read the descriptor, should never happen... */
        return(MAREMMA);
    }

    /* close the data frame */
    if ((status = SCFCLO(fileid)) != 0) {
        /* problems closing the sigma frame */
        return(MAREMMA);
    }

    /* open the sigma frame */
    if ((status = SCFOPN(myframe->sigmaname, FLAMESDATATYPE, 0, F_IMA_TYPE,
                    &sigmaid)) != 0) {
        /* I could not open the file: protest... */
        sprintf(messagebuffer, "File %s could not be opened",
                        myframe->sigmaname);
        SCTPUT(messagebuffer);
        return(MAREMMA);
    }
    /* read the sigma frame itself */
    if ((status = SCFGET(sigmaid, 1,
                    myframe->subrows*myframe->subcols,
                    &actsize, (char *)myframe->frame_sigma[0]))
                    != 0) {
        /* something went wrong in SCFGET */
        sprintf(messagebuffer, "Could not read the file %s as a sigma frame",
                        myframe->sigmaname);
        SCTPUT(messagebuffer);
        return(MAREMMA);
    }
    /* did I get all the elements I asked for? */
    if(actsize != myframe->subrows*myframe->subcols) {
        /* some elements were lost: protest... */
        sprintf(messagebuffer, "Could not completely read file %s as a sigma frame",
                        myframe->sigmaname);
        SCTPUT(messagebuffer);
        return(MAREMMA);
    }
    /* close the sigma frame */
    if ((status = SCFCLO(sigmaid)) != 0) {
        /* problems closing the sigma frame */
        return(MAREMMA);
    }

    /* open the bad pixel frame */
    if ((status = SCFOPN(myframe->badname, D_I1_FORMAT, 0, F_IMA_TYPE,
                    &badid)) != 0) {
        /* I could not open the file: protest... */
        sprintf(messagebuffer, "File %s could not be opened",
                        myframe->badname);
        SCTPUT(messagebuffer);
        return(MAREMMA);
    }
    /* read the badpixel frame itself */
    if ((status = SCFGET(badid, 1,
                    myframe->subrows*myframe->subcols,
                    &actsize, (char *)myframe->badpixel[0]))
                    != 0) {
        /* something went wrong in SCFGET */
        sprintf(messagebuffer, "Could not read the file %s as a bad pixel mask",
                        myframe->badname);
        SCTPUT(messagebuffer);
        return(MAREMMA);
    }
    /* did I get all the elements I asked for? */
    if(actsize != myframe->subrows*myframe->subcols) {
        /* some elements were lost: protest... */
        sprintf(messagebuffer, "Could not completely read file %s as a bad pixel mask",
                        myframe->badname);
        SCTPUT(messagebuffer);
        return(MAREMMA);
    }
    /* close the bad pixel frame */
    if ((status = SCFCLO(badid)) != 0) {
        /* problems closing the sigma frame */
        return(MAREMMA);
    }

    return(NOERR);

}
