/* $Id: xsh_detmon_utils.c,v 1.8 2013-07-15 12:03:32 amodigli Exp $
 *
 * This file is part of the IIINSTRUMENT Pipeline
 * Copyright (C) 2002,2003 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: amodigli $
 * $Date: 2013-07-15 12:03:32 $
 * $Revision: 1.8 $
 * $Name: not supported by cvs2svn $
 */

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

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

#include "xsh_detmon_utils.h"
#include "irplib_utils.h"

#include <cpl.h>
#include <assert.h>

/**@{*/
/*----------------------------------------------------------------------------*/
/**
 * @defgroup iiinstrument_utils     Miscellaneous Utilities
 */
/*----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------*/
/**
  @brief	Get the pipeline copyright and license
  @return   The copyright and license string

  The function returns a pointer to the statically allocated license string.
  This string should not be modified using the returned pointer.
 */
/*----------------------------------------------------------------------------*/
const char * xsh_detmon_get_license(void)
{
    const char  *   xsh_detmon_license = 
        "This file is part of the DETMON Instrument Pipeline\n"
        "Copyright (C) 2002,2003 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\n"
        "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, \n"
        "MA  02111-1307  USA" ;
    return xsh_detmon_license ;
}


/* ---------------------------------------------------------------------------*/
/**
 * @brief utility to convert negative region to full image
 *
 * @param ref reference image, region set to image size
 * @param llx  lower left X coordinate
 * @param lly  lower left Y coordinate
 * @param urx  upper right X coordinate
 * @param ury  upper right Y coordinate
 *
 */
/* ---------------------------------------------------------------------------*/
static void expand_region(const cpl_image * ref,
                          cpl_size * llx,
                          cpl_size * lly,
                          cpl_size * urx,
                          cpl_size * ury)
{
    if (*llx < 1)
        *llx = 1;
    if (*lly < 1)
        *lly = 1;
    if (*urx < 1)
        *urx = cpl_image_get_size_x(ref);
    if (*ury < 1)
        *ury = cpl_image_get_size_y(ref);
}


/* ---------------------------------------------------------------------------*/
/**
 * @brief load data in frameset into an imagelist
 *
 * @param fset   frameset to load from
 * @param type   type to convert data to
 * @param pnum   plane number in cube to load (0 for first)
 * @param xtnum  extension in file to load (0 for first, -1 for all)
 * @param llx    lower left x
 * @param lly    lower left y
 * @param urx    upper right x
 * @param ury    upper right y
 * @param nx     output image size x
 * @param ny     output image size y
 *
 * @return imagelist of loaded images padded to nx/ny
 * @note pads images with zeros to output image size
 *       unlike cpl_imagelist_frameset_load no support for
 *       loading multiple planes
 */
