/* $Id: visir_dfs.c,v 1.79 2013-05-14 12:59:23 jtaylor Exp $
 *
 * This file is part of the VISIR Pipeline
 * Copyright (C) 2002,2003 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, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
 */

/*
 * $Author: jtaylor $
 * $Date: 2013-05-14 12:59:23 $
 * $Revision: 1.79 $
 * $Name: not supported by cvs2svn $
 */

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

/*-----------------------------------------------------------------------------
                                   Includes
 -----------------------------------------------------------------------------*/

#include "irplib_utils.h"
#include "visir_utils.h"
#include "visir_pfits.h"
#include "visir_dfs.h"
#include <cpl.h>

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <math.h>


/*-----------------------------------------------------------------------------
                        Private function prototypes
 -----------------------------------------------------------------------------*/

static const char * visir_dfs_find_tag_from_dpr(const char *, const char *,
                                                const char *);

/*----------------------------------------------------------------------------*/
/**
 * @defgroup visir_dfs  DFS related functions
 *
 * TBD
 */
/*----------------------------------------------------------------------------*/

/**@{*/

/*----------------------------------------------------------------------------*/
/**
  @brief    Set the group as RAW or CALIB in a frameset
  @param    set     the input frameset
  @return   0 iff ok
 */
/*----------------------------------------------------------------------------*/
int visir_dfs_set_groups(cpl_frameset * set)
{
    int         i = 0;


    skip_if (0);

    /* Loop on frames */
    FOR_EACH_FRAMESET(frame, set) {
        const char * tag = cpl_frame_get_tag(frame);

        skip_if (0);
       
        /* RAW frames */
        if (tag == NULL) cpl_msg_warning(cpl_func,
                                         "Frame %d has no tag", i);
        else if (!strcmp(tag, VISIR_IMG_ACHRO_RAW) ||
                 !strcmp(tag, VISIR_IMG_COMBINE_CN) ||
                 !strcmp(tag, VISIR_IMG_COMBINE_CN_BURST) ||
                 !strcmp(tag, VISIR_IMG_COMBINE_CNJ) ||
                 !strcmp(tag, VISIR_IMG_COMBINE_CNJ_BURST) ||
                 !strcmp(tag, VISIR_IMG_COMBINE_CJ) ||
                 !strcmp(tag, VISIR_IMG_COMBINE_NJ) ||
                 !strcmp(tag, VISIR_IMG_COMBINE_DJ) ||
                 !strcmp(tag, VISIR_IMG_CAL_PHOT) ||
                 !strcmp(tag, VISIR_IMG_CAL_PHOT_PP) ||
                 !strcmp(tag, VISIR_IMG_CAL_PHOT_BURST) ||
                 !strcmp(tag, VISIR_IMG_CAL_OBJ) ||
                 !strcmp(tag, VISIR_IMG_CAL_OBJ_BURST) ||
                 !strcmp(tag, VISIR_IMG_FF_RAW) ||
                 !strcmp(tag, VISIR_IMG_TECH_FF_RAW) ||
                 !strcmp(tag, VISIR_IMG_FOCFWHM_RAW) ||
                 !strcmp(tag, VISIR_IMG_ILLU_RAW) ||
                 !strcmp(tag, VISIR_IMG_PFOV_BIN) ||
                 !strcmp(tag, VISIR_IMG_PFOV_TEL) ||
                 !strcmp(tag, VISIR_IMG_PHOT_RAW) ||
                 !strcmp(tag, VISIR_IMG_PHOT_COMBINED_PROCATG) ||
                 !strcmp(tag, VISIR_IMG_COADDED_IMG) ||
                 !strcmp(tag, VISIR_IMG_PSF_RAW) ||
                 !strcmp(tag, VISIR_IMG_TRANS_RAW) ||
                 !strcmp(tag, VISIR_IMG_DARK_RAW) ||
                 !strcmp(tag, VISIR_ACQ_CNJ) ||
                 !strcmp(tag, VISIR_SPC_OBS_ECH_RAW) ||
                 !strcmp(tag, VISIR_SPC_OBS_RAW) ||
                 !strcmp(tag, VISIR_SPC_OBS_PP) ||
                 !strcmp(tag, VISIR_SPC_OBS_HR_RAW) ||
                 !strcmp(tag, VISIR_SPC_PHOT_RAW) ||
                 !strcmp(tag, VISIR_SPC_PHOT_PP) ||
                 !strcmp(tag, VISIR_SPC_PHOT_ECH_RAW) ||
                 !strcmp(tag, VISIR_SPC_PHOT_ECH_PP) ||
                 !strcmp(tag, VISIR_SPC_OBS_ECH_PP) ||
                 !strcmp(tag, VISIR_SPC_WCAL_ECH_RAW) ||
                 !strcmp(tag, VISIR_SPC_WCAL_RAW) ||
                 !strcmp(tag, VISIR_SPC_FF_RAW) ||
                 !strcmp(tag, VISIR_SPC_TECH_FF_RAW) ||
                 !strcmp(tag, VISIR_SPC_DARK_RAW) ||
                 !strcmp(tag, VISIR_IMG_LINES_ASCII) ||
                 !strcmp(tag, VISIR_SPC_LINES_ASCII) ||
                 !strcmp(tag, VISIR_SPC_QEFF_ASCII) ||
                 !strcmp(tag, VISIR_SAM_CAL_N_RAW) ||
                 !strcmp(tag, VISIR_SAM_CAL_CN_RAW) ||
                 !strcmp(tag, VISIR_SAM_CAL_NJ_RAW) ||
                 !strcmp(tag, VISIR_SAM_CAL_CNJ_RAW) ||
                 !strcmp(tag, VISIR_CORO_CAL_CNJ_RAW) ||
                 !strcmp(tag, VISIR_SAM_OBS_N_RAW) ||
                 !strcmp(tag, VISIR_SAM_OBS_CN_RAW) ||
                 !strcmp(tag, VISIR_SAM_OBS_NJ_RAW) ||
                 !strcmp(tag, VISIR_SAM_OBS_CNJ_RAW) ||
                 !strcmp(tag, VISIR_CORO_OBS_CNJ_RAW) ||
                 !strcmp(tag, VISIR_UTIL_QC_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_REPACK_MEAN_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_REPACK_MEAN_A_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_REPACK_MEAN_B_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_REPACK_MEAN_A_ON_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_REPACK_MEAN_A_OFF_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_REPACK_MEAN_B_ON_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_REPACK_MEAN_B_OFF_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_REPACK_A_ON_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_REPACK_A_OFF_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_REPACK_B_ON_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_REPACK_B_OFF_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_DETECT_SHIFT_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_DETECT_SHIFT_TEMPLATE_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_INPUTS_RAW) ||
                 !strcmp(tag, VISIR_UTIL_CORRECTED) ||
                 !strcmp(tag, VISIR_UTIL_NODDED) ||
                 !strcmp(tag, VISIR_UTIL_CONVERT_RAW) ||
                 !strcmp(tag, VISIR_UTIL_CONVERT_TAB) ||
                 !strcmp(tag, VISIR_UTIL_CONVERT_INV)  ||
                 !strcmp(tag, VISIR_UTIL_CONVERT_POS_AUX) ||
                 !strcmp(tag, VISIR_UTIL_CONVERT_INV_AUX) ||
                 !strcmp(tag, VISIR_UTIL_WEIGHT2ERROR) ||
                 !strcmp(tag, VISIR_IMG_BURST) ||
                 !strcmp(tag, VISIR_UTIL_DATA) ||
                 !strcmp(tag, VISIR_UTIL_UNDISTORT_RAW) ||
                 !strcmp(tag, VISIR_UTIL_REPACK_RAW))
            cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW);
        /* CALIB frames */
        else if (!strcmp(tag, VISIR_CALIB_FLAT) ||
                 !strcmp(tag, VISIR_CALIB_BPM) ||
                 !strcmp(tag, VISIR_CALIB_STATIC_MASK) ||
                 !strcmp(tag, VISIR_CALIB_STDSTAR_IMG) ||
                 !strcmp(tag, VISIR_CALIB_STDSTAR_SPC) ||
                 !strcmp(tag, VISIR_CALIB_LINES_SPC) ||
                 !strcmp(tag, VISIR_CALIB_LIN) ||
                 !strcmp(tag, VISIR_SPC_OBS_SKYFRAME) ||
                 !strcmp(tag, VISIR_UTIL_WEIGHT2ERROR_PROCATG) ||
                 !strcmp(tag, VISIR_IMG_CLIPPED_MAP_PROCATG) ||
                 !strcmp(tag, VISIR_UTIL_WEIGHT2ERROR) ||
                 !strcmp(tag, VISIR_UTIL_WEIGHT_MAP) ||
                 !strcmp(tag, VISIR_UTIL_ERROR_MAP) ||
                 !strcmp(tag, VISIR_UTIL_VARIANCE_MAP) ||
                 !strcmp(tag, VISIR_SPC_CAT_ASCII) ||
                 !strcmp(tag, VISIR_CALIB_QEFF_SPC))
            cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
        else cpl_msg_warning(cpl_func,
                             "Frame %d has unknown tag: %s", i, tag);
    }

 end_skip;

    if (cpl_error_get_code())
        cpl_msg_error(cpl_func, "Could not identify RAW and CALIB frames "
                      "(after processing %d frames)", i);

    return cpl_error_get_code();
}

