/*
 * This file is part of the ESO SINFONI Pipeline
 * Copyright (C) 2004,2005 European Southern Observatory
 *
 * 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, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
 */
/*----------------------------------------------------------------------------

   File name    :   sinfo_dark_ini_by_cpl.c
   Author       :   Andrea Modigliani
   Created on   :   May 18, 2004
   Description  :   sinfo_dark cpl input file handling for SPIFFI
 ---------------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
/*---------------------------------------------------------------------------
                                Includes
 ---------------------------------------------------------------------------*/
#include <string.h>
#include "sinfo_dark_ini_by_cpl.h"
#include "sinfo_raw_types.h"
#include "sinfo_pro_types.h"
#include "sinfo_globals.h"
#include "sinfo_hidden.h"
#include "sinfo_functions.h"
/*---------------------------------------------------------------------------
                    Functions private to this module
 ---------------------------------------------------------------------------*/
static void     
parse_section_frames(dark_config *, cpl_frameset* sof, 
                     cpl_frameset** raw, int* status);
static void     
parse_section_cleanmean(dark_config *, cpl_parameterlist* cpl_cfg);
static void     
parse_section_qclog(dark_config * cfg, cpl_parameterlist * cpl_cfg);

void sinfo_detnoise_free(dark_config * cfg);

/**@{*/
/**
 * @addtogroup sinfo_dark_cfg Dark manipulation functions
 *
 * TBD
 */

/**
  @name     sinfo_parse_cpl_input_dark
  @memo     Parse input frames & parameters and create a blackboard.
  @param    cpl_cfg pointer to parameterlist
  @param    sof pointer to input set of frames
  @param    raw pointer to input set of raw frames
  @return   1 newly allocated dark_config blackboard structure.
  @doc

  The requested ini file is parsed and a blackboard object is created, then
  updated accordingly. Returns NULL in case of error.
 */

dark_config * 
sinfo_parse_cpl_input_dark(cpl_parameterlist * cpl_cfg, 
                           cpl_frameset* sof, 
                           cpl_frameset** raw)
{
    int status=0;

    dark_config   *       cfg ;

    /* Removed check on ini_file */
    /* Removed load of ini file */

    cfg = sinfo_dark_cfg_create();

    /*
     * Perform sanity checks, fill up the structure with what was
     * found in the ini file
     */
    parse_section_cleanmean    (cfg, cpl_cfg);
    parse_section_qclog    (cfg, cpl_cfg);
    parse_section_frames       (cfg, sof, raw, &status);
    if (status > 0) {
        sinfo_msg_error("parsing cpl input");
        sinfo_dark_cfg_destroy(cfg);
        cfg = NULL ;
        return NULL ;
    }

    return cfg ;
}

/**
  @name     parse_section_frames
  @memo     Parse input frames and create a blackboard.
  @param    cfg pointer to dark_config
  @param    sof pointer to input set of frames
  @param    raw pointer to input set of raw frames
  @param    status status of function
  @return   void
 */

