/* $Id: naco_utils.c,v 1.32 2009-10-13 08:05:57 llundin Exp $
 *
 * This file is part of the NACO 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: llundin $
 * $Date: 2009-10-13 08:05:57 $
 * $Revision: 1.32 $
 * $Name: not supported by cvs2svn $
 */

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

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

#include <string.h>
#include <math.h>
#include <cpl.h>

#include "naco_utils.h"
#include "naco_pfits.h"

/*----------------------------------------------------------------------------*/
/**
 * @defgroup naco_utils     Miscellaneous Utilities
 */
/*----------------------------------------------------------------------------*/

/**@{*/

/*----------------------------------------------------------------------------*/
/**
  @brief    Get the infos of one of the filters
  @param    f      The filter name
  @param    lam    The associated central wavelength [micrometer]
  @param    dlam   The associated filter width [micrometer]
  @note The function will return immediately if called with a CPL error.
  @return   0 iff ok
 */
/*----------------------------------------------------------------------------*/
cpl_error_code naco_get_filter_infos(const char * f, double * lam,
                                     double * dlam)
{

    bug_if(cpl_error_get_code());
    bug_if( f    == NULL);
    bug_if( lam  == NULL);
    bug_if( dlam == NULL);

    if (!strncmp(f, "J", IRPLIB_FITS_STRLEN))        {
         *lam = 1.265; *dlam = 0.250;
    } else if (!strncmp(f, "Jc", IRPLIB_FITS_STRLEN))       {
         *lam = 1.265; *dlam = 0.250;
    } else if (!strncmp(f, "H", IRPLIB_FITS_STRLEN))        {
         *lam = 1.660; *dlam = 0.330;
    } else if (!strncmp(f, "K", IRPLIB_FITS_STRLEN))        {
         *lam = 2.230; *dlam = 0.390;
    } else if (!strncmp(f, "Ks", IRPLIB_FITS_STRLEN))       {
         *lam = 2.180; *dlam = 0.350;
    } else if (!strncmp(f, "L", IRPLIB_FITS_STRLEN))        {
         *lam = 3.500; *dlam = 0.610;
    } else if (!strncmp(f, "L_prime", IRPLIB_FITS_STRLEN))  {
         *lam = 3.800; *dlam = 0.620;
    } else if (!strncmp(f, "M_prime", IRPLIB_FITS_STRLEN))  {
         *lam = 4.780; *dlam = 0.590;
    } else if (!strncmp(f, "SJ", IRPLIB_FITS_STRLEN))       {
         *lam = 1.160; *dlam = 0.470;
    } else if (!strncmp(f, "SH", IRPLIB_FITS_STRLEN))       {
         *lam = 1.630; *dlam = 0.430;
    } else if (!strncmp(f, "SK", IRPLIB_FITS_STRLEN))       {
         *lam = 2.270; *dlam = 0.760;
    } else if (!strncmp(f, "NB_1.04", IRPLIB_FITS_STRLEN))  {
         *lam = 1.040; *dlam = 0.015;
    } else if (!strncmp(f, "NB_1.08", IRPLIB_FITS_STRLEN))  {
         *lam = 1.083; *dlam = 0.015;
    } else if (!strncmp(f, "NB_1.09", IRPLIB_FITS_STRLEN))  {
         *lam = 1.094; *dlam = 0.015;
    } else if (!strncmp(f, "NB_1.24", IRPLIB_FITS_STRLEN))  {
         *lam = 1.237; *dlam = 0.015;
    } else if (!strncmp(f, "NB_1.26", IRPLIB_FITS_STRLEN))  {
         *lam = 1.257; *dlam = 0.014;
    } else if (!strncmp(f, "NB_1.28", IRPLIB_FITS_STRLEN))  {
         *lam = 1.282; *dlam = 0.014;
    } else if (!strncmp(f, "NB_1.64", IRPLIB_FITS_STRLEN))  {
         *lam = 1.644; *dlam = 0.018;
    } else if (!strncmp(f, "NB_1.75", IRPLIB_FITS_STRLEN))  {
         *lam = 1.748; *dlam = 0.026;
    } else if (!strncmp(f, "NB_3.74", IRPLIB_FITS_STRLEN))  {
         *lam = 3.740; *dlam = 0.020;
    } else if (!strncmp(f, "IB_2.00", IRPLIB_FITS_STRLEN))  {
         *lam = 2.000; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.03", IRPLIB_FITS_STRLEN))  {
         *lam = 2.030; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.06", IRPLIB_FITS_STRLEN))  {
         *lam = 2.060; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.09", IRPLIB_FITS_STRLEN))  {
         *lam = 2.090; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.12", IRPLIB_FITS_STRLEN))  {
         *lam = 2.120; *dlam = 0.060;
    } else if (!strncmp(f, "NB_2.12", IRPLIB_FITS_STRLEN))  {
         *lam = 2.122; *dlam = 0.022;
    } else if (!strncmp(f, "IB_2.15", IRPLIB_FITS_STRLEN))  {
         *lam = 2.150; *dlam = 0.060;
    } else if (!strncmp(f, "NB_2.17", IRPLIB_FITS_STRLEN))  {
         *lam = 2.166; *dlam = 0.023;
    } else if (!strncmp(f, "IB_2.18", IRPLIB_FITS_STRLEN))  {
         *lam = 2.180; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.21", IRPLIB_FITS_STRLEN))  {
         *lam = 2.210; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.24", IRPLIB_FITS_STRLEN))  {
         *lam = 2.240; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.27", IRPLIB_FITS_STRLEN))  {
         *lam = 2.270; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.30", IRPLIB_FITS_STRLEN))  {
         *lam = 2.300; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.33", IRPLIB_FITS_STRLEN))  {
         *lam = 2.330; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.36", IRPLIB_FITS_STRLEN))  {
         *lam = 2.360; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.39", IRPLIB_FITS_STRLEN))  {
         *lam = 2.390; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.42", IRPLIB_FITS_STRLEN))  {
         *lam = 2.420; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.45", IRPLIB_FITS_STRLEN))  {
         *lam = 2.450; *dlam = 0.060;
    } else if (!strncmp(f, "IB_2.48", IRPLIB_FITS_STRLEN))  {
         *lam = 2.480; *dlam = 0.060;
    } else if (!strncmp(f, "NB_4.05", IRPLIB_FITS_STRLEN))  {
         *lam = 4.051; *dlam = 0.020;
    } else if (!strncmp(f, "IB_4.05", IRPLIB_FITS_STRLEN))  {
        /* As per email 2009-10-13 from epompei@eso.org */
         *lam = 4.05; *dlam = 0.100;
    } else
        irplib_ensure(0, CPL_ERROR_DATA_NOT_FOUND, "Unknown filter: %s", f);

    end_skip;

    return cpl_error_get_code();
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Retag a framelist according to the given tagging function
  @param    self   Framelist with frames to retag
  @param    pftag  Function to create a new tag for one frame
  @param    pntags On success, number of new tags in framelist, otherwise undef
  @return   List of new tags or NULL on error
  @note (*pftag)() must return a newly allocated pointer. It must indicate an
        error by returning NULL and by setting a CPL error code.
        On error some of the the tags in the framelist may be modified.
        The integer parameter to (*pftag)() is its index in the framelist
        (starting with zero).

 */
/*----------------------------------------------------------------------------*/
const char ** naco_framelist_set_tag(irplib_framelist * self,
                                     char * (*pftag)(const cpl_frame *,
                                                     const cpl_propertylist *,
                                                     int),
                                     int *pntags)
{

    const char ** taglist = NULL; /* Must be initialized due to realloc call */
    int iframe, size;

    cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
    cpl_ensure(self   != NULL, CPL_ERROR_NULL_INPUT, NULL);
    cpl_ensure(pftag  != NULL, CPL_ERROR_NULL_INPUT, NULL);
    cpl_ensure(pntags != NULL, CPL_ERROR_NULL_INPUT, NULL);

    size = irplib_framelist_get_size(self);

    cpl_ensure(size > 0, CPL_ERROR_DATA_NOT_FOUND, NULL);

    *pntags = 0;

    for (iframe = 0; iframe < size ; iframe++) {
        cpl_frame  * frame = irplib_framelist_get(self, iframe);
        const cpl_propertylist * plist
            = irplib_framelist_get_propertylist_const(self, iframe);
        char       * tag;
        const char * newtag;
        int          i;


        /* This should really be an assert() */
        cpl_ensure(frame != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
        cpl_ensure(plist != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);

        tag = (*pftag)(frame, plist, iframe);

        cpl_ensure(tag != NULL, cpl_error_get_code(), NULL);

        /* From this point on failures should not really happen */

        (void)cpl_frame_set_tag(frame, tag);
        cpl_free(tag);

        newtag = cpl_frame_get_tag(frame);

        cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);

        /* Compare the new tags with those of previous frames */
        for (i=0; i < *pntags; i++)
            if (strcmp(newtag, taglist[i]) == 0) break;

        if (i == *pntags) {
            /* The new tag is different from the previous ones
               - add it to the list */
            (*pntags)++;
            taglist = (const char **)cpl_realloc(taglist, *pntags *
                                                 sizeof(const char *));
            taglist[i] = newtag;
        }

    }

    return taglist;

}

/**@}*/
