/* $Id: uves_propertylist.h,v 1.11 2010-09-24 09:32:07 amodigli Exp $
 *
 * This file is part of the ESO Common Pipeline Library
 * Copyright (C) 2001-2005 European Southern Observatory
 *
 * This program 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, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 * $Author: amodigli $
 * $Date: 2010-09-24 09:32:07 $
 * $Revision: 1.11 $
 * $Name: not supported by cvs2svn $
 */

#ifndef UVES_PROPERTYLIST_H
#define UVES_PROPERTYLIST_H

/* Define appropriately to switch on/off cpl_propertylists */
#undef USE_CPL
//#define USE_CPL

#ifdef USE_CPL
/* Workaround code ahead. No, it is not nice. */
#include <cpl.h>
#include <fitsio.h>
#include <longnam.h>

#define uves_propertylist cpl_propertylist

#define uves_vector_save(a, b, c, d, e) \
 cpl_vector_save(a, b, c, d, e)
#define uves_image_save(a, b, c, d, e) \
 cpl_image_save(a, b, c, d, e)
#define uves_imagelist_save(a, b, c, d, e) \
 cpl_imagelist_save(a, b, c, d, e)
#define uves_table_save(a, b, c, d, e) \
 cpl_table_save(a, b, c, d, e)
#define uves_dfs_setup_product_header(a, b, c, d, e, f, g) \
 cpl_dfs_setup_product_header(a, b, c, d, e, f, g)
//#define uves_table_sort(a, b)
// cpl_table_sort(a, b)
#define uves_propertylist_new() \
 cpl_propertylist_new()
#define uves_propertylist_duplicate(a) \
 cpl_propertylist_duplicate(a)
#define uves_propertylist_delete(a) \
 cpl_propertylist_delete(a)
#define uves_propertylist_get_size(a) \
 cpl_propertylist_get_size(a)
#define uves_propertylist_is_empty(a) \
 cpl_propertylist_is_empty(a)
#define uves_propertylist_get_type(a, b) \
 cpl_propertylist_get_type(a, b)
#define uves_propertylist_contains(a, b) \
 cpl_propertylist_contains(a, b)
#define my_uves_propertylist_contains(a, b) \
 cpl_propertylist_contains(a, b)

#define uves_propertylist_set_comment(a, b, c) \
 cpl_propertylist_set_comment(a, b, c)
#define uves_propertylist_set_char(a, b, c) \
 cpl_propertylist_set_char(a, b, c)
#define uves_propertylist_set_bool(a, b, c) \
 cpl_propertylist_set_bool(a, b, c)
#define uves_propertylist_set_int(a, b, c) \
 cpl_propertylist_set_int(a, b, c)
#define uves_propertylist_set_long(a, b, c) \
 cpl_propertylist_set_long(a, b, c)
#define uves_propertylist_set_float(a, b, c) \
 cpl_propertylist_set_float(a, b, c)
#define uves_propertylist_set_double(a, b, c) \
 cpl_propertylist_set_double(a, b, c)
#define uves_propertylist_set_string(a, b, c) \
 cpl_propertylist_set_string(a, b, c)
#define uves_propertylist_get_const(a, b) \
 cpl_propertylist_get(a, b)
#define uves_propertylist_get(a, b) \
 cpl_propertylist_get(a, b)
#define uves_propertylist_get_comment(a, b) \
 cpl_propertylist_get_comment(a, b)
#define uves_propertylist_get_char(a, b) \
 cpl_propertylist_get_char(a, b)
#define uves_propertylist_get_bool(a, b) \
 cpl_propertylist_get_bool(a, b)
#define uves_propertylist_get_int(a, b) \
 cpl_propertylist_get_int(a, b)
#define uves_propertylist_get_long(a, b) \
 cpl_propertylist_get_long(a, b)
#define uves_propertylist_get_float(a, b) \
 cpl_propertylist_get_float(a, b)
#define uves_propertylist_get_double(a, b) \
 cpl_propertylist_get_double(a, b)
