/*                                                                           *
 *   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: 2010-12-28 08:50:13 $
 * $Revision: 1.22 $
 */
#ifndef XSH_DATA_REC_H
#define XSH_DATA_REC_H

#include <cpl.h>
#include <xsh_data_instrument.h>
#include <xsh_data_pre.h>
#include <xsh_data_spectralformat.h>
#include <xsh_parameters.h>

#define XSH_REC_TABLE_NB_UVB_ORDERS 11
#define XSH_REC_TABLE_NB_VIS_ORDERS 14
#define XSH_REC_TABLE_NB_NIR_ORDERS 16

/* Column Names */
#define XSH_REC_TABLE_COLNAME_ORDER "ORDER"
#define XSH_REC_TABLE_COLNAME_NLAMBDA "NLAMBDA"
#define XSH_REC_TABLE_COLNAME_NSLIT "NSLIT"
/*
  The 2 following columns are "array" columns
  The depth (and dimension) is respectively nlambda, nslit.
*/
#define XSH_REC_TABLE_COLNAME_LAMBDA "LAMBDA"
#define XSH_REC_TABLE_COLNAME_SLIT   "SLIT"
/*
  The 3 following columns are "array" columns
  The depth is nlambda*nslit, the dimensions are nlambda and nslit.
*/
#define XSH_REC_TABLE_COLNAME_FLUX1   "FLUX1"
#define XSH_REC_TABLE_COLNAME_FLUX2   "FLUX2"
#define XSH_REC_TABLE_COLNAME_FLUX3   "FLUX3"
#define XSH_REC_TABLE_COLNAME_ERRS1   "ERRS1"
#define XSH_REC_TABLE_COLNAME_ERRS2   "ERRS2"
#define XSH_REC_TABLE_COLNAME_ERRS3   "ERRS3"
#define XSH_REC_TABLE_COLNAME_QUAL1   "QUAL1"
#define XSH_REC_TABLE_COLNAME_QUAL2   "QUAL2"
#define XSH_REC_TABLE_COLNAME_QUAL3   "QUAL3"

typedef struct{
  int order ;
  int nlambda;
  int nslit ;
  float * slit ;
  double * lambda ;
  float * data1 ;
  float * data2 ;
  float * data3 ;
  float * errs1 ;
  /* FOR IFU mode */
  float * errs2 ; 
  float * errs3 ;
  int * qual1 ;
  int * qual2 ;
  int * qual3 ;
} xsh_rec ;

typedef struct{
  int size;
  double slit_min;
  double slit_max;
  int nslit;
  //int max_nlambda ;
  //int max_nslit ;
  xsh_rec * list;
  xsh_instrument * instrument; 
  cpl_propertylist * header;
} xsh_rec_list;

/* Create / Loading */

xsh_rec_list * xsh_rec_list_create( xsh_instrument* instr);

xsh_rec_list* xsh_rec_list_create_with_size( int size, xsh_instrument *instr);

xsh_rec_list * xsh_rec_list_load( cpl_frame *frame, xsh_instrument *instr);
xsh_rec_list * xsh_rec_list_load_eso( cpl_frame *frame, xsh_instrument *instr);
xsh_rec_list* xsh_rec_list_load_eso_1d(cpl_frame* frame,xsh_instrument* instr);
/* Save */

cpl_frame* xsh_rec_list_save( xsh_rec_list * list, const char* filename,
                              const char* tag,int is_temp);

cpl_frame* xsh_rec_list_save_table(xsh_rec_list* list, const char* filename, 
                              const char* tag, int is_temp );

cpl_frame* xsh_rec_list_save2(xsh_rec_list* list, const char* filename, 
                              const char* tag);

/* Free */

void xsh_rec_list_free( xsh_rec_list ** list);

xsh_rec_list * xsh_rec_list_duplicate( xsh_rec_list * old,
				       xsh_instrument * instrument ) ;
cpl_frame * xsh_rec_list_frame_invert( cpl_frame * rec_frame,
				       const char * tag,
				       xsh_instrument * instrument ) ;

void xsh_rec_list_dump( xsh_rec_list * list, const char * fname) ;

void xsh_rec_list_set_data_size( xsh_rec_list * list, int idx, int ordnum,
  int nlambda, int ns);

void xsh_rec_list_update_header( xsh_rec_list *list, xsh_pre *pre, 
  xsh_rectify_param *rec_par,
  const char* pro_catg);

/* GET */

cpl_propertylist * xsh_rec_list_get_header( xsh_rec_list * list);

float* xsh_rec_list_get_slit( xsh_rec_list * list, int idx);

double* xsh_rec_list_get_lambda( xsh_rec_list * list, int idx);

float* xsh_rec_list_get_data1( xsh_rec_list * list, int idx);

float * xsh_rec_list_get_errs1( xsh_rec_list * list, int idx);

int * xsh_rec_list_get_qual1( xsh_rec_list * list, int idx);

int xsh_rec_list_get_order( xsh_rec_list * list, int idx);

int xsh_rec_list_get_nslit( xsh_rec_list * list, int idx);

int xsh_rec_list_get_nlambda( xsh_rec_list * list, int idx);

void xsh_rec_get_nod_kw( cpl_frame * rec_frame, double * throw,
			 double * jitter, double * reloffset,
			 double * cumoffset ) ;

double xsh_rec_list_get_slit_min( xsh_rec_list* list);
double xsh_rec_list_get_slit_max( xsh_rec_list* list);

double xsh_rec_list_get_lambda_min( xsh_rec_list* list);
double xsh_rec_list_get_lambda_max( xsh_rec_list* list);


cpl_error_code xsh_rec_list_set_slit_min( xsh_rec_list* list,const double val);
cpl_error_code xsh_rec_list_set_slit_max( xsh_rec_list* list,const double val);
void xsh_compute_slit_index( float slit_min, float slit_step,
  xsh_rec_list **from, int *slit_index_tab, int size);

void
xsh_rec_list_add(xsh_rec_list *dest, xsh_rec_list **from,
                 int *slit_index, int nb_frames, int no,
                 int method, const int decode_bp);
cpl_error_code
xsh_rec_get_nod_extract_slit_min_max(xsh_rec_list* rlist, const double slit_step,
		double* smin, double* smax);

#endif  /* XSH_REC_H */
