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

/**
    @defgroup kmo_priv_shift_test   kmo_priv_shift unit tests

    @{
*/

void kmo_test_verbose_off();
void kmo_test_verbose_on();

/**
    @brief   test for kmo_priv_shift()
*/
void test_kmo_priv_shift()
{
    kmo_test_verbose_off();
    kmo_priv_shift(NULL, NULL, NULL, NULL, 3, 3, 2, 2, "NN",
                   NONE_CLIPPING, FALSE);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_imagelist *data = NULL;
    kmo_priv_shift(&data, NULL, NULL, NULL, 3, 3, 2, 2, "NN",
                   NONE_CLIPPING, FALSE);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    data = cpl_imagelist_new();
    kmo_priv_shift(&data, NULL, NULL, NULL, 3, 3, 2, 2, "NN",
                   NONE_CLIPPING, FALSE);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_propertylist *pld = NULL;
    kmo_priv_shift(&data, NULL, &pld, NULL, 3, 3, 2, 2, "NN",
                   NONE_CLIPPING, FALSE);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    pld = cpl_propertylist_new();
    kmo_priv_shift(&data, NULL, &pld, NULL, 3, 3, 2, 2, "NN",
                   NONE_CLIPPING, FALSE);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    // unsupported method
    kmo_priv_shift(&data, NULL, &pld, NULL, 3, 3, 2, 2, "NN",
                   RESIZE_BCS_NATURAL, FALSE);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    // empty imagelist
    kmo_priv_shift(&data, NULL, &pld, NULL, 3, 3, 2, 2, "BCS",
                   RESIZE_BCS_NATURAL, FALSE);
    cpl_test_error(CPL_ERROR_ILLEGAL_INPUT);

    kmo_test_verbose_on();

    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);
    cpl_image *img = cpl_image_new(10,10, CPL_TYPE_FLOAT);
    kmo_image_fill(img, 0);
    cpl_image_set(img, 3, 3, 1);
    cpl_imagelist_set(data, img, 0);
    kmo_priv_shift(&data, NULL, &pld, NULL, 3, 3, 1, 2, "BCS",
                   RESIZE_BCS_NATURAL, FALSE);
    cpl_test_error(CPL_ERROR_NONE);

    cpl_propertylist_update_double(pld, CRPIX1, 5.5);
    cpl_propertylist_update_double(pld, CRPIX2, 7.0);
    kmo_priv_shift(&data, NULL, &pld, NULL, 3, 3, 1, 2, "BCS",
                   RESIZE_BCS_NATURAL, FALSE);
    cpl_test_abs(-0.5, cpl_propertylist_get_double(pld, CRPIX1), 0.01);
    cpl_test_abs(13, cpl_propertylist_get_double(pld, CRPIX2), 0.01);
    cpl_test_error(CPL_ERROR_NONE);

    // test also with noise
    kmo_test_verbose_off();
    cpl_imagelist *noise = NULL;
    kmo_priv_shift(&data, &noise, &pld, NULL, 3, 3, 1, 2, "BCS",
                   RESIZE_BCS_NATURAL, FALSE);
    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_shift(&data, &noise, &pld, NULL, 3, 3, 1, 2, "BCS",
                   RESIZE_BCS_NATURAL, FALSE);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    cpl_propertylist *pln = NULL;
    kmo_priv_shift(&data, &noise, &pld, &pln, 3, 3, 1, 2, "BCS",
                   RESIZE_BCS_NATURAL, FALSE);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    kmo_test_verbose_on();

    pln = cpl_propertylist_new();
    kmo_priv_shift(&data, &noise, &pld, &pln, 3, 3, 1, 2, "BCS",
                   RESIZE_BCS_NATURAL, FALSE);
    cpl_test_error(CPL_ERROR_NONE);

    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, 5.5);
    cpl_propertylist_update_double(pld, CRPIX2, 7.0);
    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);
    cpl_propertylist_update_double(pld, CRPIX1, 5.5);
    cpl_propertylist_update_double(pld, CRPIX2, 7.0);
    cpl_propertylist_update_int(pln, "PCOUNT", 0);
    cpl_propertylist_update_int(pln, "GCOUNT", 1);
    cpl_propertylist_update_double(pln, CRPIX1, 5.5);
    cpl_propertylist_update_double(pln, CRPIX2, 7.0);
    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_shift(&data, &noise, &pld, &pln, 3, 3, 1, 2, "BCS",
                   RESIZE_BCS_NATURAL, FALSE);
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_abs(-0.5, cpl_propertylist_get_double(pld, CRPIX1), 0.01);
    cpl_test_abs(13, cpl_propertylist_get_double(pld, CRPIX2), 0.01);
    cpl_test_abs(-0.5, cpl_propertylist_get_double(pln, CRPIX1), 0.01);
    cpl_test_abs(13, cpl_propertylist_get_double(pln, CRPIX2), 0.01);
    cpl_propertylist_delete(pln);
    cpl_propertylist_delete(pld);

    pld = cpl_propertylist_new();
    pln = cpl_propertylist_new();
    cpl_propertylist_update_int(pld, "PCOUNT", 0);
    cpl_propertylist_update_int(pld, "GCOUNT", 1);
    cpl_propertylist_update_double(pld, CRPIX1, 5.5);
    cpl_propertylist_update_double(pld, CRPIX2, 7.0);
    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);
    cpl_propertylist_update_double(pld, CRPIX1, 5.5);
    cpl_propertylist_update_double(pld, CRPIX2, 7.0);
    cpl_propertylist_update_int(pln, "PCOUNT", 0);
    cpl_propertylist_update_int(pln, "GCOUNT", 1);
    cpl_propertylist_update_double(pln, CRPIX1, 5.5);
    cpl_propertylist_update_double(pln, CRPIX2, 7.0);
    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);

    img = cpl_image_new(10,10, CPL_TYPE_FLOAT);
    kmo_image_fill(img, 1);
    cpl_imagelist_set(data, img, 1);
    img = cpl_image_new(10,10, CPL_TYPE_FLOAT);
    kmo_image_fill(img, .1);
    cpl_imagelist_set(noise, img, 1);

    kmo_priv_shift(&data, &noise, &pld, &pln, 2.1, -0.5, 1, 2, "BCS",
                   BCS_NATURAL, FALSE);
    cpl_test_error(CPL_ERROR_NONE);
    cpl_test_abs(1.3, cpl_propertylist_get_double(pld, CRPIX1), 0.01);
    cpl_test_abs(6, cpl_propertylist_get_double(pld, CRPIX2), 0.01);
    cpl_test_abs(1.3, cpl_propertylist_get_double(pln, CRPIX1), 0.01);
    cpl_test_abs(6, cpl_propertylist_get_double(pln, CRPIX2), 0.01);
    cpl_test_abs(0.4, kmo_imagelist_get_mean(data), 0.0001);
    cpl_test_abs(0.04, 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_shift
*/
int main()
{
    cpl_test_init("<usd-help@eso.org>", CPL_MSG_WARNING);

    test_kmo_priv_shift();

    return cpl_test_end(0);
}

/** @} */