static void     
parse_section_frames(dark_config * cfg,
                     cpl_frameset * sof,
                     cpl_frameset** raw,
                     int* status)
{

    int                     i;
    int                   nraw=0;
    int                   nraw_good=0;
    cpl_frame* frame=NULL;

    char spat_res[FILE_NAME_SZ];
    char lamp_status[FILE_NAME_SZ];
    char band[FILE_NAME_SZ];
    int ins_set=0;
    sinfo_extract_raw_frames_type(sof,raw,RAW_DARK);

    nraw=cpl_frameset_get_size(*raw);
    if (nraw < 1) {
        sinfo_msg_error("Too few (%d) raw frames (%s) present in"
                        "frameset!Aborting...",nraw,RAW_DARK);
        (*status)++;
        return;
    }



    /* Removed: get "general:infile" read it, check input sinfo_matrix */
    /* Allocate structures to go into the blackboard */
    cfg->inFrameList     = cpl_malloc(nraw * sizeof(char*));


    /* read input frames */
    for (i=0 ; i<nraw ; i++) {
        frame = cpl_frameset_get_frame(*raw,i);
        /* Store file name into framelist */
        cfg->inFrameList[i]=cpl_strdup(cpl_frame_get_filename(frame));
        nraw_good++;
    }

    if(nraw_good<1) {
        sinfo_msg_error("no good raw frame in input, something wrong!");
        (*status)++;
        return;
    }
    /* Copy relevant information into the blackboard */
    cfg->nframes         = nraw ;

    strcpy(cfg -> outName, DARK_OUT_FILENAME);


    frame = cpl_frameset_get_frame(*raw,0);
    sinfo_get_spatial_res(frame,spat_res);

    switch(sinfo_frame_is_on(frame))
    {
    case 0:
        strcpy(lamp_status,"on");
        break;
    case 1: 
        strcpy(lamp_status,"off");
        break;
    case -1:
        strcpy(lamp_status,"undefined");
        break;
    default: 
        strcpy(lamp_status,"undefined");
        break;


    }

    sinfo_get_band(frame,band);
    sinfo_msg("Spatial resolution: %s lamp status: %s band: %s \n",
              spat_res,    lamp_status,    band);


    sinfo_get_ins_set(band,&ins_set);
    return ;
}

/**
  @name     parse_section_cleanmean
  @memo     Parse cleanmean parameters.
  @param    cfg pointer to dark_config
  @param    cpl_cfg pointer to input parameters
  @return   void
 */

static void     
parse_section_cleanmean(dark_config * cfg, cpl_parameterlist *   cpl_cfg)
{
    cpl_parameter *p;

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.low_rejection");
    cfg -> lo_reject = cpl_parameter_get_double(p);

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.high_rejection");
    cfg -> hi_reject = cpl_parameter_get_double(p);

}

/**
  @name     parse_section_qclog
  @memo     Parse qclog parameters.
  @param    cfg pointer to dark_config
  @param    cpl_cfg pointer to input parameters
  @return   void
 */
static void     
parse_section_qclog(dark_config * cfg, cpl_parameterlist *   cpl_cfg)
{
    cpl_parameter *p;

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.qc_ron_xmin");
    cfg -> qc_ron_xmin = cpl_parameter_get_int(p);

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.qc_ron_xmax");
    cfg -> qc_ron_xmax = cpl_parameter_get_int(p);

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.qc_ron_ymin");
    cfg -> qc_ron_ymin = cpl_parameter_get_int(p);

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.qc_ron_ymax");
    cfg -> qc_ron_ymax = cpl_parameter_get_int(p);

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.qc_ron_hsize");
    cfg -> qc_ron_hsize = cpl_parameter_get_int(p);

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.qc_ron_nsamp");
    cfg -> qc_ron_nsamp = cpl_parameter_get_int(p);



    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.qc_fpn_xmin");
    cfg -> qc_fpn_xmin = cpl_parameter_get_int(p);

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.qc_fpn_xmax");
    cfg -> qc_fpn_xmax = cpl_parameter_get_int(p);

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.qc_fpn_ymin");
    cfg -> qc_fpn_ymin = cpl_parameter_get_int(p);

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.qc_fpn_ymax");
    cfg -> qc_fpn_ymax = cpl_parameter_get_int(p);

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.qc_fpn_hsize");
    cfg -> qc_fpn_hsize = cpl_parameter_get_int(p);

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.dark.qc_fpn_nsamp");
    cfg -> qc_fpn_nsamp = cpl_parameter_get_int(p);


}

/**
@name sinfo_dark_free
@memo deallocates dark_config structure
@param cfg pointer to dark_config structure
@return void
 */
void
sinfo_dark_free(dark_config ** cfg)
{  

    if((*cfg) != NULL) {
        int i=0;
        for(i=0;i<(*cfg)->nframes;i++) {
            if((*cfg)->inFrameList[i] != NULL) {
                cpl_free((*cfg)->inFrameList[i]);
                (*cfg)->inFrameList[i]=NULL;
            }
        }
        cpl_free((*cfg)->inFrameList);
        (*cfg)->inFrameList=NULL;
        sinfo_dark_cfg_destroy((*cfg));
        *cfg = NULL;
    }
    return;

}
