/*                                                                          *
 *   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: 2012-01-16 21:09:42 $
 * $Revision: 1.4 $
 */

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

/*-------------------------------------------------------------------------*/
/**
  @defgroup test_xsh_opt_extract  Test Object optimal extraction
  @ingroup unit_tests 
*/
/*-------------------------------------------------------------------------*/
/**@{*/

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

#include <tests.h>

#include <xsh_data_pre.h>
#include <xsh_data_order.h>
#include <xsh_data_wavesol.h>
#include <xsh_data_spectralformat.h>
#include <xsh_error.h>
#include <xsh_msg.h>
#include <xsh_data_instrument.h>
#include <xsh_drl.h>
#include <xsh_pfits.h>


#include <cpl.h>
#include <math.h>

/*--------------------------------------------------------------------------
  Defines
  --------------------------------------------------------------------------*/

#define MODULE_ID "XSH_DATA_WAVEMAP"

#define SYNTAX "Test the wavemap (work only for vis for now)\n"\
  "use : ./test_xsh_data_wavemap [OPTIONS] ORDER_TAB WAVESOL WAVEMAP"\
  " SPECTRALFORMAT\n"\
  "ORDER_TAB => the order table\n"\
  "WAVESOL => the wavesolution table\n"\
  "WAVEMAP => the wavemap frame\n"\
  "SPECTRALFORMAT => the spectral format table\n"

/*--------------------------------------------------------------------------
  Implementation
  --------------------------------------------------------------------------*/

/**
  @brief
    Unit test of xsh_data_wavemap
  @return
    0 if success

*/
int main( int argc, char **argv)
{
  /* Declarations */
  int ret = 0 ;
  xsh_instrument* instrument = NULL;
 
  char* order_tab_name = NULL;
  char* wavesol_name = NULL;
  char* wavemap_name = NULL;
  char* spectralformat_name = NULL;

  cpl_frame *order_tab_frame = NULL;
  cpl_frame *wavesol_frame = NULL;
  cpl_frame *wavemap_frame = NULL;
  cpl_frame *spectralformat_frame = NULL;


  /* Initialize libraries */
  TESTS_INIT( MODULE_ID);
  cpl_msg_set_level( CPL_MSG_DEBUG);
  xsh_debug_level_set( XSH_DEBUG_LEVEL_MEDIUM);

  /* Analyse parameters */
  if ( (argc ) >= 4 ) {
    order_tab_name = argv[1];
    wavesol_name = argv[2];
    wavemap_name = argv[3];
    spectralformat_name = argv[4];
  }
  else{
    printf(SYNTAX);
    exit(0);
  }
  xsh_msg(" order tab frame name %s",order_tab_name);
  xsh_msg(" wave sol frame name %s", wavesol_name);
  xsh_msg(" wave map frame name %s",wavemap_name);
  xsh_msg(" spectral format frame name %s",spectralformat_name);

  TESTS_XSH_FRAME_CREATE( order_tab_frame, "ORDER_TAB_EDGES_arm", 
    order_tab_name);
  TESTS_XSH_FRAME_CREATE( wavesol_frame, "WAVE_TAB_2D_arm", wavesol_name);
  TESTS_XSH_FRAME_CREATE( wavemap_frame, "WAVE_MAP_arm", wavemap_name);
  TESTS_XSH_FRAME_CREATE( spectralformat_frame, "SPECTRAL_FORMAT_TAB_arm", 
    spectralformat_name);

  /* Create instrument structure and fill */
  instrument = xsh_instrument_new() ;

  instrument = xsh_instrument_new();
  xsh_instrument_set_arm( instrument, XSH_ARM_VIS); 

  xsh_instrument_set_mode( instrument, XSH_MODE_SLIT ) ;
  xsh_instrument_set_lamp( instrument, XSH_LAMP_QTH_D2) ;

  
  {
    cpl_image* wavemap = NULL;
    float * wavemap_data = NULL;
    int nx, ny;
    xsh_order_list *order_list= NULL;
    xsh_wavesol *wavesol = NULL;
    int iorder=0, nblines=0;
    cpl_table *table = NULL;

    check( wavemap = cpl_image_load( cpl_frame_get_filename(  wavemap_frame),
      CPL_TYPE_FLOAT, 0, 0));
    check (nx = cpl_image_get_size_x(  wavemap));
    check (ny = cpl_image_get_size_y(  wavemap));
    check( wavemap_data = cpl_image_get_data_float( wavemap));
    check( order_list = xsh_order_list_load( order_tab_frame, instrument));
    check( wavesol = xsh_wavesol_load( wavesol_frame, instrument ));
    check( table = cpl_table_new( 6));
    XSH_TABLE_NEW_COL(table, "absorder", "",CPL_TYPE_INT);
    XSH_TABLE_NEW_COL(table, "wavelength", "",CPL_TYPE_DOUBLE);
    XSH_TABLE_NEW_COL(table, "wavemap_x", "",CPL_TYPE_DOUBLE);
    XSH_TABLE_NEW_COL(table, "wavemap_y", "",CPL_TYPE_DOUBLE);
    XSH_TABLE_NEW_COL(table, "wavesol_x", "",CPL_TYPE_DOUBLE);
    XSH_TABLE_NEW_COL(table, "wavesol_y", "",CPL_TYPE_DOUBLE);
    check(cpl_table_set_size( table, order_list->size*ny));
    /* Loop on order */
    for( iorder= 0; iorder < order_list->size; iorder++) {
      int abs_order, start_y, end_y, y;

      abs_order = order_list->list[iorder].absorder;
      check( start_y = xsh_order_list_get_starty( order_list, iorder));
      check( end_y = xsh_order_list_get_endy( order_list, iorder));

      for(y=start_y; y < end_y; y++){
        double x, x_center, y_center;
        int int_x;
        double lambda_wavemap;

        check( x= cpl_polynomial_eval_1d( order_list->list[iorder].cenpoly,
        y, NULL));
        int_x = floor(x);
        lambda_wavemap = wavemap_data[int_x+y*nx];
        check( x_center = xsh_wavesol_eval_polx( wavesol, lambda_wavemap, abs_order,
          0.0));
        check( y_center = xsh_wavesol_eval_poly( wavesol, lambda_wavemap, abs_order,
          0.0)); 
        check(cpl_table_set_int(table, "absorder", nblines, abs_order));
        check(cpl_table_set_double(table, "wavelength", nblines, lambda_wavemap));
        check(cpl_table_set_double(table, "wavemap_x", nblines, int_x));
        check(cpl_table_set_double(table, "wavemap_y", nblines, y));
        check(cpl_table_set_double(table, "wavesol_x", nblines, x_center));
        check(cpl_table_set_double(table, "wavesol_y", nblines, y_center));
        nblines++;
      }
    }
    check( cpl_table_save(table, NULL, NULL, "result.fits", CPL_IO_DEFAULT));
  }
  cleanup:
    if (cpl_error_get_code() != CPL_ERROR_NONE) {
      xsh_error_dump(CPL_MSG_ERROR);
      return 1;
    }
    else return ret ;
}

/**@}*/
