/*                                                                           *
 *   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-12-18 14:15:44 $
 * $Revision: 1.13 $
 * $Name: not supported by cvs2svn $
 */

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

/*---------------------------------------------------------------------------*/
/**
 * @defgroup xsh_data_shift_tab The shift table
 * @ingroup data_handling
 */
/*---------------------------------------------------------------------------*/

/**@{*/


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

#include <xsh_data_shift_tab.h>
#include <xsh_utils.h>
#include <xsh_utils_table.h>
#include <xsh_error.h>
#include <xsh_msg.h>
#include <xsh_pfits.h>
#include <cpl.h>
#include <xsh_drl.h>
#include <math.h>

/*----------------------------------------------------------------------------
                                 Function implementation
 ----------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/** 
  @brief Load a shift table
  @param frame The shift table frame
  @param instr instrument arm and lamp setting
  @return A new allocated shift table
*/
/*---------------------------------------------------------------------------*/
xsh_shift_tab* xsh_shift_tab_load( cpl_frame *frame, xsh_instrument *instr)
{
  cpl_table *table = NULL;
  const char* tablename = NULL;
  xsh_shift_tab *result = NULL;
  XSH_MODE mode;
  double shift_cen=0, shift_up=0, shift_down=0;

  XSH_ASSURE_NOT_NULL( frame);
  check( tablename = cpl_frame_get_filename( frame));
  XSH_TABLE_LOAD( table, tablename);

  /* allocate memory */
  XSH_CALLOC( result, xsh_shift_tab, 1);

  check( mode = xsh_instrument_get_mode( instr));

  result->is_ifu = ( mode == XSH_MODE_IFU);

  if ( result->is_ifu){
    check( xsh_get_table_value( table, XSH_SHIFT_TABLE_COLNAME_YSHIFT_DOWN,
      CPL_TYPE_DOUBLE, 0, &shift_down));
    check( xsh_get_table_value( table, XSH_SHIFT_TABLE_COLNAME_YSHIFT_CEN,
      CPL_TYPE_DOUBLE, 0, &shift_cen));
    check( xsh_get_table_value( table, XSH_SHIFT_TABLE_COLNAME_YSHIFT_UP,
     CPL_TYPE_DOUBLE, 0, &shift_up));

    result->shift_y_cen = shift_cen;
    result->shift_y_down = shift_down;
    result->shift_y_up = shift_up;
  }
  else{
    check( xsh_get_table_value( table, XSH_SHIFT_TABLE_COLNAME_YSHIFT,
      CPL_TYPE_DOUBLE, 0, &shift_cen));
    result->shift_y = shift_cen;
  }
  check( result->header = cpl_propertylist_load( tablename, 0));

  cleanup:
    if ( cpl_error_get_code() != CPL_ERROR_NONE){
      xsh_shift_tab_free( &result);
    }
    XSH_TABLE_FREE( table);
    return result;
}
/*---------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------*/
/**
  @brief 
    Free memory associated to a the_arcline
  @param tab 
    The shift_tab to free
 */
/*---------------------------------------------------------------------------*/
void xsh_shift_tab_free( xsh_shift_tab **tab)
{
  if( tab && *tab) {
	  xsh_free_propertylist(&((*tab)->header));
      cpl_free( *tab);
      *tab=NULL;
  }

}
/*---------------------------------------------------------------------------*/


cpl_frame * xsh_shift_tab_save(xsh_shift_tab *tab, const char * tag,const int clean_tmp )
{
  cpl_frame * result = NULL ;
  cpl_table *table = NULL;
  cpl_propertylist *header = NULL;
  char filename[256];

  XSH_ASSURE_NOT_NULL( tab ) ;

  check( table = cpl_table_new( 1 )); /* One row */
  if ( tab->is_ifu == 0 ) {

    /* create column */
    XSH_TABLE_NEW_COL(table, XSH_SHIFT_TABLE_COLNAME_YSHIFT,
		      XSH_SHIFT_TABLE_UNIT_YSHIFT, CPL_TYPE_DOUBLE);
    /* insert data */
    check(cpl_table_set_double(table,XSH_SHIFT_TABLE_COLNAME_YSHIFT,
			       0, tab->shift_y));
  }
  else {
    /* create columns */ 
    XSH_TABLE_NEW_COL(table, XSH_SHIFT_TABLE_COLNAME_YSHIFT_DOWN,
		      XSH_SHIFT_TABLE_UNIT_YSHIFT_DOWN, CPL_TYPE_DOUBLE);
    XSH_TABLE_NEW_COL(table, XSH_SHIFT_TABLE_COLNAME_YSHIFT_CEN,
		      XSH_SHIFT_TABLE_UNIT_YSHIFT_CEN, CPL_TYPE_DOUBLE);
    XSH_TABLE_NEW_COL(table, XSH_SHIFT_TABLE_COLNAME_YSHIFT_UP,
		      XSH_SHIFT_TABLE_UNIT_YSHIFT_UP, CPL_TYPE_DOUBLE);
    /* insert data */
    check(cpl_table_set_double(table, XSH_SHIFT_TABLE_COLNAME_YSHIFT_DOWN,
			       0, tab->shift_y_down));
    check(cpl_table_set_double(table, XSH_SHIFT_TABLE_COLNAME_YSHIFT_CEN,
			       0, tab->shift_y_cen));
    check(cpl_table_set_double(table, XSH_SHIFT_TABLE_COLNAME_YSHIFT_UP,
			       0, tab->shift_y_up));
  }

  header = tab->header;

  check( xsh_pfits_set_pcatg( header, tag ) );
  sprintf(filename,"%s.fits",tag) ;
  check( cpl_table_save(table, header, NULL, filename, CPL_IO_DEFAULT));
  
  /* Create the frame */
  check(result=xsh_frame_product(filename,
				 tag,
				 CPL_FRAME_TYPE_TABLE,
				 CPL_FRAME_GROUP_PRODUCT,
				 CPL_FRAME_LEVEL_TEMPORARY));


  if(clean_tmp) {
     check (xsh_add_temporary_file( filename));
  }
  cleanup:
    if (cpl_error_get_code() != CPL_ERROR_NONE){
      xsh_free_frame(&result);
    }

    XSH_TABLE_FREE( table);
    return result ;

}


/** 
 * Create an empty shift_tab structure.
 * 
 * @param instrument Instrument structure
 * 
 * @return An empty shift_tab structure
 */
xsh_shift_tab * xsh_shift_tab_create( xsh_instrument * instrument )
{
  xsh_shift_tab * result = NULL;
  XSH_MODE mode;

  XSH_ASSURE_NOT_NULL( instrument ) ;
  /* allocate memory */
  XSH_CALLOC( result, xsh_shift_tab, 1);

  check (result->header = cpl_propertylist_new());
  check( mode = xsh_instrument_get_mode( instrument));

  result->is_ifu = ( mode == XSH_MODE_IFU);

 cleanup:
  return result ;
}

/**@}*/
