/*                                                                            *
 *   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:10:13 $
 * $Revision: 1.5 $
 * $Name: not supported by cvs2svn $
 */
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

/*--------------------------------------------------------------------------*/
/**
 * @defgroup test_xsh_tests_create_map Test Create SLITMAP and WAVEMAP
 * @ingroup unit_tests
 *
 */
/*--------------------------------------------------------------------------*/
/**@{*/

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


#include <xsh_data_pre.h>
#include <xsh_error.h>
#include <xsh_msg.h>
#include <xsh_data_instrument.h>
#include <xsh_parameters.h>
#include <xsh_dfs.h>
#include <xsh_pfits.h>
#include <tests.h>
#include <cpl.h>
#include <math.h>
#include <getopt.h>
#include <string.h>
#include <xsh_model_utils.h>
/*---------------------------------------------------------------------------
                            Defines
 ---------------------------------------------------------------------------*/
#define MODULE_ID "XSH_CREATE_MAP"

enum {
  DEBUG_OPT, HELP_OPT
};

static struct option LongOptions[] = {
  {"debug", required_argument, 0, DEBUG_OPT},
  {"help", 0, 0, HELP_OPT},
  {NULL, 0, 0, 0}
};

static void Help( void )
{
  puts ("Unitary test : Create a slitmap and a wavemap from a set of files (SOF)");
  puts( "Usage : ./the_xsh_data_wave_tab_2d [options] <SOF>");

  puts( "Options" ) ;
  puts( " --debug=<n>        : Level of debug LOW | MEDIUM | HIGH [MEDIUM]" );
  puts( " --help             : What you see" ) ;

  puts( "The input files argument MUST be in this order:" );
  puts( " 1. PRE frame");
  puts( " 2. SOF a) MODEL     : [XSH_MOD_CFG_TAB_UVB]");
  puts( "        b) POLYNOMIAL: [DISP_TAB, ORDER_TAB_EDGES]");
  
  TEST_END();
  exit(0);
}

static void HandleOptions( int argc, char ** argv)
{
  int opt ;
  int option_index = 0;

  while( (opt = getopt_long( argc, argv, "debug:help",
                             LongOptions, &option_index )) != EOF){
    switch( opt ) {
    case DEBUG_OPT:
      if ( strcmp( optarg, "LOW")==0){
        xsh_debug_level_set( XSH_DEBUG_LEVEL_LOW);
      }
      else if ( strcmp( optarg, "HIGH")==0){
        xsh_debug_level_set( XSH_DEBUG_LEVEL_HIGH);
      }
      break;
    case HELP_OPT:
      Help();
      break;
    default:
      break;
    }
  }
}
/*---------------------------------------------------------------------------
                         Functions prototypes
 ---------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------*/
/**
  @brief    Create a SLITMAP and a WAVEMAP from Set Of Files (SOF)
  @return   0 if success

  Test the Data Reduction Library function XSH_CREATE_MAP
 */
/*--------------------------------------------------------------------------*/

int main( int argc, char** argv)
{
  xsh_instrument * instrument = NULL ;
  cpl_frameset* set = NULL;
  char *sof_name = NULL;
  char *pre_name = NULL;
  cpl_frame *pre_frame = NULL;
  cpl_propertylist *pre_header = NULL;
  cpl_frame *model_frame = NULL;
  cpl_frame *disptab_frame = NULL;
  cpl_frame *ordertab_frame = NULL;
  cpl_frame *wavemap_frame = NULL;
  cpl_frame *slitmap_frame = NULL;
  bool use_model;
  int binx=1;
  int biny=1;
  int ret =0;
  char wavemap_name[256];
  char slitmap_name[256];

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

  HandleOptions( argc, argv);

  /* Analyse parameters */
  if ( (argc-optind) >= 2) {
    pre_name = argv[optind];
    sof_name = argv[optind+1];
    /* Create frameset from sof */
    check( set = sof_to_frameset( sof_name));

    /* Validate frame set */
    check( instrument = xsh_dfs_set_groups( set));
    check( pre_header = cpl_propertylist_load( pre_name, 0));
    if ( xsh_instrument_get_arm( instrument) != XSH_ARM_NIR){
      check( binx = xsh_pfits_get_binx( pre_header));
      check( biny = xsh_pfits_get_biny( pre_header));
    }
    instrument->binx = binx;
    instrument->biny = biny;
    TESTS_XSH_FRAME_CREATE( pre_frame, "PRE", pre_name); 
    
    /* one should have either model config frame or wave sol frame */
    if((model_frame = xsh_find_frame_with_tag( set,
                                               XSH_MOD_CFG_OPT_2D,
                                               instrument)) == NULL) {

       xsh_error_reset();

       if ((model_frame = xsh_find_frame_with_tag( set,XSH_MOD_CFG_TAB,
                                               instrument)) == NULL) {
       xsh_error_reset();
       }

    }
    xsh_error_reset();

    cpl_error_reset();
    if ( model_frame == NULL){
      xsh_msg("Using polynomial solution to produce map");
      check( disptab_frame = xsh_find_disp_tab( set, instrument));
      check( ordertab_frame = xsh_find_order_tab_edges( set, instrument));
      use_model = FALSE;
    }
    else{
      xsh_msg("Using model to produce map");
      use_model = TRUE;
    }
  }
  else{
    Help();
  }
    xsh_msg("PRE binning %dx%d : %s", binx, biny, cpl_frame_get_filename( pre_frame));

  if (use_model){
    int found_temp=true;

    sprintf( wavemap_name, "model_%dx%d_WAVE_MAP", binx, biny);
    sprintf( slitmap_name, "model_%dx%d_SLIT_MAP", binx, biny);
    xsh_msg("MODEL            : %s", cpl_frame_get_filename( model_frame));
    check( xsh_model_temperature_update_frame(&model_frame, pre_frame,
      instrument,&found_temp));
    check( xsh_create_model_map( model_frame, instrument,
                                 wavemap_name, slitmap_name, 
                                 &wavemap_frame, &slitmap_frame,0));
  }
  else{
    xsh_msg("DISPERSION TAB  : %s", cpl_frame_get_filename( disptab_frame));
    xsh_msg("ORDER TAB       : %s", cpl_frame_get_filename( ordertab_frame));

    sprintf( wavemap_name, "poly_%dx%d", binx, biny);

    check( xsh_create_map( disptab_frame, ordertab_frame, pre_frame, 
      instrument, &wavemap_frame, &slitmap_frame, wavemap_name));
  }

  xsh_msg( "Created SLITMAP: %s", cpl_frame_get_filename( slitmap_frame));
  xsh_msg( "Created WAVEMAP: %s", cpl_frame_get_filename( wavemap_frame));
  cleanup:
    xsh_instrument_free( &instrument);
    xsh_free_frameset( &set);
    xsh_free_frame( &pre_frame);
    xsh_free_propertylist( &pre_header);
    xsh_free_frame( &wavemap_frame);
    xsh_free_frame( &slitmap_frame);

    if (cpl_error_get_code() != CPL_ERROR_NONE) {
      xsh_error_dump( CPL_MSG_ERROR);
      ret = 1;
    } 
    TEST_END();
    return ret;
}

/**@}*/
