/* $Id: fors_instrument.c,v 1.4 2010-09-14 07:49:30 cizzo Exp $
 *
 * This file is part of the FORS Library
 * Copyright (C) 2002-2010 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  02110-1301 USA
 */

/*
 * $Author: cizzo $
 * $Date: 2010-09-14 07:49:30 $
 * $Revision: 1.4 $
 * $Name: not supported by cvs2svn $
 */

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

#include <fors_instrument.h>
#include <string.h>

const struct fors_filterlist {
    const char  name[10];
    const char  band;
} fors_filterlist[15] = {
    /* FORS1 */
    {"U_BESS", 'U'},
    {"u_HIGH", 'U'},
    {"B_BESS", 'B'},
    {"b_HIGH", 'B'},
    {"g_HIGH", 'V'},    /* G uses V ?????????????????????????????????? */
    {"V_BESS", 'V'},
    {"v_HIGH", 'V'},
    {"R_BESS", 'R'},
    {"I_BESS", 'I'},

    /* FORS2 */
    {"U_SPECIAL", 'U'},
    {"B_BESS"   , 'B'},
    {"V_BESS"   , 'V'},
    {"R_SPECIAL", 'R'},
    {"I_BESS"   , 'I'},
    {""         , '\0'}
};

const char  fors_filterband_unknown = '?',
            fors_filterband_none    = '\0';

/**
 * @brief   Find the respective filter of the FORS @em setting->filtername and get the band.
 * @param   setting FORS instrument settings
 * @return  Band
 * 
 * - If @a setting is NULL, then the return value from
 *   @ref fors_instrument_filterband_value_unknown() is returned, and the
 *   error CPL_ERROR_NULL_INPUT is set.
 * - If @a setting->filtername is NULL or empty, then '\0' is returned, what
 *   means that no filter was used.
 * - If the filter is unknown, then the return value from
 *   @ref fors_instrument_filterband_value_unknown() is returned, and the
 *   error CPL_ERROR_ILLEGAL_INPUT is set.
 */
char
fors_instrument_filterband_get_by_setting(  const fors_setting  *setting)
{
    char            band;
    cpl_errorstate  errstat = cpl_errorstate_get();
    
    if (setting == NULL)
    {
        cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
        return fors_filterband_unknown;
    }
    
    band = fors_instrument_filterband_get_by_name(setting->filter_name);
    if (!cpl_errorstate_is_equal(errstat))
        cpl_error_set_where(cpl_func);
    
    return band;
}

/**
 * @brief   Find the respective filter of the FORS filter set and get the band.
 * @param   filtername  Filter name
 * @return  Band
 * 
 * - If @a filtername is NULL or empty, then '\0' is returned, what means
 *   that no filter was used.
 * - If the filter is unknown, the return value from
 *   @ref fors_instrument_filterband_value_unknown() is returned, and the
 *   error CPL_ERROR_ILLEGAL_INPUT is set.
 */
char
fors_instrument_filterband_get_by_name(     const char  *filtername)
{
    int n;
    
    if (filtername == NULL || filtername[0] == '\0')
        return fors_filterband_none;
    
    n = 0;
    while ((fors_filterlist[n].name)[0] != '\0')
    {
        if (strcmp(filtername, fors_filterlist[n].name) == 0)
            return fors_filterlist[n].band;
        n++;
    }
    
    cpl_error_set_message(                  cpl_func,
                                            CPL_ERROR_ILLEGAL_INPUT,
                                            "unknown filter name \"%s\"",
                                            filtername);
    return fors_filterband_unknown;
}

/**
 * @brief   Check whether a filter band is neither @em none nor @em unknown.
 * @param   band    Filter band
 * @return  True if fulfilled
 * 
 * Returning true means, that neither the @em none value nor an @em unknown
 * value is set. It does not mean that it exists in the FORS filter list.
 */
bool
fors_instrument_filterband_is_defined(      char    band)
{
    return  (band >= 'A' && band <= 'Z');
}

/**
 * @brief   Check whether a filter band is @em none.
 * @param   band    Filter band
 * @return  True if fulfilled
 * 
 * Returning true means, that exactly the @em none value is set.
 */
bool
fors_instrument_filterband_is_none(         char    band)
{
    return  (band == '\0');
}

/**
 * @brief   Check whether a filter band is @em unknown.
 * @param   band    Filter band
 * @return  True if fulfilled
 * 
 * Returning true means, that an @em unknown value is set. This means that
 * neither the @a none value is set nor that any valid value is set.
 */
bool
fors_instrument_filterband_is_unknown(      char    band)
{
    return  !(  fors_instrument_filterband_is_defined(band)
                || fors_instrument_filterband_is_none(band));
}

/**
 * @brief   Return the @a unknown filterband value.
 * @return  Value
 */
char
fors_instrument_filterband_value_unknown(   void)
{
    return fors_filterband_unknown;
}

/**
 * @brief   Get the number of filters in the FORS filter set.
 * @return  Number
 */
int
fors_instrument_known_filters_get_number(   void)
{
    return (sizeof(fors_filterlist)/sizeof(*fors_filterlist)) - 1;
}

/**
 * @brief   Get the name of a filter in the FORS filter set.
 * @param   n   Filter index
 * @return  The filter name
 * 
 * If @a n < 0 or @a n >= @ref fors_instrument_known_filters_get_number(),
 * then CPL_ERROR_ACCESS_OUT_OF_RANGE is set and NULL is returned.
 */
const char  *
fors_instrument_known_filters_get_name(     int n)
{
    if (n < 0
        || n >= fors_instrument_known_filters_get_number())
    {
        cpl_error_set(                      cpl_func,
                                            CPL_ERROR_ACCESS_OUT_OF_RANGE);
        return NULL;
    }
    return fors_filterlist[n].name;
}

/**
 * @brief   Get the optical band of a filter in the FORS filter set.
 * @param   n   Filter index
 * @return  Band
 * 
 * If @a n < 0 or @a n >= @ref fors_instrument_known_filters_get_number(),
 * then CPL_ERROR_ACCESS_OUT_OF_RANGE is set and the return value of
 * @ref fors_instrument_filterband_value_unknown() is returned.
 */
char
fors_instrument_known_filters_get_band(     int n)
{
    if (n < 0
        || n >= fors_instrument_known_filters_get_number())
    {
        cpl_error_set(                      cpl_func,
                                            CPL_ERROR_ACCESS_OUT_OF_RANGE);
        return fors_filterband_unknown;
    }
    return fors_filterlist[n].band;
}