/* ---------------------------------------------------------------------------*/
cpl_imagelist *
xsh_detmon_load_frameset_window(const cpl_frameset * fset, cpl_type type,
                            cpl_size pnum, cpl_size xtnum,
                            cpl_size llx, cpl_size lly,
                            cpl_size urx, cpl_size ury,
                            cpl_size nx, cpl_size ny)
{
    cpl_imagelist * list = cpl_imagelist_new();
    const size_t n = cpl_frameset_get_size(fset);
    skip_if(pnum < 0);
    if (nx >= 0 && ny >= 0) {
        error_if(urx - llx + 1 > nx || ury - lly + 1 > ny ,
                 CPL_ERROR_ILLEGAL_INPUT,
                 "window size [%d:%d,%d:%d] larger than output size [%d, %d]",
                 (int)llx, (int)urx, (int)lly, (int)ury, (int)nx, (int)ny);
    }

    for (size_t i = 0; i < n; i++) {
        const cpl_frame * frm = cpl_frameset_get_position_const(fset, i);
        const char * fn = cpl_frame_get_filename(frm);
        if (xtnum  < 0) {
            cpl_size next = cpl_frame_get_nextensions(frm);
            for (size_t e = 0; e < next; e++) {
                cpl_image * image = cpl_image_load_window(fn, type, pnum, e,
                                                          llx, lly, urx, ury);
                skip_if(image == NULL);
                if(nx < 0 || ny < 0 ) {
                   cpl_imagelist_set(list, image, cpl_imagelist_get_size(list));
                } else {
                   cpl_image * full = cpl_image_new(nx, ny, type);
                   cpl_image_copy(full, image, llx, lly);
                   cpl_image_delete(image);
                   cpl_imagelist_set(list, full, cpl_imagelist_get_size(list));
                }

            }
        }
        else {
            cpl_image * image = cpl_image_load_window(fn, type, pnum, xtnum,
                                                      llx, lly, urx, ury);
            skip_if(image == NULL);
            if(nx < 0 || ny < 0 ) {
                cpl_imagelist_set(list, image, cpl_imagelist_get_size(list));
            } else {
                cpl_image * full = cpl_image_new(nx, ny, type);
                cpl_image_copy(full, image, llx, lly);
                cpl_image_delete(image);
                cpl_imagelist_set(list, full, cpl_imagelist_get_size(list));
            }
        }
    }

    end_skip;

    if (cpl_error_get_code()) {
        cpl_imagelist_delete(list);
        return NULL;
    }

    return list;
}


/* ---------------------------------------------------------------------------*/
/**
 * @brief subtract window two images creating new image of window size
 *
 * @param a image
 * @param b image
 * @param llx  lower left X coordinate
 * @param lly  lower left Y coordinate
 * @param urx  upper right X coordinate
 * @param ury  upper right Y coordinate
 *
 * @return image of window size
 */
/* ---------------------------------------------------------------------------*/
cpl_image * xsh_detmon_subtract_create_window(const cpl_image * a,
                                          const cpl_image * b,
                                          cpl_size llx,
                                          cpl_size lly,
                                          cpl_size urx,
                                          cpl_size ury)
{
    cpl_image * na = cpl_image_extract(a, llx, lly, urx, ury);
    cpl_image * nb = cpl_image_extract(b, llx, lly, urx, ury);
    cpl_image_subtract(na, nb);
    cpl_image_delete(nb);

    return na;
}


/* ---------------------------------------------------------------------------*/
/**
 * @brief return absolute average of subtracted images
 *
 * @param on1  first on image
 * @param off1 first off image
 * @param on2  second on image
 * @param off2 second off image
 * @param off2 second off image
 * @param llx  lower left X coordinate
 * @param lly  lower left Y coordinate
 * @param urx  upper right X coordinate
 * @param ury  upper right Y coordinate
 *
 * @return abs(avg((on1 - off1), (on2 - off2)))
 */
/* ---------------------------------------------------------------------------*/
cpl_image * xsh_detmon_subtracted_avg(const cpl_image * on1,
                                  const cpl_image * off1,
                                  const cpl_image * on2,
                                  const cpl_image * off2,
                                  cpl_size llx, cpl_size lly,
                                  cpl_size urx, cpl_size ury)
{
    expand_region(on1, &llx, &lly, &urx, &ury);
    cpl_image * dif1 = cpl_image_extract(on1, llx, lly, urx, ury);
    cpl_image * dif2 = cpl_image_extract(on2, llx, lly, urx, ury);
    cpl_image * b = cpl_image_extract(off1, llx, lly, urx, ury);
    cpl_image * dif_avg;

    cpl_image_subtract(dif1, b);
    if (off1 != off2) {
        cpl_image_delete(b);
        b = cpl_image_extract(off2, llx, lly, urx, ury);
        cpl_image_subtract(dif1, b);
    }
    else {
        cpl_image_subtract(dif2, b);
    }
    cpl_image_delete(b);

    dif_avg = cpl_image_average_create(dif1, dif2);
    cpl_image_abs(dif_avg);

    cpl_image_delete(dif1);
    cpl_image_delete(dif2);

    return dif_avg;
}

/**@}*/