#define uves_propertylist_get_string(a, b) \
 cpl_propertylist_get_string(a, b)
#define uves_propertylist_insert_char(a, b, c, d) \
 cpl_propertylist_insert_char(a, b, c, d)
#define uves_propertylist_insert_bool(a, b, c, d) \
 cpl_propertylist_insert_bool(a, b, c, d)
#define uves_propertylist_insert_int(a, b, c, d) \
 cpl_propertylist_insert_int(a, b, c, d)
#define uves_propertylist_insert_long(a, b, c, d) \
 cpl_propertylist_insert_long(a, b, c, d)
#define uves_propertylist_insert_float(a, b, c, d) \
 cpl_propertylist_insert_float(a, b, c, d)
#define uves_propertylist_insert_double(a, b, c, d) \
 cpl_propertylist_insert_double(a, b, c, d)
#define uves_propertylist_insert_string(a, b, c, d) \
 cpl_propertylist_insert_string(a, b, c, d)
#define uves_propertylist_insert_after_char(a, b, c, d) \
 cpl_propertylist_insert_after_char(a, b, c, d)
#define uves_propertylist_insert_after_bool(a, b, c, d) \
 cpl_propertylist_insert_after_bool(a, b, c, d)
#define uves_propertylist_insert_after_int(a, b, c, d) \
 cpl_propertylist_insert_after_int(a, b, c, d)
#define uves_propertylist_insert_after_long(a, b, c, d) \
 cpl_propertylist_insert_after_long(a, b, c, d)
#define uves_propertylist_insert_after_float(a, b, c, d) \
 cpl_propertylist_insert_after_float(a, b, c, d)
#define uves_propertylist_insert_after_double(a, b, c, d) \
 cpl_propertylist_insert_after_double(a, b, c, d)
#define uves_propertylist_insert_after_string(a, b, c, d) \
 cpl_propertylist_insert_after_string(a, b, c, d)
#define uves_propertylist_prepend_char(a, b, c) \
 cpl_propertylist_prepend_char(a, b, c)
#define uves_propertylist_prepend_bool(a, b, c) \
 cpl_propertylist_prepend_bool(a, b, c)
#define uves_propertylist_prepend_int(a, b, c) \
 cpl_propertylist_prepend_int(a, b, c)
#define uves_propertylist_prepend_long(a, b, c) \
 cpl_propertylist_prepend_long(a, b, c)
#define uves_propertylist_prepend_float(a, b, c) \
 cpl_propertylist_prepend_float(a, b, c)
#define uves_propertylist_prepend_double(a, b, c) \
 cpl_propertylist_prepend_double(a, b, c)
#define uves_propertylist_prepend_string(a, b, c) \
 cpl_propertylist_prepend_string(a, b, c)
#define uves_propertylist_append_char(a, b, c) \
 cpl_propertylist_append_char(a, b, c)
#define uves_propertylist_append_bool(a, b, c) \
 cpl_propertylist_append_bool(a, b, c)
#define uves_propertylist_append_int(a, b, c) \
 cpl_propertylist_append_int(a, b, c)
#define uves_propertylist_append_long(a, b, c) \
 cpl_propertylist_append_long(a, b, c)
#define uves_propertylist_append_float(a, b, c) \
 cpl_propertylist_append_float(a, b, c)
#define uves_propertylist_append_double(a, b, c) \
 cpl_propertylist_append_double(a, b, c)
#define uves_propertylist_append_string(a, b, c) \
 cpl_propertylist_append_string(a, b, c)
#define uves_propertylist_append(a, b) \
 cpl_propertylist_append(a, b)
#define uves_propertylist_erase(a, b) \
 cpl_propertylist_erase(a, b)
#define uves_propertylist_erase_regexp(a, b, c) \
 cpl_propertylist_erase_regexp(a, b, c)
#define uves_propertylist_empty(a) \
 cpl_propertylist_empty(a)
#define uves_propertylist_update_char(a, b, c) \
 cpl_propertylist_update_char(a, b, c)
