/* $Id: hawki_util_stdstars.c,v 1.20 2013-08-22 16:04:49 cgarcia Exp $
 *
 * This file is part of the HAWKI 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/*
 * $Author: cgarcia $
 * $Date: 2013-08-22 16:04:49 $
 * $Revision: 1.20 $
 * $Name: not supported by cvs2svn $
 */

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

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

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

#include "irplib_utils.h"
#include "irplib_stdstar.h"

#include "hawki_utils.h"
#include "hawki_load.h"
#include "hawki_pfits.h"
#include "hawki_dfs.h"

/*-----------------------------------------------------------------------------
                            Functions prototypes
 -----------------------------------------------------------------------------*/

static int hawki_util_stdstars_create(cpl_plugin *) ;
static int hawki_util_stdstars_exec(cpl_plugin *) ;
static int hawki_util_stdstars_destroy(cpl_plugin *) ;
static int hawki_util_stdstars(cpl_frameset *) ;
static cpl_table * hawki_util_stdstars_convert(const char *) ; 

/*-----------------------------------------------------------------------------
                            Static variables
 -----------------------------------------------------------------------------*/

static char hawki_util_stdstars_description[] = 
"hawki_util_stdstars -- HAWK-I standard stars catalog creation.\n"
"The files listed in the Set Of Frames (sof-file) must be tagged:\n"
"raw-file.txt "HAWKI_UTIL_STDSTARS_RAW"\n" ;

/*-----------------------------------------------------------------------------
                                Functions code
 -----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/**
  @brief    Build the list of available plugins, for this module. 
  @param    list    the plugin list
  @return   0 if everything is ok

  This function is exported.
 */
