/* $Id: visir_recipes_test.c,v 1.3 2012-03-20 12:38:51 llundin Exp $
 *
 * This file is part of the VISIR Pipeline
 * Copyright (C) 20011 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: 2012-03-20 12:38:51 $
 * $Revision: 1.3 $
 * $Name: not supported by cvs2svn $
 */

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

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

#include "visir_recipes_test.h"

#include <irplib_utils.h>

#include <math.h>


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

static cpl_error_code visir_util_clip_test_one_fill_frameset(cpl_frameset *);
static cpl_error_code visir_util_clip_test_one_save_imagelist(const char *);
static cpl_error_code visir_util_clip_test_one_save_bpm(const char *);

/*----------------------------------------------------------------------------*/
/**
 * @defgroup visir_recipes_test   Recipe specific tests
 */
/*----------------------------------------------------------------------------*/

/**@{*/

/*-----------------------------------------------------------------------------
                            Function definitions
 -----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------*/
/**
  @brief    Find a plugin and submit it to some tests
  @param    self   A non-empty pluginlist
  @return   void

 */
/*----------------------------------------------------------------------------*/
void visir_util_clip_test_one(cpl_pluginlist * self) {

    cpl_plugin     * plugin;
    cpl_recipe     * recipe;
    int            (*recipe_create) (cpl_plugin *);
    int            (*recipe_exec  ) (cpl_plugin *);
    int            (*recipe_deinit) (cpl_plugin *);
    cpl_error_code error;


    plugin = cpl_pluginlist_get_first(self);
    cpl_test_nonnull(plugin);

    if (plugin == NULL) return;

    recipe_create = cpl_plugin_get_init(plugin);
    cpl_test( recipe_create != NULL);

    recipe_exec   = cpl_plugin_get_exec(plugin);
    cpl_test( recipe_exec != NULL);

    recipe_deinit = cpl_plugin_get_deinit(plugin);
    cpl_test( recipe_deinit != NULL);

    /* Only plugins of type recipe are tested (further)  */
    cpl_test_eq(cpl_plugin_get_type(plugin), CPL_PLUGIN_TYPE_RECIPE);

    if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return;

    cpl_test_zero(recipe_create(plugin));

    recipe = (cpl_recipe *) plugin;

    cpl_test_nonnull( recipe->parameters );

    recipe->frames = cpl_frameset_new();

    error = visir_util_clip_test_one_fill_frameset(recipe->frames);
    cpl_test_eq_error(error, CPL_ERROR_NONE);

    error = recipe_exec(plugin);

    cpl_test_eq_error(error, CPL_ERROR_NONE);

    cpl_frameset_delete(recipe->frames);

    error = recipe_deinit(plugin);
    cpl_test_eq_error(error, CPL_ERROR_NONE);

    return;
}

/**@}*/

static
cpl_error_code visir_util_clip_test_one_fill_frameset(cpl_frameset * self)
{

    cpl_frame     * frame = cpl_frame_new();
    const char    * filename = "visir_util_clip_one.fits";
    const char    * bpmname  = "visir_util_clip_one_bpm.fits";

    bug_if(self == NULL);

    bug_if(visir_util_clip_test_one_save_imagelist(filename));
    bug_if(visir_util_clip_test_one_save_bpm(bpmname));

    bug_if(cpl_frame_set_filename(frame, filename));
    bug_if(cpl_frame_set_tag(frame, "RAW"));

    bug_if(cpl_frameset_insert(self, frame));

    frame = cpl_frame_new();

    bug_if(cpl_frame_set_filename(frame, bpmname));
    bug_if(cpl_frame_set_tag(frame, "BPM"));

    bug_if(cpl_frameset_insert(self, frame));
    frame = NULL;

    end_skip;

    cpl_frame_delete(frame);

    return cpl_error_get_code();

}


static
cpl_error_code visir_util_clip_test_one_save_imagelist(const char * filename)
{

    cpl_image * image = cpl_image_new(1, 1, CPL_TYPE_FLOAT);
    int i;

    skip_if(cpl_propertylist_save(NULL, filename, CPL_IO_CREATE));

    for (i = 0; i < 300; i++) {
        double value;
        if (i > 270) {
            value = 2.0;
        } else {
            const double x = 3.0 * (i - 135) / 135.0; /* sigma = 3 */
            value = 1.0 / (CPL_MATH_SQRT2PI * exp(x * x / 2.0));
        }
        bug_if(cpl_image_set(image, 1, 1, value));

        skip_if(cpl_image_save(image, filename, CPL_TYPE_FLOAT, NULL,
                               CPL_IO_EXTEND));
    }

    end_skip;

    cpl_image_delete(image);

    return cpl_error_get_code();

}


static
cpl_error_code visir_util_clip_test_one_save_bpm(const char * filename)
{

    cpl_image * image = cpl_image_new(1, 1, CPL_TYPE_INT);
    int i;

    skip_if(cpl_propertylist_save(NULL, filename, CPL_IO_CREATE));

    for (i = 0; i < 300; i++) {

        skip_if(cpl_image_save(image, filename, CPL_TYPE_FLOAT, NULL,
                               CPL_IO_EXTEND));
    }

    end_skip;

    cpl_image_delete(image);

    return cpl_error_get_code();

}