#define uves_propertylist_update_bool(a, b, c) \
 cpl_propertylist_update_bool(a, b, c)
#define uves_propertylist_update_int(a, b, c) \
 cpl_propertylist_update_int(a, b, c)
#define uves_propertylist_update_long(a, b, c) \
 cpl_propertylist_update_long(a, b, c)
#define uves_propertylist_update_float(a, b, c) \
 cpl_propertylist_update_float(a, b, c)
#define uves_propertylist_update_double(a, b, c) \
 cpl_propertylist_update_double(a, b, c)
#define uves_propertylist_update_string(a, b, c) \
 cpl_propertylist_update_string(a, b, c)
#define uves_propertylist_copy_property(a, b, c) \
 cpl_propertylist_copy_property(a, b, c)
#define uves_propertylist_copy_property_regexp(a, b, c, d) \
 cpl_propertylist_copy_property_regexp(a, b, c, d) 
#define uves_propertylist_load(a, b) \
 cpl_propertylist_load(a, b)  
#define uves_propertylist_load_regexp(a, b, c, d) \
 cpl_propertylist_load_regexp(a, b, c, d) 
#define uves_propertylist_to_fits(a) \
 cpl_propertylist_to_fits(a) 
#define uves_propertylist_from_fits(a) \
     cpl_propertylist_from_fits(a) 

#else /* if USE_CPL */

#include <cpl.h>
#include <qfits.h>

/**
 * @ingroup uves_propertylist
 *
 * @brief
 *   The opaque property list data type.
 */
     
typedef struct _uves_propertylist_ uves_propertylist;


/*
 * Wrappers for functions which have cpl_propertylists in their interface 
 */
cpl_error_code uves_vector_save(const cpl_vector *v, const char *f, cpl_type_bpp bpp,
                                const uves_propertylist *header, unsigned mode);
cpl_error_code uves_image_save(const cpl_image *image, const char *f, cpl_type_bpp bpp,
                               const uves_propertylist *header, unsigned mode);
cpl_error_code uves_imagelist_save(const cpl_imagelist *imagelist, const char *f, cpl_type_bpp bpp,
                   const uves_propertylist *header, unsigned mode);
cpl_error_code uves_table_save(const cpl_table *table, const uves_propertylist *header,
                   const uves_propertylist *ext_header, const char *filename,
                   unsigned mode);
cpl_error_code uves_dfs_setup_product_header(uves_propertylist *header,
                                             const cpl_frame *frame,
                                             const cpl_frameset *set,
                                             const cpl_parameterlist *par,
                                             const char *c1,
                                             const char *c2,
                                             const char *c3);
cpl_error_code uves_table_sort(cpl_table *, const uves_propertylist *);

/*
 * Create, copy and destroy operations.
 */

uves_propertylist *
uves_propertylist_new(void);

uves_propertylist *
uves_propertylist_duplicate(const uves_propertylist *other);

void
uves_propertylist_delete(const uves_propertylist *self);


/*
 * Non modifying operations
 */

long
uves_propertylist_get_size(const uves_propertylist *self);

int
uves_propertylist_is_empty(const uves_propertylist *self);

cpl_type
uves_propertylist_get_type(const uves_propertylist *self, const char *name);

int
uves_propertylist_contains(const uves_propertylist *self, const char *name);

int
my_uves_propertylist_contains(const cpl_propertylist *self, const char *name);


/*
 * Assignment operations
 */

cpl_error_code
uves_propertylist_set_comment(uves_propertylist *self, const char *name,
                             const char *comment);
cpl_error_code
uves_propertylist_set_char(uves_propertylist *self, const char *name,
                          char value);
cpl_error_code
uves_propertylist_set_bool(uves_propertylist *self, const char *name ,
                          int value);
cpl_error_code
uves_propertylist_set_int(uves_propertylist *self, const char *name,
                         int value);
cpl_error_code
uves_propertylist_set_long(uves_propertylist *self, const char *name,
                          long value);
