/*                                                                            *
 *   This file is part of the ESO X-shooter Pipeline                          *
 *   Copyright (C) 2006 European Southern Observatory                         *
 *                                                                            *
 *   This library 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, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA     *
 *                                                                            */

/*
 * $Author: amodigli $
 * $Date $
 * $Revision: 1.19 $
 */

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

/*----------------------------------------------------------------------------*/
/**
 * @defgroup xsh_subtract_sky_nod  Subtract Sky NOD Frames
 * @ingroup drl_functions
 *
 * Function ...
 */
/*----------------------------------------------------------------------------*/
/**@{*/

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

#include <math.h>
#include <xsh_drl.h>

#include <xsh_badpixelmap.h>
#include <xsh_data_pre.h>
#include <xsh_data_order.h>
#include <xsh_data_wavemap.h>
#include <xsh_data_localization.h>
#include <xsh_data_rec.h>
#include <xsh_dfs.h>
#include <xsh_pfits.h>
#include <xsh_error.h>
#include <xsh_msg.h>
#include <xsh_fit.h>
#include <xsh_badpixelmap.h>

#include <cpl.h>

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

/*-----------------------------------------------------------------------------
  Implementation
  -----------------------------------------------------------------------------*/
static void save_pre_frame( cpl_frame * frame, xsh_instrument * instrument,
  cpl_frame *B_frame)
{
  xsh_pre *pre = NULL;
  cpl_frame * res_frame = NULL ;
  const char * fname = NULL ;
  cpl_propertylist *list_B = NULL;
  const char * name_B = NULL;
  double ra_off_B, dec_off_B;
  double ra_cumoff_B, dec_cumoff_B;

  /* Load pre frame */
  fname = cpl_frame_get_filename( frame);
  name_B = cpl_frame_get_filename( B_frame);
  check( pre = xsh_pre_load( frame, instrument));
  check( list_B = cpl_propertylist_load( name_B, 0));
  
  check( ra_off_B = xsh_pfits_get_ra_reloffset( list_B));
  check( dec_off_B = xsh_pfits_get_dec_reloffset( list_B));

  check( ra_cumoff_B = xsh_pfits_get_ra_cumoffset( list_B));
  check( dec_cumoff_B = xsh_pfits_get_dec_cumoffset( list_B));

  check( xsh_pfits_set_b_ra_reloffset( pre->data_header, ra_off_B));
  check( xsh_pfits_set_b_dec_reloffset( pre->data_header, dec_off_B));

  check( xsh_pfits_set_b_ra_cumoffset( pre->data_header, ra_cumoff_B));
  check( xsh_pfits_set_b_dec_cumoffset( pre->data_header, dec_cumoff_B));

  /* Save it */
  check( res_frame = xsh_pre_save( pre, fname, "FRAME_PRE_FORMAT", 1));

  cleanup:
    xsh_pre_free( &pre);
    xsh_free_propertylist( &list_B);
    xsh_free_frame( &res_frame);
    return;
}

/** 
 * Subtract A to B frames. Note that the order of input frames MUST be
 *   AB[B1A1...]. In the output frameset, we always have A-B, B-A, A1-B1, B1-A1
 *   in this order.
 * 
 * @param raws_ord_set Raw frames frameset
 * @param instrument Pointer to instrument structure
 * @param mode_fast specify of fast mode is set
 * @return Frameset of A-B and B-A frames
 */


/*****************************************************************************/
/*****************************************************************************/
cpl_frameset* xsh_subtract_sky_nod( cpl_frameset *raws_ord_set, 
  xsh_instrument *instrument, int mode_fast)
{
  int i, size;
  cpl_frameset* result = NULL;
  const char* arm_name = NULL;
  //char * a_b_name = NULL;

  XSH_ASSURE_NOT_NULL( raws_ord_set);
  XSH_ASSURE_NOT_NULL( instrument);

  check( arm_name = xsh_instrument_arm_tostring( instrument));
  check( size = cpl_frameset_get_size( raws_ord_set));
  result = cpl_frameset_new();

  for( i = 0; i< size; i += 2) {
    char frame_name[256];
    cpl_frame * a = NULL, * b = NULL, *a_b = NULL, *b_a = NULL;

    check( a = cpl_frameset_get_frame( raws_ord_set, i)) ;
    check( b = cpl_frameset_get_frame( raws_ord_set, i+1));
    sprintf( frame_name, "SUBTRACTED_NOD_AB_%d_%s.fits", i/2, arm_name);

    check( a_b = xsh_pre_frame_subtract( a, b, frame_name, instrument,1)) ;
    save_pre_frame( a_b, instrument, b);
    check(cpl_frameset_insert( result, a_b)) ;
    xsh_add_temporary_file(frame_name);
    if (mode_fast != CPL_TRUE){
      /* check why the full subtraction is done again and we do not use B-A=-(A-B) */
      sprintf( frame_name, "SUBTRACTED_NOD_BA_%d_%s.fits", i/2, arm_name);
      check( b_a = xsh_pre_frame_subtract( b, a, frame_name, instrument,0)) ;
      save_pre_frame( b_a, instrument, b);
      check(cpl_frameset_insert( result, b_a)) ;
    }
  }

 cleanup:
    if ( cpl_error_get_code() != CPL_ERROR_NONE){
      xsh_free_frameset( &result);
    }
    return result ;

}
/*****************************************************************************/

/**@}*/
