/*                                                                           *
 *   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: 2011-12-09 10:05:11 $
 * $Revision: 1.24 $
 * $Name: not supported by cvs2svn $
 */
#ifndef XSH_DATA_WAVESOL_H
#define XSH_DATA_WAVESOL_H

#include <cpl.h>
#include <xsh_cpl_size.h>
#include <xsh_parameters.h>

#define XSH_SLIT_RANGE 1.2

#define XSH_WAVESOL_TABLE_NB_COL 4
#define XSH_WAVESOL_TABLE_NB_ROWS 2
#define XSH_WAVESOL_TABLE_COLNAME_AXIS "AXIS"
#define XSH_WAVESOL_TABLE_COLNAME_DEGLAMBDA "DEGLAMBDA"
#define XSH_WAVESOL_TABLE_COLNAME_DEGORDER "DEGORDER"
#define XSH_WAVESOL_TABLE_COLNAME_DEGSLIT "DEGSLIT"

enum wavesol_type{
  XSH_WAVESOL_GUESS,
  XSH_WAVESOL_2D,
  XSH_WAVESOL_UNDEFINED
};
 
typedef struct{
  enum wavesol_type type;
  int bin_x;
  int bin_y;
  cpl_polynomial* polx;
  cpl_polynomial* poly;
  cpl_propertylist* header;
  cpl_vector* dim;
  int * coefs;
  int nbcoefs;
  int deg_slit;
  int deg_order;
  int deg_lambda;
  double min_lambda;
  double max_lambda;
  double min_order;
  double max_order;
  double min_slit;
  double max_slit;
  double min_x;
  double max_x;
  double min_y;
  double max_y;

} xsh_wavesol;

//xsh_wavesol* xsh_wavesol_create(cpl_frame* frame);
xsh_wavesol* xsh_wavesol_create( 
  cpl_frame* spectral_format_frame, xsh_detect_arclines_param* p,
  xsh_instrument *instrument);

xsh_wavesol * xsh_wavesol_duplicate( xsh_wavesol * org ) ;
void xsh_wavesol_add_poly( xsh_wavesol * to, xsh_wavesol * from ) ;
void xsh_wavesol_dump( xsh_wavesol * wsol, const char * fname, int nb ) ;

void xsh_wavesol_set_type(xsh_wavesol * wsol, enum wavesol_type type);
enum wavesol_type xsh_wavesol_get_type(xsh_wavesol *wsol);

cpl_polynomial* xsh_wavesol_get_poly(xsh_wavesol* sol);
cpl_polynomial* xsh_wavesol_get_polx(xsh_wavesol* sol);
cpl_propertylist* xsh_wavesol_get_header(xsh_wavesol* sol);
double xsh_wavesol_eval_polx(xsh_wavesol* sol, double lambda, double order,
  double slit);
double xsh_wavesol_eval_poly(xsh_wavesol* sol, double lambda, double order,
  double slit);
void xsh_wavesol_compute(xsh_wavesol* sol, int size, 
  double* posdata, double *minpos, double *maxpos, double* lambda, double* order, 
  double* slit, cpl_polynomial* res);
void xsh_wavesol_residual(xsh_wavesol* sol, xsh_wavesol * adj, int size, 
			  double* new_pos, double* lambda, 
			  double* order, double* slit,
			  cpl_polynomial* result, char axis) ;

cpl_frame* 
xsh_wavesol_save(xsh_wavesol *w, cpl_table* trace, const char* filename,const char* tag);
void xsh_wavesol_free(xsh_wavesol** w);
xsh_wavesol * xsh_wavesol_load( cpl_frame * frame,
				xsh_instrument * instrument ) ;
cpl_table* 
xsh_wavesol_trace( xsh_wavesol * wsol, double* lambda, 
		   double* order, double* slit,int size);
void xsh_wavesol_set_bin_x( xsh_wavesol * wsol, int bin ) ;
void xsh_wavesol_set_bin_y( xsh_wavesol * wsol, int bin ) ;
void xsh_wavesol_apply_shift( xsh_wavesol *wsol, float shift_x, float shift_y);

#endif  /* XSH_WAVESOL_H */