cpl_error_code
uves_propertylist_set_float(uves_propertylist *self, const char *name,
                           float value);
cpl_error_code
uves_propertylist_set_double(uves_propertylist *self, const char *name,
                            double value);
cpl_error_code
uves_propertylist_set_string(uves_propertylist *self, const char *name,
                            const char *value);

/*
 * Element access
 */

const cpl_property *
uves_propertylist_get_const(const uves_propertylist *self, long position);

cpl_property *
uves_propertylist_get(uves_propertylist *self, long position);

const char *
uves_propertylist_get_comment(const uves_propertylist *self, const char *name);

char
uves_propertylist_get_char(const uves_propertylist *self, const char *name);

int
uves_propertylist_get_bool(const uves_propertylist *self, const char *name);

int
uves_propertylist_get_int(const uves_propertylist *self, const char *name);

long
uves_propertylist_get_long(const uves_propertylist *self, const char *name);

float
uves_propertylist_get_float(const uves_propertylist *self, const char *name);

double
uves_propertylist_get_double(const uves_propertylist *self, const char *name);

const char *
uves_propertylist_get_string(const uves_propertylist *self, const char *name);


/*
 * Inserting and removing elements
 */

cpl_error_code
uves_propertylist_insert_char(uves_propertylist *self, const char *here,
                             const char *name, char value);

cpl_error_code
uves_propertylist_insert_bool(uves_propertylist *self, const char *here,
                             const char *name, int value);

cpl_error_code
uves_propertylist_insert_int(uves_propertylist *self, const char *here,
                            const char *name, int value);

cpl_error_code
uves_propertylist_insert_long(uves_propertylist *self, const char *here,
                             const char *name, long value);

cpl_error_code
uves_propertylist_insert_float(uves_propertylist *self, const char *here,
                              const char *name, float value);

cpl_error_code
uves_propertylist_insert_double(uves_propertylist *self, const char *here,
                               const char *name, double value);

cpl_error_code
uves_propertylist_insert_string(uves_propertylist *self, const char *here,
                               const char *name, const char *value);


cpl_error_code
uves_propertylist_insert_after_char(uves_propertylist *self, const char *after,
                                   const char *name, char value);

cpl_error_code
uves_propertylist_insert_after_bool(uves_propertylist *self, const char *after,
                                   const char *name, int value);

cpl_error_code
uves_propertylist_insert_after_int(uves_propertylist *self, const char *after,
                                  const char *name, int value);

cpl_error_code
uves_propertylist_insert_after_long(uves_propertylist *self, const char *after,
                                   const char *name, long value);

cpl_error_code
uves_propertylist_insert_after_float(uves_propertylist *self, const char *after,
                                    const char *name, float value);

cpl_error_code
uves_propertylist_insert_after_double(uves_propertylist *self, const char *after,
                                     const char *name, double value);

cpl_error_code
uves_propertylist_insert_after_string(uves_propertylist *self, const char *after,
                                     const char *name, const char *value);


cpl_error_code
uves_propertylist_prepend_char(uves_propertylist *self, const char *name,
                              char value);

cpl_error_code
uves_propertylist_prepend_bool(uves_propertylist *self, const char *name,
                              int value);
cpl_error_code
uves_propertylist_prepend_int(uves_propertylist *self, const char *name,
                             int value);

cpl_error_code
uves_propertylist_prepend_long(uves_propertylist *self, const char *name,
                              long value);

cpl_error_code
uves_propertylist_prepend_float(uves_propertylist *self, const char *name,
                               float value);

cpl_error_code
uves_propertylist_prepend_double(uves_propertylist *self, const char *name,
                                double value);

cpl_error_code
uves_propertylist_prepend_string(uves_propertylist *self, const char *name,
                                const char *value);



cpl_error_code
uves_propertylist_append_c_char(uves_propertylist *self, const char *name,
                             char value, const char *comment);

cpl_error_code
uves_propertylist_append_c_bool(uves_propertylist *self, const char *name,
                             int value, const char *comment);

