/*
 * 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 "kmo_priv_rotate.h"
#include "kmo_cpl_extensions.h"

/**
    @defgroup kmo_priv_rotate_test   kmo_priv_rotate unit tests

    @{
*/

void kmo_test_verbose_off();
void kmo_test_verbose_on();

/**
    @brief   test for kmo_priv_rotate()
*/
void test_kmo_priv_rotate()
{
    kmo_test_verbose_off();
    kmo_priv_rotate(NULL, NULL, NULL, NULL, 20, 0, 2, "NN", NONE_CLIPPING);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_imagelist *data = NULL;
    kmo_priv_rotate(&data, NULL, NULL, NULL, 20, 0, 2, "NN", NONE_CLIPPING);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    data = cpl_imagelist_new();
    kmo_priv_rotate(&data, NULL, NULL, NULL, 20, 0, 2, "NN", NONE_CLIPPING);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_propertylist *pld = NULL;
    kmo_priv_rotate(&data, NULL, &pld, NULL, 20, 0, 2, "NN", NONE_CLIPPING);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    pld = cpl_propertylist_new();
    cpl_propertylist_update_int(pld, "PCOUNT", 0);
    cpl_propertylist_update_int(pld, "GCOUNT", 1);
    cpl_propertylist_update_double(pld, CRPIX1, 1.1);
    cpl_propertylist_update_double(pld, CRPIX2, 1.2);
    cpl_propertylist_update_double(pld, CRPIX3, 1.3);
    cpl_propertylist_update_double(pld, CDELT1, -0.111);
    cpl_propertylist_update_double(pld, CDELT2, 0.122);
    cpl_propertylist_update_double(pld, CDELT3, 0.133);
    cpl_propertylist_update_int(pld, NAXIS, 3);
    cpl_propertylist_update_int(pld, NAXIS1, 10);
    cpl_propertylist_update_int(pld, NAXIS2, 10);
    cpl_propertylist_update_int(pld, NAXIS3, 2);
    cpl_propertylist_update_double(pld, CRVAL1, 10);
    cpl_propertylist_update_double(pld, CRVAL2, 11);
    cpl_propertylist_update_double(pld, CRVAL3, 11);
    cpl_propertylist_update_double(pld, CD1_1, -0.111);
    cpl_propertylist_update_double(pld, CD1_2, 0);
    cpl_propertylist_update_double(pld, CD1_3, 0);
    cpl_propertylist_update_double(pld, CD2_1, 0);
    cpl_propertylist_update_double(pld, CD2_2, 0.122);
    cpl_propertylist_update_double(pld, CD2_3, 0);
    cpl_propertylist_update_double(pld, CD3_1, 0);
    cpl_propertylist_update_double(pld, CD3_2, 0);
    cpl_propertylist_update_double(pld, CD3_3, 0.133);
//    cpl_propertylist_update_string(pld, CTYPE1, "RA---TAN");
//    cpl_propertylist_update_string(pld, CTYPE1, "DEC--TAN");
//    cpl_propertylist_update_string(pld, CTYPE3, "WAVE");
    kmo_priv_rotate(&data, NULL, &pld, NULL, 20, 2, 2, "NN", NONE_CLIPPING);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    // unsupported method
    kmo_priv_rotate(&data, NULL, &pld, NULL, 20, 0, 2, "NN", RESIZE_BCS_NATURAL);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    // empty imagelist
    kmo_priv_rotate(&data, NULL, &pld, NULL, 20, 0, 2, "BCS", RESIZE_BCS_NATURAL);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    kmo_test_verbose_on();

    cpl_image *img = cpl_image_new(10,10, CPL_TYPE_FLOAT);
    kmo_image_fill(img, 0);
    cpl_image_set(img, 3, 3, 0);
    cpl_imagelist_set(data, img, 0);
    kmo_priv_rotate(&data, NULL, &pld, NULL, 20, 0, 2, "BCS", RESIZE_BCS_NATURAL);
    cpl_test_error(CPL_ERROR_NONE);

    cpl_propertylist_update_double(pld, CDELT1, 0.1);
    cpl_propertylist_update_double(pld, CDELT2, 0.2);
    cpl_propertylist_update_double(pld, CD1_1, 0.1);
    cpl_propertylist_update_double(pld, CD2_2, 0.2);
    kmo_priv_rotate(&data, NULL, &pld, NULL, 20, 0, 2, "BCS", RESIZE_BCS_NATURAL);
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_abs(0.0998931, cpl_propertylist_get_double(pld, CD1_1), 0.00001);
    cpl_test_abs(0.00924363, cpl_propertylist_get_double(pld, CD1_2), 0.00001);
    cpl_test_abs(-0.00462182, cpl_propertylist_get_double(pld, CD2_1), 0.00001);
    cpl_test_abs(0.199786, cpl_propertylist_get_double(pld, CD2_2), 0.00001);

    // test also with noise
    kmo_test_verbose_off();
    cpl_imagelist *noise = NULL;
    kmo_priv_rotate(&data, &noise, &pld, NULL, 20, 0, 2, "BCS", RESIZE_BCS_NATURAL);
    cpl_test_error(CPL_ERROR_NONE);

    noise = cpl_imagelist_new();
    img = cpl_image_new(10,10, CPL_TYPE_FLOAT);
    kmo_image_fill(img, 0);
    cpl_image_set(img, 3, 3, 0.1);
    cpl_imagelist_set(noise, img, 0);
    kmo_priv_rotate(&data, &noise, &pld, NULL, 20, 0, 2, "BCS", RESIZE_BCS_NATURAL);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_propertylist *pln = NULL;
    kmo_priv_rotate(&data, &noise, &pld, &pln, 20, 0, 2, "BCS", RESIZE_BCS_NATURAL);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmo_test_verbose_on();

    cpl_propertylist_delete(pld);
    pld = cpl_propertylist_new();
    cpl_propertylist_update_int(pld, "PCOUNT", 0);
    cpl_propertylist_update_int(pld, "GCOUNT", 1);
    cpl_propertylist_update_double(pld, CRPIX1, 1.1);
    cpl_propertylist_update_double(pld, CRPIX2, 1.2);
    cpl_propertylist_update_double(pld, CRPIX3, 1.3);
    cpl_propertylist_update_double(pld, CDELT1, 0.1);
    cpl_propertylist_update_double(pld, CDELT2, 0.2);
    cpl_propertylist_update_double(pld, CDELT3, 0.133);
    cpl_propertylist_update_int(pld, NAXIS, 3);
    cpl_propertylist_update_int(pld, NAXIS1, 10);
    cpl_propertylist_update_int(pld, NAXIS2, 10);
    cpl_propertylist_update_int(pld, NAXIS3, 2);
    cpl_propertylist_update_double(pld, CRVAL1, 10);
    cpl_propertylist_update_double(pld, CRVAL2, 11);
    cpl_propertylist_update_double(pld, CRVAL3, 11);
    cpl_propertylist_update_double(pld, CD1_1, 0.1);
    cpl_propertylist_update_double(pld, CD1_2, 0);
    cpl_propertylist_update_double(pld, CD1_3, 0);
    cpl_propertylist_update_double(pld, CD2_1, 0);
    cpl_propertylist_update_double(pld, CD2_2, 0.2);
    cpl_propertylist_update_double(pld, CD2_3, 0);
    cpl_propertylist_update_double(pld, CD3_1, 0);
    cpl_propertylist_update_double(pld, CD3_2, 0);
    cpl_propertylist_update_double(pld, CD3_3, 0.133);
    pln = cpl_propertylist_new();
    cpl_propertylist_update_int(pln, "PCOUNT", 0);
    cpl_propertylist_update_int(pln, "GCOUNT", 1);
    cpl_propertylist_update_double(pln, CRPIX1, 1.1);
    cpl_propertylist_update_double(pln, CRPIX2, 1.2);
    cpl_propertylist_update_double(pln, CRPIX3, 1.3);
    cpl_propertylist_update_double(pln, CDELT1, 0.1);
    cpl_propertylist_update_double(pln, CDELT2, 0.2);
    cpl_propertylist_update_double(pln, CDELT3, 0.133);
    cpl_propertylist_update_int(pln, NAXIS, 3);
    cpl_propertylist_update_int(pln, NAXIS1, 10);
    cpl_propertylist_update_int(pln, NAXIS2, 10);
    cpl_propertylist_update_int(pln, NAXIS3, 2);
    cpl_propertylist_update_double(pln, CRVAL1, 10);
    cpl_propertylist_update_double(pln, CRVAL2, 11);
    cpl_propertylist_update_double(pln, CRVAL3, 11);
    cpl_propertylist_update_double(pln, CD1_1, 0.1);
    cpl_propertylist_update_double(pln, CD1_2, 0);
    cpl_propertylist_update_double(pln, CD1_3, 0);
    cpl_propertylist_update_double(pln, CD2_1, 0);
    cpl_propertylist_update_double(pln, CD2_2, 0.2);
    cpl_propertylist_update_double(pln, CD2_3, 0);
    cpl_propertylist_update_double(pln, CD3_1, 0);
    cpl_propertylist_update_double(pln, CD3_2, 0);
    cpl_propertylist_update_double(pln, CD3_3, 0.133);
    kmo_priv_rotate(&data, &noise, &pld, &pln, 20, 0, 2, "BCS", RESIZE_BCS_NATURAL);
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_abs(0.0939693, cpl_propertylist_get_double(pln, CD1_1), 0.00001);
    cpl_test_abs(-0.068404, cpl_propertylist_get_double(pln, CD1_2), 0.00001);
    cpl_test_abs(0.034202, cpl_propertylist_get_double(pln, CD2_1), 0.00001);
    cpl_test_abs(0.187939, cpl_propertylist_get_double(pln, CD2_2), 0.00001);
    cpl_propertylist_delete(pln); pln=NULL;

    cpl_propertylist_delete(pld);
    pld = cpl_propertylist_new();
    cpl_propertylist_update_int(pld, "PCOUNT", 0);
    cpl_propertylist_update_int(pld, "GCOUNT", 1);
    cpl_propertylist_update_double(pld, CRPIX1, 1.1);
    cpl_propertylist_update_double(pld, CRPIX2, 1.2);
    cpl_propertylist_update_double(pld, CRPIX3, 1.3);
    cpl_propertylist_update_double(pld, CDELT1, 0.1);
    cpl_propertylist_update_double(pld, CDELT2, 0.2);
    cpl_propertylist_update_double(pld, CDELT3, 0.133);
    cpl_propertylist_update_int(pld, NAXIS, 3);
    cpl_propertylist_update_int(pld, NAXIS1, 10);
    cpl_propertylist_update_int(pld, NAXIS2, 10);
    cpl_propertylist_update_int(pld, NAXIS3, 2);
    cpl_propertylist_update_double(pld, CRVAL1, 10);
    cpl_propertylist_update_double(pld, CRVAL2, 11);
    cpl_propertylist_update_double(pld, CRVAL3, 11);
    cpl_propertylist_update_double(pld, CD1_1, 0.1);
    cpl_propertylist_update_double(pld, CD1_2, 0);
    cpl_propertylist_update_double(pld, CD1_3, 0);
    cpl_propertylist_update_double(pld, CD2_1, 0);
    cpl_propertylist_update_double(pld, CD2_2, 0.2);
    cpl_propertylist_update_double(pld, CD2_3, 0);
    cpl_propertylist_update_double(pld, CD3_1, 0);
    cpl_propertylist_update_double(pld, CD3_2, 0);
    cpl_propertylist_update_double(pld, CD3_3, 0.133);
    cpl_propertylist_update_double(pld, CDELT1, 0.1);
    cpl_propertylist_update_double(pld, CDELT2, 0.2);
    pln = cpl_propertylist_new();
    kmo_priv_rotate(&data, &noise, &pld, &pln, 90, 0, 2, "BCS", RESIZE_BCS_NATURAL);
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_abs(0, cpl_propertylist_get_double(pld, CD1_1), 0.00001);
    cpl_test_abs(-0.2, cpl_propertylist_get_double(pld, CD1_2), 0.00001);
    cpl_test_abs(0.1, cpl_propertylist_get_double(pld, CD2_1), 0.00001);
    cpl_test_abs(0, cpl_propertylist_get_double(pld, CD2_2), 0.00001);
    cpl_test_abs(0, cpl_propertylist_get_double(pln, CD1_1), 0.00001);
    cpl_test_abs(-0.2, cpl_propertylist_get_double(pln, CD1_2), 0.00001);
    cpl_test_abs(0.1, cpl_propertylist_get_double(pln, CD2_1), 0.00001);
    cpl_test_abs(0, cpl_propertylist_get_double(pln, CD2_2), 0.00001);
    cpl_test_abs(0, kmo_imagelist_get_mean(data), 0.0001);
    cpl_test_abs(-0.00266337, kmo_imagelist_get_mean(noise), 0.0001);

    cpl_imagelist_delete(data);
    cpl_propertylist_delete(pld);
    cpl_imagelist_delete(noise);
    cpl_propertylist_delete(pln);
}

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

    test_kmo_priv_rotate();

    return cpl_test_end(0);
}

/** @} */