/*----------------------------------------------------------------------------*/
int cpl_plugin_get_info(cpl_pluginlist * list)
{
    cpl_recipe  *   recipe = cpl_calloc(1, sizeof(*recipe)) ;
    cpl_plugin  *   plugin = &recipe->interface ;

    cpl_plugin_init(plugin,
                    CPL_PLUGIN_API,
                    HAWKI_BINARY_VERSION,
                    CPL_PLUGIN_TYPE_RECIPE,
                    "hawki_util_stdstars",
                    "Standard stars catalog creation",
                    hawki_util_stdstars_description,
                    "Cesar Enrique Garcia Dabo",
                    PACKAGE_BUGREPORT,  
                    hawki_get_license(),
                    hawki_util_stdstars_create,
                    hawki_util_stdstars_exec,
                    hawki_util_stdstars_destroy) ;

    cpl_pluginlist_append(list, plugin) ;
    
    return 0;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Setup the recipe options    
  @param    plugin  the plugin
  @return   0 if everything is ok

  Create the recipe instance and make it available to the application using the 
  interface. 
 */
/*----------------------------------------------------------------------------*/
static int hawki_util_stdstars_create(cpl_plugin * plugin)
{
    cpl_recipe      * recipe ;

    /* Get the recipe out of the plugin */
    if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
        recipe = (cpl_recipe *)plugin ;
    else return -1 ;

    /* Create the parameters list in the cpl_recipe object */
    recipe->parameters = cpl_parameterlist_new() ;

    /* Return */
    return 0;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Execute the plugin instance given by the interface
  @param    plugin  the plugin
  @return   0 if everything is ok
 */
/*----------------------------------------------------------------------------*/
static int hawki_util_stdstars_exec(cpl_plugin * plugin)
{
    cpl_recipe  *   recipe ;

    /* Get the recipe out of the plugin */
    if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
        recipe = (cpl_recipe *)plugin ;
    else return -1 ;

    /* Issue a banner */
    hawki_print_banner();

    return hawki_util_stdstars(recipe->frames) ;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Destroy what has been created by the 'create' function
  @param    plugin  the plugin
  @return   0 if everything is ok
 */
/*----------------------------------------------------------------------------*/
static int hawki_util_stdstars_destroy(cpl_plugin * plugin)
{
    cpl_recipe  *   recipe ;

    /* Get the recipe out of the plugin */
    if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
        recipe = (cpl_recipe *)plugin ;
    else return -1 ;

    cpl_parameterlist_delete(recipe->parameters) ;
    return 0 ;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The recipe data reduction part is implemented here 
  @param    framelist   the frames list
  @return   0 if everything is ok
 */
/*----------------------------------------------------------------------------*/
static int hawki_util_stdstars(
        cpl_frameset        *   framelist)
{
    cpl_frameset        *   rawframes ;
    const char          *   recipe_name = "hawki_util_stdstars" ;

    
    /* Identify the RAW and CALIB frames in the input frameset */
    if (hawki_dfs_set_groups(framelist)) {
        cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
        return -1 ;
    }

    /* Retrieve raw frames */
    if ((rawframes = hawki_extract_frameset(framelist,
                    HAWKI_UTIL_STDSTARS_RAW)) == NULL) {
        cpl_msg_error(__func__, "Cannot find raw frames in the input list") ;
        return -1 ;
    }

    /* Write the catalog */
    if (irplib_stdstar_write_catalogs(framelist,
                rawframes, 
                recipe_name,
                HAWKI_CALPRO_STDSTARS, 
                HAWKI_PROTYPE_STDSTARS,
                PACKAGE "/" PACKAGE_VERSION,
                "HAWKI",
                hawki_util_stdstars_convert) != CPL_ERROR_NONE) {
        cpl_msg_error(__func__, "Cannot write the catalogs") ;
        cpl_frameset_delete(rawframes) ;
        return -1 ;
    }
    cpl_frameset_delete(rawframes) ;

    /* Return */
    if (cpl_error_get_code())
    {
        cpl_msg_error(__func__,
                      "HAWK-I pipeline could not recover from previous errors");
        return -1 ;
    }
    else return 0 ;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Convert the ASCII catalog to the table
  @param    filename    the ascii file
  @return   the newly allocated table or NULL in error case

  The returned table must be deallocated with cpl_table_delete().

  The inputcatalogs are ASCII files respecting this format:

  Star_name RA DEC Spec_type MAG_FILT1 MAG_FILT2 

  Example:
  AS01-0 13.7912 0.720278 -- 10.716 10.507 
  AS03-0 16.09 4.2275 -- 12.606 12.729 
  AS04-1 28.6808 0.733056 -- 12.371 12.033
  ... 

  99 is the value for unknown magnitudes.
  
 */
/*----------------------------------------------------------------------------*/
static cpl_table * hawki_util_stdstars_convert(const char * filename) 
{
    cpl_table   *   out ;
    int             nfilters ;
    const char  *   filters[4];
    double          mags[4] ;
    int             nbentries ;
    FILE        *   in ;
    char            line[1024];
    double          ra, dec ;
    char            sname[512];
    char            stype[512];
    int             i ;
    
    /* Check entries */
    if (filename == NULL) return NULL ;

    /* Initialise */
    nfilters = 4 ;
    filters[0] = hawki_std_band_name(HAWKI_BAND_J) ;
    filters[1] = hawki_std_band_name(HAWKI_BAND_H) ;
    filters[2] = hawki_std_band_name(HAWKI_BAND_K) ;
    filters[3] = hawki_std_band_name(HAWKI_BAND_Y) ;
   
    /* Get the number of lines */
    nbentries = 0 ;
    if ((in = fopen(filename, "r")) == NULL) {
        return NULL ;
    }
    while (fgets(line, 1024, in) != NULL) {
        if (line[0] != '#') nbentries ++ ;
    }
    fclose(in) ;
    
   /* Create the table */
    out = cpl_table_new(nbentries);
    cpl_table_new_column(out, IRPLIB_STDSTAR_STAR_COL, CPL_TYPE_STRING);
    cpl_table_new_column(out, IRPLIB_STDSTAR_TYPE_COL, CPL_TYPE_STRING);
    cpl_table_new_column(out, IRPLIB_STDSTAR_RA_COL, CPL_TYPE_DOUBLE);
    cpl_table_new_column(out, IRPLIB_STDSTAR_DEC_COL, CPL_TYPE_DOUBLE);
    for (i=0 ; i<nfilters ; i++)
        cpl_table_new_column(out, filters[i], CPL_TYPE_DOUBLE);

    /* Parse the file */
    if ((in = fopen(filename, "r")) == NULL) {
        cpl_table_delete(out) ;
        return NULL ;
    }
    nbentries = 0 ;
    while (fgets(line, 1024, in) != NULL) {
        if (line[0] != '#') {
            if (sscanf(line, "%510s %lg %lg %510s %lg %lg %lg %lg", 
                        sname, &ra, &dec, stype, &(mags[0]), &(mags[1]),
                        &(mags[2]), &(mags[3])) != 8) {
                cpl_table_delete(out) ;
                fclose(in);
                return NULL ;
            }
            cpl_table_set_string(out, IRPLIB_STDSTAR_STAR_COL,nbentries, sname);
            cpl_table_set_string(out, IRPLIB_STDSTAR_TYPE_COL,nbentries, stype);
            cpl_table_set_double(out, IRPLIB_STDSTAR_RA_COL, nbentries, ra);
            cpl_table_set_double(out, IRPLIB_STDSTAR_DEC_COL, nbentries, dec);
            for (i=0 ; i<nfilters ; i++)
                cpl_table_set_double(out, filters[i], nbentries, mags[i]);
            nbentries ++ ;
        }
    }
    fclose(in) ;
                
    return out ;
}