const char *
visir_dfs_output_catg(const char * inpcatg, const char * pipecatg)
{
    int phot = 0;
    if (!strcmp(pipecatg, VISIR_IMG_PHOT_ONEBEAM_PROCATG) ||
        !strcmp(pipecatg, VISIR_IMG_PHOT_COMBINED_PROCATG)) {
        phot = 1;
    }
    if (!strcmp(inpcatg, VISIR_ACQ_CNJ)) {
        if (phot) {
            return "ACQ_IMG_PHOT_COMBINED";
        }
        else {
            return "ACQ_IMG_OBJ_COMBINED";
        }
    }
    else if (!strcmp(inpcatg, VISIR_IMG_CAL_PHOT_BURST)) {
        return VISIR_IMG_PHOT_COMBINED_PROCATG"_BURST";
    }
    else if (!strcmp(inpcatg, VISIR_IMG_CAL_OBJ_BURST) ||
             !strcmp(inpcatg, VISIR_IMG_COMBINE_CN_BURST) ||
             !strcmp(inpcatg, VISIR_IMG_COMBINE_CNJ_BURST)) {
        return VISIR_IMG_OBJ_COMBINED_PROCATG"_BURST";
    }
    return pipecatg;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Check the tags in a frameset (group raw only)
  @param    self   The frameset to check
  @return   0 iff ok
 */
/*----------------------------------------------------------------------------*/
cpl_error_code visir_dfs_check_framelist_tag(const irplib_framelist * self)
{

    if (cpl_error_get_code()) return cpl_error_get_code();

    cpl_ensure_code(self  != NULL, CPL_ERROR_NULL_INPUT);

    return irplib_dfs_check_framelist_tag(self, visir_dfs_find_tag_from_dpr);

}

/**@}*/

/*----------------------------------------------------------------------------*/
/**
  @brief    Find the DO category from the DPR triplet
  @param    catg  The value of DPR.CATG
  @param    type  The value of DPR.TYPE
  @param    tech  The value of DPR.TECH
  @return   The DO category or NULL on error

 */
/*----------------------------------------------------------------------------*/
static const char * visir_dfs_find_tag_from_dpr(const char * catg,
                                                const char * type,
                                                const char * tech)
{
    const char * docatg = NULL;


    if (cpl_error_get_code()) return NULL;

    cpl_ensure(catg != NULL, CPL_ERROR_NULL_INPUT, NULL);
    cpl_ensure(type != NULL, CPL_ERROR_NULL_INPUT, NULL);
    cpl_ensure(tech != NULL, CPL_ERROR_NULL_INPUT, NULL);

#include "visir_dfs_dpr.h"

    return docatg;

}


