/* $Id: test_hough.c,v 1.5 2013-04-24 14:14:13 cgarcia Exp $
 *
 * This file is part of the FORS Data Reduction Pipeline
 * 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: cgarcia $
 * $Date: 2013-04-24 14:14:13 $
 * $Revision: 1.5 $
 * $Name: not supported by cvs2svn $
 */

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

#include <math.h>
#include <cpl.h>
#include <moses.h>
#include <fors_dfs.h>
#include <fors_qc.h>

static int test_hough_create(cpl_plugin *);
static int test_hough_exec(cpl_plugin *);
static int test_hough_destroy(cpl_plugin *);
static int test_hough(cpl_parameterlist *, cpl_frameset *);

static char test_hough_description[] =
"This recipe is used to test the Hough transformation on any table.\n\n"
"Input files:\n\n"
"  DO category:      Type:       Explanation:\n"
"  TABLE             Raw         Table with at least 2 numerical columns.\n\n"
"Output files:\n\n"
"  DO category:      Data type:  Explanation:\n"
"  TRANSFORMED       FITS table  Table with estimates.\n\n";

#define test_hough_exit(message)              \
{                                             \
if (message) cpl_msg_error(recipe, message);  \
cpl_table_delete(table);                      \
cpl_table_delete(output);                     \
cpl_msg_indent_less();                        \
return -1;                                    \
}

#define test_hough_exit_memcheck(message)     \
{                                             \
if (message) cpl_msg_info(recipe, message);   \
cpl_table_delete(table);                      \
cpl_table_delete(output);                     \
cpl_msg_indent_less();                        \
return 0;                                     \
}


/**
 * @brief    Build the list of available plugins, for this module. 
 *
 * @param    list    The plugin list
 *
 * @return   0 if everything is ok, -1 otherwise
 *
 * Create the recipe instance and make it available to the application 
 * using the interface. 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,
                    FORS_BINARY_VERSION,
                    CPL_PLUGIN_TYPE_RECIPE,
                    "test_hough",
                    "Test Hough transform on any table of points",
                    test_hough_description,
                    "Carlo Izzo",
                    PACKAGE_BUGREPORT,
    "This file is currently part of the FORS Instrument Pipeline\n"
    "Copyright (C) 2002-2010 European Southern Observatory\n\n"
    "This program is free software; you can redistribute it and/or modify\n"
    "it under the terms of the GNU General Public License as published by\n"
    "the Free Software Foundation; either version 2 of the License, or\n"
    "(at your option) any later version.\n\n"
    "This program is distributed in the hope that it will be useful,\n"
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
    "GNU General Public License for more details.\n\n"
    "You should have received a copy of the GNU General Public License\n"
    "along with this program; if not, write to the Free Software Foundation,\n"
    "Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n",
                    test_hough_create,
                    test_hough_exec,
                    test_hough_destroy);

    cpl_pluginlist_append(list, plugin);
    
    return 0;
}


/**
 * @brief    Setup the recipe options    
 *
 * @param    plugin  The plugin
 *
 * @return   0 if everything is ok
 *
 * Defining the command-line/configuration parameters for the recipe.
 */

static int test_hough_create(cpl_plugin *plugin)
{
    cpl_recipe    *recipe;
    cpl_parameter *p;


    /* 
     * Check that the plugin is part of a valid recipe 
     */

    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(); 


    /*
     * Table column with x coordinate
     */

    p = cpl_parameter_new_value("fors.test_hough.xcolumn",
                                CPL_TYPE_STRING,
                                "Table column with x coordinate",
                                "fors.test_hough",
                                "0");
    cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcolumn");
    cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
    cpl_parameterlist_append(recipe->parameters, p);

    /*
     * Table column with y coordinate
     */

    p = cpl_parameter_new_value("fors.test_hough.ycolumn",
                                CPL_TYPE_STRING,
                                "Table column with y coordinate",
                                "fors.test_hough",
                                "0");
    cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ycolumn");
    cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
    cpl_parameterlist_append(recipe->parameters, p);

    return 0;
}


/**
 * @brief    Execute the plugin instance given by the interface
 *
 * @param    plugin  the plugin
 *
 * @return   0 if everything is ok
 */

static int test_hough_exec(cpl_plugin *plugin)
{
    cpl_recipe *recipe;
    
    if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 
        recipe = (cpl_recipe *)plugin;
    else 
        return -1;

    return test_hough(recipe->parameters, recipe->frames);
}


/**
 * @brief    Destroy what has been created by the 'create' function
 *
 * @param    plugin  The plugin
 *
 * @return   0 if everything is ok
 */

static int test_hough_destroy(cpl_plugin *plugin)
{
    cpl_recipe *recipe;
    
    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    Interpret the command line options and execute the data processing
 *
 * @param    parlist     The parameters list
 * @param    frameset    The set-of-frames
 *
 * @return   0 if everything is ok
 */

static int test_hough(cpl_parameterlist *parlist, cpl_frameset *frameset)
{

    const char *recipe = "test_hough";


    /*
     * Input parameters
     */

    const char *xcolumn;
    const char *ycolumn;

    /*
     * CPL objects
     */

    cpl_table *table = NULL;
    cpl_table *output = NULL;

    /*
     * Auxiliary variables
     */

    int  nframes;

    cpl_msg_set_indentation(2);


    /* 
     * Get configuration parameters
     */

    cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe);
    cpl_msg_indent_more();

    xcolumn = dfs_get_parameter_string(parlist, 
                                       "fors.test_hough.xcolumn", NULL);
    ycolumn = dfs_get_parameter_string(parlist, 
                                       "fors.test_hough.ycolumn", NULL);

    if (cpl_error_get_code())
        test_hough_exit("Failure getting the configuration parameters");

    /* 
     * Check input set-of-frames
     */

    cpl_msg_indent_less();
    cpl_msg_info(recipe, "Check input set-of-frames:");
    cpl_msg_indent_more();

    nframes = cpl_frameset_count_tags(frameset, "TABLE");

    if (nframes == 0)
        test_hough_exit("Missing input table");

    if (nframes > 1) {
        cpl_msg_error(recipe, "Too many input tables found (%d). "
                      "Just one is required.", nframes);
        test_hough_exit(NULL);
    }

    cpl_msg_info(recipe, "Load %s frame...", "TABLE");
    cpl_msg_indent_more();

    table = dfs_load_table(frameset, "TABLE", 1);

    output = mos_hough_table(table, xcolumn, ycolumn);
    cpl_table_delete(table); table = NULL;

    if (dfs_save_table(frameset, output, "TRANSFORMED", NULL,
                       parlist, recipe, "test_version"))
        test_hough_exit(NULL);

    cpl_table_delete(output); output = NULL;

    return 0;

} 
