/*
 * This file is part of the KMOS Library
 * Copyright (C) 2007-2008 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
 */

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

#include "kmclipm_constants.h"

#include "kmo_priv_extract_spec.h"
#include "kmo_cpl_extensions.h"

/**
    @defgroup kmo_priv_extract_spec_test   kmo_priv_extract_spec unit tests

    @{
*/

void kmo_test_verbose_off();
void kmo_test_verbose_on();
cpl_imagelist* kmo_test_create_cube(int x, int y, int z, int gauss, int *offset);

/**
    @brief   test for kmo_priv_extract_spec()
*/
void test_kmo_priv_extract_spec(void)
{
    float tol = 0.01;
    int offset = 0;

    cpl_imagelist *data = kmo_test_create_cube(14, 14, 14, FALSE, &offset);
    cpl_imagelist *noise = kmo_test_create_cube(14, 14, 14, FALSE, &offset);

    cpl_image *mask = cpl_image_new(5, 5, CPL_TYPE_FLOAT);
    kmo_image_fill(mask, 0.5);

    cpl_vector *spec_data = NULL,
               *spec_noise = NULL;

    /* --- invalid tests --- */
    kmo_test_verbose_off();
    kmo_priv_extract_spec(NULL, NULL, NULL, NULL, NULL);
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_priv_extract_spec(NULL, NULL, mask, NULL, NULL);
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_priv_extract_spec(NULL, NULL, mask, &spec_data, NULL);
    kmo_priv_extract_spec(data, NULL, mask, &spec_data, NULL);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    cpl_imagelist_delete(data);
    data = kmo_test_create_cube(5, 5, 5, FALSE, &offset);
    kmo_priv_extract_spec(data, noise, mask, &spec_data, NULL);
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_priv_extract_spec(data, noise, mask, &spec_data, &spec_noise);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);
    kmo_test_verbose_on();

    /* --- valid tests --- */
    cpl_imagelist_delete(noise);
    noise = kmo_test_create_cube(5, 5, 5, FALSE, &offset);
    cpl_imagelist_divide_scalar(noise, 100.0);

    kmo_priv_extract_spec(data, NULL, mask, &spec_data, NULL);
    cpl_test_error(CPL_ERROR_NONE);

    cpl_test_abs(cpl_vector_get(spec_data, 0), 41.2, tol);
    cpl_test_abs(cpl_vector_get(spec_data, 1), 42.2, tol);
    cpl_test_abs(cpl_vector_get(spec_data, 2), 43.2, tol);
    cpl_test_abs(cpl_vector_get(spec_data, 3), 44.2, tol);
    cpl_test_abs(cpl_vector_get(spec_data, 4), 45.2, tol);
    cpl_vector_delete(spec_data);

    kmo_priv_extract_spec(data, noise, mask, &spec_data, &spec_noise);
    cpl_test_error(CPL_ERROR_NONE);

    cpl_test_abs(cpl_vector_get(spec_data, 0), 41.2, tol);
    cpl_test_abs(cpl_vector_get(spec_data, 1), 42.2, tol);
    cpl_test_abs(cpl_vector_get(spec_data, 2), 43.2, tol);
    cpl_test_abs(cpl_vector_get(spec_data, 3), 44.2, tol);
    cpl_test_abs(cpl_vector_get(spec_data, 4), 45.2, tol);
    cpl_vector_delete(spec_data);

    cpl_test_abs(cpl_vector_get(spec_noise, 0), 0.468760, tol);
    cpl_test_abs(cpl_vector_get(spec_noise, 1), 0.478619, tol);
    cpl_test_abs(cpl_vector_get(spec_noise, 2), 0.488483, tol);
    cpl_test_abs(cpl_vector_get(spec_noise, 3), 0.498353, tol);
    cpl_test_abs(cpl_vector_get(spec_noise, 4), 0.508228, tol);
    cpl_vector_delete(spec_noise);

    cpl_image_delete(mask);
    mask = cpl_image_new(5, 5, CPL_TYPE_FLOAT);
    kmo_image_fill(mask, 0.0);
    cpl_image_set(mask, 2, 2, 1.0);

    kmo_priv_extract_spec(data, noise, mask, &spec_data, &spec_noise);
    cpl_test_error(CPL_ERROR_NONE);

    cpl_test_abs(cpl_vector_get(spec_data, 0), 34.6, tol);
    cpl_test_abs(cpl_vector_get(spec_data, 1), 35.6, tol);
    cpl_test_abs(cpl_vector_get(spec_data, 2), 36.6, tol);
    cpl_test_abs(cpl_vector_get(spec_data, 3), 37.6, tol);
    cpl_test_abs(cpl_vector_get(spec_data, 4), 38.6, tol);
    cpl_vector_delete(spec_data);

    cpl_test_abs(cpl_vector_get(spec_noise, 0), 0.396, tol);
    cpl_test_abs(cpl_vector_get(spec_noise, 1), 0.406, tol);
    cpl_test_abs(cpl_vector_get(spec_noise, 2), 0.416, tol);
    cpl_test_abs(cpl_vector_get(spec_noise, 3), 0.426, tol);
    cpl_test_abs(cpl_vector_get(spec_noise, 4), 0.436, tol);
    cpl_vector_delete(spec_noise);

    cpl_image_delete(mask);
    cpl_imagelist_delete(data);
    cpl_imagelist_delete(noise);

    cpl_test_error(CPL_ERROR_NONE);
}

/**
    @brief   test for kmo_priv_update_header()
*/
void test_kmo_priv_update_header(void)
{
    cpl_propertylist *pl = cpl_propertylist_new();

    // --- invalid tests ---
    kmo_test_verbose_off();
    kmo_priv_update_header(NULL);
    cpl_test_error(CPL_ERROR_NULL_INPUT);
    kmo_test_verbose_on();

    // --- valid tests ---
    cpl_propertylist_update_double(pl, CRPIX1, 3.3);
    cpl_propertylist_set_comment(pl, CRPIX1, "crpix1");
    cpl_propertylist_update_double(pl, CRPIX3, 2.2);
    cpl_propertylist_update_double(pl, CRVAL3, 1.1);
    cpl_propertylist_update_double(pl, CDELT3, 0.1);
    cpl_propertylist_update_string(pl, CTYPE3, "gaga");
    kmo_priv_update_header(pl);
    cpl_test_abs(2.2, cpl_propertylist_get_double(pl, CRPIX1), 0.01);
    cpl_test_abs(1.1, cpl_propertylist_get_double(pl, CRVAL1), 0.01);
    cpl_test_abs(0.1, cpl_propertylist_get_double(pl, CDELT1), 0.01);
    cpl_test_eq_string("gaga", cpl_propertylist_get_string(pl, CTYPE1));
    cpl_test_eq(0, cpl_propertylist_has(pl, CRPIX3));
    cpl_test_eq(0, cpl_propertylist_has(pl, CRVAL3));
    cpl_test_eq(0, cpl_propertylist_has(pl, CDELT3));
    cpl_test_eq(0, cpl_propertylist_has(pl, CTYPE3));
    cpl_test_error(CPL_ERROR_NONE);

    cpl_propertylist_delete(pl);
}

/**
    @brief   Test of helper functions for kmo_extract_spec
*/
int main(void)
{
    cpl_test_init("<usd-help@eso.org>", CPL_MSG_WARNING);

    test_kmo_priv_extract_spec();
    test_kmo_priv_update_header();

    return cpl_test_end(0);
}

/** @} */
