/* FITS specific macros and structures */

# ifndef GFITSIO
# define GFITSIO

/* also defined in libautocode/def/common.h */
/* what about lin64 ?? - 'linux' might be defined automatically by linux */
# ifndef BYTE_SWAP
# ifdef linux
# define BYTE_SWAP
# endif

# ifdef sid
# define BYTE_SWAP
# endif

# ifdef dec
# define BYTE_SWAP
# endif
# endif /* BYTE_SWAP */

# ifndef NEWLINE
# define NEWLINE                 10  /* UNIX RETURN character */
# endif /* NEWLINE */

/********** FITS Constants *********/
# define FT_TEXT_LENGTH          18  /* max length text header field */
# define FT_MAX_NAXES            10  /* max number of axes */
# define FT_FIELD_LENGTH          8  /* max length header field */   
# define FT_COMMENT_LENGTH       47  /* max length comment field */
# define FT_HISTORY_LENGTH       72  /* max length history / comment */
# define FT_LINE_LENGTH          80  /* FITS header line length */
# define FT_RECORD_SIZE        2880  /* FITS block size */

/* this structure defines the buffer which contains a header
   and contains the minimum required keywords */

typedef struct {
  int                     simple;
  int                     unsign;
  int                     extend;
  int                     bitpix;
  int                     Naxes;
  int                     Naxis[FT_MAX_NAXES];
  int                     size;
  double                  bzero;
  double                  bscale;
  char                   *buffer;
} Header;

/* this structure defines the buffer which contains a matrix
   and contains some relavant info */

typedef struct {
  int                     unsign;
  int                     bitpix;
  int                     Naxes;
  int                     Naxis[FT_MAX_NAXES];
  int                     size;
  double                  bzero;
  double                  bscale;
  char                   *buffer;
} Matrix;
   
/* the FTable represents a complete table on disk */          
typedef struct {
  Header                 *header;
  char                   *buffer;
  int                     size;
} FTable;

/* the VTable represents rows from a table on disk */          
typedef struct {
  Header                 *header;
  char                  **buffer;
  int                     Nrow;
  int                    *row;
  int                     size;  /* total buffer size */
  int                     pad;   /* bytes of padding at the end */
} VTable;

# ifndef PROTO
# define PROTO(A) A
# endif

char *gfits_version                PROTO(());

/******************************* Header functions *************/
int   gfits_read_header            PROTO((char *, Header *));
// int   fits_copy_header            PROTO((Header *, Header *)); 
int   gfits_copy_header           PROTO((Header *, Header *)); 
void  gfits_free_header            PROTO((Header *)); 
int   gfits_write_header           PROTO((char *, Header *)); 
int   gfits_create_header          PROTO((Header *)); 
int   gfits_delete                 PROTO((Header *, char *, int)); 
char *gfits_header_field           PROTO((Header *, char *, int)); 
int   gfits_read_Xheader           PROTO((char *filename, Header *header, int N));
int   gfits_fread_Xheader          PROTO((FILE *f, Header *header, int N));
int   gfits_load_header            PROTO((FILE *f, Header *header));

int   gfits_fread_header           PROTO((FILE *, Header *));
int   gfits_fread_Theader          PROTO((FILE *, Header *));
int   gfits_fread_ftable           PROTO((FILE *, FTable *, char *)); 
int   gfits_fread_vtable_range     PROTO((FILE *f, VTable *table, int start, int Nrows));
int   gfits_fread_vtable           PROTO((FILE *f, VTable *table, char *extname, int Nrow, int *row));
int   gfits_fread_ftable_data      PROTO((FILE *f, FTable *table));
int   gfits_fwrite_header          PROTO((FILE *, Header *)); 
int   gfits_fwrite_Theader         PROTO((FILE *, Header *));
int   gfits_fwrite_matrix          PROTO((FILE *, Matrix *));      
int   gfits_fwrite_table           PROTO((FILE *, FTable *)); 
int   gfits_fwrite_vtable          PROTO((FILE *, VTable *)); 

int   gfits_matrix_size            PROTO ((Header *));
int   gfits_init_header            PROTO ((Header *));
int   gfits_get_unsign_mode        PROTO (());
int   gfits_set_unsign_mode        PROTO ((int mode));
int   gfits_create_table_header    PROTO ((Header *, char *, char *));
int   gfits_vtable_from_ftable     PROTO ((FTable *ftable, VTable *vtable, int *row, int Nrow));
int   gfits_table_to_vtable        PROTO ((FTable *ftable, VTable *vtable, int start, int Nkeep));
int   gfits_create_table           PROTO ((Header *, FTable *));
int   gfits_vadd_rows              PROTO ((VTable *, char *, int, int));
int   gfits_add_rows               PROTO ((FTable *, char *, int, int));
char *gfits_table_print            PROTO ((FTable *,...));

