/*===========================================================================
  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  : readslit.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_readslit.h>
#include <flames_uves.h>
#include <flames_dfs.h>
#include <flames_newmatrix.h>
#include <flames.h>


#if FLAMES_DEBUG
static void dump_slitflat(const allslitflats *slitflat)
{
    if (slitflat == NULL) fprintf(stderr, "NULL\n");
    else {
        fprintf(stderr, "slit = %p\n", slitflat->slit);
        fprintf(stderr, "nflats = %d\n", slitflat->nflats);
        fprintf(stderr, "subrows = %d\n", slitflat->subrows);
        fprintf(stderr, "subcols = %d\n", slitflat->subcols);
        fprintf(stderr, "chiprows = %d\n", slitflat->chiprows);
        fprintf(stderr, "chipcols = %d\n", slitflat->chipcols);
        fprintf(stderr, "subfirstrow = %d\n", slitflat->subfirstrow);
        fprintf(stderr, "subfirstcol = %d\n", slitflat->subfirstcol);

        fprintf(stderr, "substartx = %f\n", slitflat->substartx);
        fprintf(stderr, "substarty = %f\n", slitflat->substarty);
        fprintf(stderr, "substepx = %f\n", slitflat->substepx);
        fprintf(stderr, "substepy = %f\n", slitflat->substepy);
        fprintf(stderr, "chipstartx = %f\n", slitflat->chipstartx);
        fprintf(stderr, "chipstarty = %f\n", slitflat->chipstarty);
        fprintf(stderr, "chipstepx = %f\n", slitflat->chipstepx);
        fprintf(stderr, "chipstepy = %f\n", slitflat->chipstepy);

        fprintf(stderr, "chipchoice = %c\n", slitflat->chipchoice);

        fprintf(stderr, "ron = %f\n", slitflat->ron);
        fprintf(stderr, "gain = %f\n", slitflat->gain);

        fprintf(stderr, "firstorder = %d\n", slitflat->firstorder);
        fprintf(stderr, "lastorder = %d\n", slitflat->lastorder);

        fprintf(stderr, "tab_io_oshift = %d\n", slitflat->tab_io_oshift);

        fprintf(stderr, "lowbound = %p\n", slitflat->lowbound);
        fprintf(stderr, "highbound = %p\n", slitflat->highbound);
        fprintf(stderr, "normfactor = %p\n", slitflat->normfactor);
        fprintf(stderr, "goodx = %p\n", slitflat->goodx);
    }
    return;
}
#endif

flames_err readslit(allslitflats *slitflats, int32_t iframe, 
            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;
  char messagebuffer[CATREC_LEN+1];
  double start[2]={0,0};
  double step[2]={0,0};
  int npix[2]={0,0};
  char chipchoice='\0';
  double ron=0;
  double gain=0;
  double yshift=0;
  double halfwidth=0;

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

  strcpy(slitflats->slit[iframe].framename, filename);
  /* 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=SCDRDC(fileid, "CHIPCHOICE", 1, 1, 1, &actvals, &chipchoice, 
             &unit, &null)) != 0) {
    /* something went wrong in SCDRDI */
    return(status);
  }
  if ((status=SCDRDD(fileid, "RON", 1, naxis, &actvals, &ron, &unit, 
             &null)) != 0) {
    /* something went wrong in SCDRDD */
    return(status);
  }
  if ((status=SCDRDD(fileid, "GAIN", 1, naxis, &actvals, &gain, &unit, 
             &null)) != 0) {
    /* something went wrong in SCDRDD */
    return(status);
  }
  if ((status=SCDRDD(fileid, "YSHIFT", 1, naxis, &actvals, &yshift, &unit, 
             &null)) != 0) {
    /* something went wrong in SCDRDD */
    return(status);
  }
  if ((status=SCDRDD(fileid, "HALFWIDTH", 1, naxis, &actvals, &halfwidth, 
             &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);
  }
  */

  /* compare the scalars with those already in slitflats */
  if (slitflats->substartx != start[0] ||
      slitflats->substarty != start[1] ||
      slitflats->substepx != step[0] ||
      slitflats->substepy != step[1] ||
      slitflats->subcols != (int32_t) npix[0] ||
      slitflats->subrows != (int32_t) npix[1] ||
      slitflats->chipchoice != chipchoice ||
      slitflats->ron != ron ||
      slitflats->gain != gain) {
    /* descriptors mismatch */
    SCTPUT("Descriptors mismatch");
    return(MAREMMA);
  }

  /* copy relevant scalars to current slit */
  slitflats->slit[iframe].yshift = yshift;
  slitflats->slit[iframe].halfwidth = halfwidth;

  /* now read the actual frame itself */
  if ((status = SCFGET(fileid, 1, slitflats->subrows*slitflats->subcols, 
               &actsize, 
               (char *)&slitflats->slit[iframe].data[0][0])) != 0) {
    /* something went wrong in SCFGET */
    return(status);
  }
  /* did I get all the elements I asked for? */
  if(actsize != slitflats->subrows*slitflats->subcols) {
    /* some elements were lost: protest... */
    return(MAREMMA);
  }

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

#if FLAMES_DEBUG
  fprintf(stderr, "Got this flat:\n");
  dump_slitflat(slitflats);
#endif


  return(NOERR);

}