cpl_error_code
uves_propertylist_append_c_int(uves_propertylist *self, const char *name,
                            int value, const char *comment);

cpl_error_code
uves_propertylist_append_c_long(uves_propertylist *self, const char *name,
                             long value, const char *comment);

cpl_error_code
uves_propertylist_append_c_float(uves_propertylist *self, const char *name,
                              float value, const char *comment);

cpl_error_code
uves_propertylist_append_c_double(uves_propertylist *self, const char *name,
                               double value, const char *comment);

cpl_error_code
uves_propertylist_append_c_string(uves_propertylist *self, const char *name,
                               const char *value, const char *comment);




cpl_error_code
uves_propertylist_append_char(uves_propertylist *self, const char *name,
                             char value);

cpl_error_code
uves_propertylist_append_bool(uves_propertylist *self, const char *name,
                             int value);

cpl_error_code
uves_propertylist_append_int(uves_propertylist *self, const char *name,
                            int value);

cpl_error_code
uves_propertylist_append_long(uves_propertylist *self, const char *name,
                             long value);

cpl_error_code
uves_propertylist_append_float(uves_propertylist *self, const char *name,
                              float value);

cpl_error_code
uves_propertylist_append_double(uves_propertylist *self, const char *name,
                               double value);

cpl_error_code
uves_propertylist_append_string(uves_propertylist *self, const char *name,
                               const char *value);


cpl_error_code
uves_propertylist_append(uves_propertylist *self,
                        const uves_propertylist *other);

int
uves_propertylist_erase(uves_propertylist *self, const char *name);

int
uves_propertylist_erase_regexp(uves_propertylist *self, const char *regexp,
                              int invert);

void
uves_propertylist_empty(uves_propertylist *self);


/*
 * Convenience functions
 */
int
uves_propertylist_has(const uves_propertylist *self, const char *name);

cpl_error_code
uves_propertylist_update_char(uves_propertylist *self, const char *name,
                             char value);
cpl_error_code
uves_propertylist_update_bool(uves_propertylist *self, const char *name,
                             int value);
cpl_error_code
uves_propertylist_update_int(uves_propertylist *self, const char *name,
                            int value);
cpl_error_code
uves_propertylist_update_long(uves_propertylist *self, const char *name,
                             long value);
cpl_error_code
uves_propertylist_update_float(uves_propertylist *self, const char *name,
                              float value);
cpl_error_code
uves_propertylist_update_double(uves_propertylist *self, const char *name,
                               double value);
cpl_error_code
uves_propertylist_update_string(uves_propertylist *self, const char *name,
                               const char *value);

cpl_error_code
uves_propertylist_copy_property(uves_propertylist *self,
                               const uves_propertylist *other,
                               const char *name);
cpl_error_code
uves_propertylist_copy_property_regexp(uves_propertylist *self,
                                      const uves_propertylist *other,
                                      const char *regexp,
                                      int invert);

/*
 * Loading, saving and conversion operations.
 */

uves_propertylist *
uves_propertylist_load(const char *name, int position);

uves_propertylist *
uves_propertylist_load_regexp(const char *name, int position,
                             const char *regexp, int invert);



/* Internal functions */
qfits_header *
uves_propertylist_to_fits(const uves_propertylist *self);

uves_propertylist *
uves_propertylist_from_fits(const qfits_header *header);

cpl_propertylist *
my_uves_propertylist_from_fits(const cpl_propertylist *header);

/*
cpl_propertylist *
my_cpl_propertylist_from_fitsfile(fitsfile *file);
*/


/*
cxint
_my_uves_propertylist_from_fitsfile(cpl_propertylist *self, fitsfile *file,
				   cx_compare_func filter, cxptr data);


static cxint
_my_uves_propertylist_to_fitsfile(fitsfile *file, const cpl_propertylist *self,
				  cx_compare_func filter, cxptr data);
cpl_propertylist *
my_uves_propertylist_from_fitsfile(fitsfile *file);
*/

#endif /* USE_CPL */

#endif /* UVES_PROPERTYLIST_H */