/******************************* Matrix functions *************/
int   gfits_read_matrix            PROTO((char *, Matrix *));      
int   gfits_read_portion           PROTO((char *filename, Matrix *matrix, int Nskip, int Npix));
void  gfits_free_matrix            PROTO((Matrix *)); 
int   gfits_copy_matrix            PROTO((Matrix *, Matrix *)); 
int   gfits_write_matrix           PROTO((char *,Matrix *)); 
int   gfits_create_matrix          PROTO((Header *, Matrix *)); 
double  gfits_get_matrix_value     PROTO((Matrix *, int, int)); 
void  gfits_set_matrix_value       PROTO((Matrix *, int, int, double)); 
void  gfits_add_matrix_value       PROTO((Matrix *, int, int, double)); 
int   gfits_multiply_matrix        PROTO((Matrix *, Matrix *, Matrix *)); 
int   gfits_divide_matrix          PROTO((Matrix *, Matrix *, Matrix *)); 
void  gfits_insert_array           PROTO((Matrix *, Matrix *, int, int)); 
int   gfits_load_matrix            PROTO((FILE *f, Matrix *matrix, Header *header));
int   gfits_fread_matrix           PROTO((FILE *f, Matrix *matrix, Header *header));
int   gfits_read_matrix_segment    PROTO((char *filename, Matrix *matrix, char *region));
int   gfits_fread_matrix_segment   PROTO((FILE *f, Matrix *matrix, Header *header, char *region));
int   gfits_convert_format         PROTO((Header *header, Matrix *matrix, int outBitpix, double outScale, double outZero, int outUnsign));

/******************************* Table functions *************/
int   gfits_load_Theader           PROTO((FILE *f, Header *Theader));
int   gfits_read_Theader           PROTO((char *, Header *));     
int   gfits_read_table             PROTO((char *, FTable *)); 
int   gfits_read_table             PROTO((char *, FTable *)); 
int   gfits_write_Theader          PROTO((char *, Header *header));
int   gfits_write_table            PROTO((char *, FTable *)); 
int   gfits_fwrite_table           PROTO((FILE *f, FTable *table));
int   gfits_fwrite_vtable          PROTO((FILE *f, VTable *table));

int   gfits_bintable_format        PROTO((char *, char *, int *, int *));
int   gfits_table_format           PROTO((char *, char *, int *, int *));
int   gfits_save_header            PROTO((FILE *, Header *header));
int   gfits_set_bintable_column    PROTO((Header *header, FTable *table, char *, void *, int));
int   gfits_set_table_column       PROTO((Header *header, FTable *table, char *, void *, int));
int   gfits_define_bintable_column PROTO((Header *header, char *, char *, char *, char *, double, double));
int   gfits_define_table_column    PROTO((Header *header, char *, char *, char *, char *));
int   gfits_read_ftable            PROTO((char *filename, FTable *table, char *extname));

int   gfits_free_table             PROTO((FTable *table));
int   gfits_free_vtable            PROTO((VTable *table));
int   gfits_create_Theader         PROTO((Header *header, char *type));

/* prototyping demanded for these four -- could be a problem on non-ANSI comp comp */
int   gfits_scan                   PROTO((Header *, char *, char *, int,...)); 
int   gfits_print                  PROTO((Header *, char *, char *, int,...)); 
int   gfits_modify                 PROTO((Header *, char *, char *, int,...)); 
int   gfits_table_column           PROTO((FTable *, char *, char *,...)); 
int   gfits_table_column           PROTO((FTable *table, char *, char *,...));

char *gfits_keyword_end            PROTO((char *line));
int   gfits_vscan                  PROTO((Header *header, char *field, char *mode, int N, va_list argp));
int   gfits_scan                   PROTO((Header *header, char *field, char *mode, int N,...));
int   gfits_stripwhite             PROTO((char *string));
int   gfits_matrix_size            PROTO((Header *header));

int   gfits_get_bintable_column_type PROTO((Header *header, char *label, char *type, int *Nval));
int   gfits_get_bintable_column    PROTO((Header *header, FTable *table, char *label, void **data));
int   gfits_get_table_column_type  PROTO((Header *header, char *label, char *type));
int   gfits_get_table_column       PROTO((Header *header, FTable *table, char *label, void **data));

#endif /* FITSIO */
