/*
 * 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_standstar_ini_by_cpl.c
 Author       :   Andrea Modigliani
 Created on   :   May 23, 2004
 Description  :   standard star reduction cpl input handling for SPIFFI

 ---------------------------------------------------------------------------*/

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

/*---------------------------------------------------------------------------
 Includes
 ---------------------------------------------------------------------------*/
#include <string.h>
#include "sinfo_standstar_ini_by_cpl.h"
#include "sinfo_pro_types.h"
#include "sinfo_hidden.h"
#include "sinfo_functions.h"
#include "sinfo_file_handling.h"

/*---------------------------------------------------------------------------
 Functions private to this module
 ---------------------------------------------------------------------------*/

static void
parse_section_frames(standstar_config *, cpl_frameset* sof, cpl_frameset** raw,
                     int* status);
static void
parse_section_extraction(standstar_config *, cpl_parameterlist* cpl_cfg);
/**@{*/
/**
 * @addtogroup sinfo_rec_jitter blackboard for standard star structure 
 *  configuration
 *
 * TBD
 */

/*-------------------------------------------------------------------------*/
/**
 @name     parse_standstar_ini_file
 @memo     Parse a ini_name.ini file and create a blackboard.
 @param    ini_name    Name of the ASCII file to parse.
 @return   1 newly allocate standstar_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.
 */
/*--------------------------------------------------------------------------*/

standstar_config *
sinfo_parse_cpl_input_standstar(cpl_parameterlist* cpl_cfg, cpl_frameset* sof,
                                cpl_frameset** raw)
{

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

static void
parse_section_frames(standstar_config * cfg, cpl_frameset* sof,
                     cpl_frameset** raw, int* status)
{
    int i;
    int nval;
    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;
    cpl_frameset* tmp = NULL;
    /* AMO BEWARE only STD frames should be here checked for */
    sinfo_extract_frames_group_type(sof, &tmp, CPL_FRAME_GROUP_PRODUCT);
    sinfo_extract_raw_frames_type(tmp, raw, PRO_COADD_STD);
    cpl_frameset_delete(tmp);
    nval = cpl_frameset_get_size(*raw);
    if (nval < 1) {
        sinfo_extract_raw_frames_type(sof, raw, PRO_OBS_STD);
    }
    nval = cpl_frameset_get_size(*raw);
    if (nval < 1) {
        sinfo_extract_raw_frames_type(sof, raw, PRO_COADD_PSF);
    }
    nval = cpl_frameset_get_size(*raw);
    if (nval < 1) {
        sinfo_extract_raw_frames_type(sof, raw, PRO_OBS_PSF);
    }
    nval = cpl_frameset_get_size(*raw);
    if (nval < 1) {
        sinfo_extract_raw_frames_type(sof, raw, PRO_COADD_OBJ);
    }
    nval = cpl_frameset_get_size(*raw);
    if (nval < 1) {
        sinfo_extract_raw_frames_type(sof, raw, PRO_OBS_OBJ);
    }
    nval = cpl_frameset_get_size(*raw);
    if (nval < 1) {
        sinfo_msg_error("Too few (%d) raw frames "
                        "(%s or %s or %s or %s or %s or %s ) "
                        "present in frameset!Aborting...", nval, PRO_COADD_STD,
                        PRO_OBS_STD, PRO_COADD_PSF, PRO_OBS_PSF, PRO_COADD_OBJ,
                        PRO_OBS_OBJ);
        (*status)++;
        return;
    }

    /* Allocate structures to go into the blackboard */
    cfg->inFrameList = cpl_malloc(nval * sizeof(char*));
    /* Browse through the charmatrix to get names and file types */
    /* read input frames */
    for (i = 0; i < nval; i++) {
        frame = cpl_frameset_get_frame(*raw, i);
        if (sinfo_file_exists((char*) cpl_frame_get_filename(frame)) == 1) {
            /* Store file name into framelist */
            cfg->inFrameList[i] = cpl_strdup(cpl_frame_get_filename(frame));
        }
    }

    /* Copy relevant information into the blackboard */
    cfg->nframes = nval;

    strcpy(cfg->outName, STDSTAR_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", spat_res,
                    lamp_status, band);

    sinfo_get_ins_set(band, &ins_set);
    return;
}

static void
parse_section_extraction(standstar_config * cfg, cpl_parameterlist* cpl_cfg)
{
    cpl_parameter* p;
    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.std_star.low_rejection");
    cfg->lo_reject = cpl_parameter_get_double(p);

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

    cfg->llx = 8;
    cfg->lly = 8;
    cfg->halfbox_x = 16;
    cfg->halfbox_y = 16;

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.std_star.fwhm_factor");
    cfg->fwhm_factor = cpl_parameter_get_double(p);

    cfg->backvariance = BKG_VARIANCE;
    cfg->sky = SKY_FLUX;
    cfg->gain = GAIN;

    p = cpl_parameterlist_find(cpl_cfg, "sinfoni.std_star.conversion_index");
    cfg->convInd = cpl_parameter_get_bool(p);

    strcpy(cfg->convName, STDSTAR_CONV_OUT_FILENAME);

    cfg->mag = 0;

    return;
}

void
sinfo_stdstar_free(standstar_config ** cfg)
{
    if ((*cfg) != NULL ) {
        for (int 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_standstar_cfg_destroy(*cfg);
        (*cfg) = NULL;
    }
}
/**@}*/
