/*
 * fitsTclInt.h -
 *
 *      This header file contains the definitions, structures, and
 *      function prototypes for fitsTcl's internal use.
 */

/*
 *-----------------------------------------------------------------
 * MODIFICATION HISTORY
 *        2004-02-06 Ziqin Pan
 *            1. Add long rowindex to colData structure
 *
 *----------------------------------------------------------------
 */

#ifndef FITSTCLINT
#define FITSTCLINT

#ifndef macintosh
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <ctype.h>
#include <math.h>
#include <string.h>

#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif

#include "fitsTcl.h"
#include "fitsio2.h"

#define FITS_COLMAX 999
#define FITS_MAXDIMS 15
#define FITS_MAXRANGE 30
#define FITS_CHUNKSIZE 100

#define BYTE_DATA     0
#define SHORTINT_DATA 1
#define INT_DATA      2
#define FLOAT_DATA    3
#define DOUBLE_DATA   4
#define LONGLONG_DATA 5

#define NOHDU      -1

typedef struct {
   int    numCols;
   LONGLONG numRows;
   LONGLONG rowLen;
   char   **colName;
   char   **colType;
   int    *colDataType;
   char   **colUnit;
   char   **colDisp;
   char   **colNull;
   long   *vecSize;
   long   *vecDim;
   double *colTzero;
   double *colTscale;
   int    *colTzflag;
   int    *colTsflag;
   int    *strSize;
   int    loadStatus;
   int    *colWidth;
   char   **colFormat;
   double *colMin;
   double *colMax;
} TableHDUInfo;

typedef struct {
   int    bitpix;
   int    naxes;
   LONGLONG *naxisn;
   char   **axisUnit;
   double bscale;
   double bzero;
   long   bsflag;
   long   bzflag;
   int    dataType;
   char   blank[80];
} ImageHDUInfo;

typedef union {
   TableHDUInfo table;
   ImageHDUInfo image;
} HDUInfo;

typedef struct {
   char name[FLEN_KEYWORD];
   char value[FLEN_VALUE];
   char comment[FLEN_COMMENT];
   int pos;
} Keyword;

typedef struct FitsCardStruct{
   int pos;
   char value[FLEN_CARD];
   struct FitsCardStruct * next;
} FitsCardList;

typedef struct {
   Tcl_Interp *interp;
   fitsfile *fptr;
   int fileNum;
   char* fileName;
   char* handleName;
   int rwmode;
   int chdu;
   int hduType;
   char extname[FLEN_VALUE];
   int numKwds;
   int numHis;
   int numCom;
   Tcl_HashTable *kwds;
   FitsCardList *hisHead;
   FitsCardList *comHead;
   HDUInfo CHDUInfo;
} FitsFD;


typedef struct {
   LONGLONG longlongData;
   double dblData;
   long   intData;
   char   *strData;
   char   flag;
   long   rowindex;
   unsigned char *colBuffer;
} colData;

typedef struct {
   double min;
   double max;
   double mean;
   long fmin;
   long fmax;
   double stdiv;
   long numData;
} colStat;

/*
 * These are the function Prototypes:
 */

extern DLLEXPORT void fitsCloseFile (ClientData clientData);

extern DLLEXPORT void dumpFitsErrStackToDString( Tcl_DString *stack, int status );
extern DLLEXPORT void dumpFitsErrStack         ( Tcl_Interp *interp, int status );

extern DLLEXPORT int  fitsMoveHDU (FitsFD *curFile, int nmove, 
			 int direction);

extern DLLEXPORT int  FitsCreateObject (Tcl_Interp *interp, 
			      int argc, Tcl_Obj *const argv[]);

extern DLLEXPORT int  FitsInfo (Tcl_Interp *interp, 
		      int argc, Tcl_Obj *const argv[]);

extern DLLEXPORT int  fitsLoadKwds (FitsFD *curFile);

extern DLLEXPORT int  fitsLoadHDU (FitsFD *curFile);

extern DLLEXPORT int  fitsMakeRegExp (Tcl_Interp *interp,
			    int argc, char *const argv[], 
			    Tcl_DString *concatList, 
			    int caseSen );

extern DLLEXPORT int fitsDumpHeader (FitsFD *curFile);

extern DLLEXPORT int fitsParseRangeNum (char* rangeStr);
extern DLLEXPORT int fitsParseRange (char* rangeStr, int *numInt,
			   int *range,
			   int maxInt,
			   int minval, int maxval,
			   char *errMsg);

extern DLLEXPORT void *makeContigArray (int nrows, int ncols, char type);

extern DLLEXPORT int freeCHDUInfo (FitsFD * curFile);

extern DLLEXPORT int makeNewCHDUInfo (FitsFD * curFile, int newHduType);

extern DLLEXPORT int tableBlockLoad ( FitsFD * curFile,
			    char *varName,
			    int felem,
			    int fRow,				 
			    int nRows,
			    int fCol,
			    int nCols,
			    int colNums[],
                            int format);

extern DLLEXPORT int freeDataPtr (FitsFD * curFile, char ptrAddress[]);

extern DLLEXPORT int tableGetToPtr (FitsFD * curFile,
			  long colNum,
			  char *nulStr,
			  long firstelem);

extern DLLEXPORT int tableRowGetToPtr (FitsFD * curFile,
                             long rowNum,
                             long colNum,
                             long vecSize,
                             char *nulStr,
                             long firstelem);

extern DLLEXPORT int vtableGetToPtr (FitsFD *curFile, 
			   long colNum,
                           char *nulStr);

extern DLLEXPORT void deleteFitsCardList ( FitsCardList *comCard);

extern DLLEXPORT int fitsTransColList (FitsFD     *curFile,
			     char       *colStr,
			     int        *numCols,
			     int       colNums[],
			     int       colTypes[],
			     int       strSize[]);


extern DLLEXPORT int fitsFlushKeywords (FitsFD *curFile);

extern DLLEXPORT int strToUpper (char *inStr,
		       char **outStr);

extern DLLEXPORT int fitsInsertKwds (FitsFD *curFile,
			   int index,
			   char *inCard,
			   int ifFormat);

extern DLLEXPORT int fitsPutKwds (FitsFD *curFile,
			int nkey,
			char *inCard,
			int ifFormat);

extern DLLEXPORT int fitsPutHisKwd ( FitsFD *curFile,
			   char *his);

extern DLLEXPORT int fitsDeleteKwds (FitsFD *curFile,
			   char *keyList);

extern DLLEXPORT int fitsDeleteCols (FitsFD *curFile,
			   int *colList,
			   int numCols);

extern DLLEXPORT int fitsDeleteRows (FitsFD *curFile,
			   int firstRow,
			   int numRows);

extern DLLEXPORT int fitsDeleteCHdu (FitsFD *curFile);

extern DLLEXPORT int tdispGetFormat (FitsFD *curFile, int colnum);

extern DLLEXPORT int saveTableToAscii (FitsFD *curFile,
			     char *filename,
			     char *fileStatus,
			     int felem,
			     int fRow,
			     int nRows,
			     int nCols,
			     int colTypes[],
			     int colNums[],
			     int strSize[],
			     int   ifFixedFormat,
			     int   ifCSV,
			     int   ifPrintRow,
			     char  *sepString);

extern DLLEXPORT int saveImageToAscii( FitsFD *curFile,    
			     char *filename,
			     char *fileStatus,
			     int  fRow,
			     int  nRows,
			     int fCol,
			     int nCols,
			     int cellSize,
			     int ifCSV,
			     int ifPrintRow,
			     char *sepString,
			     long slice );

extern DLLEXPORT int saveVectorTableToAscii( FitsFD *curFile,
				   char *filename,
				   char *fileStatus,
				   int fRow,
				   int nRows,
				   int fCol,
				   int nCols,
				   int baseColNum,
				   int ifCSV,
				   int ifPrintRow,
				   char *sepString,
				   int ifVariableVec);

extern DLLEXPORT int saveVectorTableRowToAscii( FitsFD *curFile,
			  	   char *filename,
				   char *fileStatus,
				   int fRow,
				   int nRows,
				   int fCol,
				   int nCols,
				   int baseColNum,
				   int ifCSV,
				   int ifPrintRow,
				   char *sepString,
				   int ifVariableVec,
                                   char *colFormat,
                                   int dataType,
                                   FILE *fPtr,
                                   int ifFixedFormat);

extern DLLEXPORT int varSaveToTable (FitsFD *curFile,
			   int     colNum,
			   long    firstRow,
			   long    firstElem,
			   long    numRows,
                           long    numElem,
			   Tcl_Obj **listArray);

extern DLLEXPORT int varSaveToImage (FitsFD *curFile,
			   long    firstElem,
			   long    numElem,
			   Tcl_Obj **listArray);

extern DLLEXPORT int addColToTable (FitsFD *curFile,
			  int     colNum,
			  char   *ttype,
			  char   *tform);

extern DLLEXPORT int addRowToTable (FitsFD *curFile,
			  int     rowNum,
			  int     nRows);

extern DLLEXPORT int fitsCopyCHduToFile (FitsFD *curFile,
			       char *newfilename);


extern DLLEXPORT void fitsQSsetFlag (colData a[],
			   int dataType,
			   int strSize,
			   int fst,
			   int lst);

extern DLLEXPORT void fitsQuickSort (colData a[],
			   int dataType,
			   int strSize,
			   int fst,
			   int lst,
			   int isAscend);
/*
extern DLLEXPORT int fitsSplit (colData a[],
		      int dataType,
		      int strSize,
		      int f,
		      int l,
		      int isAscend);
*/
extern DLLEXPORT int fitsSplit (colData a[],
		      int dataType,
		      int strSize,
		      int f,
		      int l,
		      int isAscend,
                      int * sp1,
                      int * sp2);

extern DLLEXPORT void fitsSwap (colData *p,
		      colData *q);

extern DLLEXPORT int fitsUpdateFile (FitsFD *curFile);

extern DLLEXPORT void fitsGetSortRange (colData a[],
			      long n,
			      long *t,
			      long *b);

extern DLLEXPORT void fitsGetSortRangeNum (colData a[],
				 long n,
				 long *nr);

extern DLLEXPORT int fitsWriteRowsToFile (FitsFD *curFile, 
				long rowSize, 
				colData columndata[],
				int isMerge); 

extern DLLEXPORT int fitsCalculateColumn (FitsFD *curFile,
				char *colName,
				char *colForm,
				char *expr);
extern DLLEXPORT int fitsCalculaterngColumn ( FitsFD *curFile,
				char *colName,
				char *colForm,
			        char *expr,
                                int  numrange,
                                int  range[][2]);

extern DLLEXPORT int fitsDeleteRowsExpr (FitsFD *curFile,
			       char *expr);

extern DLLEXPORT int exprGetInfo ( FitsFD *curFile,
			 char *expr );

extern DLLEXPORT int exprGetToPtr ( FitsFD *curFile,
			  char *expr,
			  char *nulStr,
                          int  numrange,
                          int  range[][2]);

extern DLLEXPORT int fitsColumnGetToArray ( FitsFD *curFile,
				  int    colNum,
				  int    felem,
				  long   fRow,
				  long   lRow, 
				  double *array,
				  char   *flagArray);

extern DLLEXPORT int fitsJustMoveHDU ( FitsFD *curFile,
			     int    nmove,
			     int    direction);

extern DLLEXPORT int fitsUpdateCHDU( FitsFD *curFile, int newHduType);

extern DLLEXPORT int fitsDumpHeaderToKV  ( FitsFD *curFile );
extern DLLEXPORT int fitsDumpHeaderToCard( FitsFD *curFile );
extern DLLEXPORT int fitsDumpKwdsToList  ( FitsFD *curFile );

extern DLLEXPORT int imageRowsMeanToPtr( FitsFD *curFile,
			       long fRow,
			       long lRow,
			       long slice );

extern DLLEXPORT int imageColsMeanToPtr( FitsFD *curFile,
			       long fCol,
			       long lCol,
			       long slice );

extern DLLEXPORT int imageBlockLoad_1D( FitsFD *curFile,
			      long fElem,
			      long nElem );

extern DLLEXPORT int imageBlockLoad( FitsFD *curFile,
			   char *varName,
			   LONGLONG fRow,
			   LONGLONG nRow,
			   LONGLONG fCol,
			   LONGLONG nCol,
			   long slice,
                           long cslice);

extern DLLEXPORT int imageGetToPtr( FitsFD *curFile,
			  long slice,
			  int  rotate );

extern DLLEXPORT int fitsPutReqKwds( FitsFD *curFile,
			   int isPrImg,
			   int hduType,
			   int argc,
			   char *const argv[] );

extern DLLEXPORT int fitsAppendCHduToFile( FitsFD *curFile,
				 char *targetfilename );

extern DLLEXPORT int fitsGetWcsMatrix( FitsFD *curFile,
                             int nDims,
                             int cols[],
                             char dest );

extern DLLEXPORT int fitsGetWcsMatrixAlt( FitsFD *curFile,
                             fitsfile *fptr, 
                             Tcl_Obj *listObj, 
                             int nDims,
                             int cols[],
                             char dest );

extern DLLEXPORT int fitsFileGetWcsMatrix( FitsFD *curFile,
                                 fitsfile *dummyFile,
                                 int nDims,
                                 int cols[],
                                 char dest, Tcl_Obj *data[]);

extern DLLEXPORT int fitsGetWcsPair( FitsFD *curFile,
                           int Col1,
                           int Col2,
                           char dest );

extern DLLEXPORT int fitsGetWcsPairAlt( FitsFD *curFile,
                              fitsfile *fptr,
                              Tcl_Obj *listObj,
                              int Col1,
                              int Col2,
                              char dest );

extern DLLEXPORT int fitsTableGetWcsOld( FitsFD *curFile,
			       int RAColNum,
			       int DecColNum );

extern DLLEXPORT int fitsReadColData( FitsFD *curFile,
			    int colNum,
			    int strSize,
			    colData columndata[],
			    int *dataType );

extern DLLEXPORT int fitsReadRawColData( FitsFD *curFile,
			       colData columndata[],
			       LONGLONG *rowSize );

extern DLLEXPORT int fitsSortTable( FitsFD *curFile,
			  int numCols,
			  int *colNum,
			  int *strSize,
			  int *isAscend,
			  int isMerge );

extern DLLEXPORT int fitsColumnStatistics( FitsFD *curFile,
				 int colNum,
				 int felem,
				 int numrange,
				 int range[][2] );

extern DLLEXPORT int fitsColumnMinMax( FitsFD *curFile,
			     int colNum,
			     int felem,
			     int numrange,
			     int range[][2] );

extern DLLEXPORT int fitsColumnMinMaxToPtr( FitsFD *curFile,
				  int colNum,
				  int felem,
				  int fRow,
				  int lRow,
				  double *min,
				  double *max );

extern DLLEXPORT int fitsColumnStatToPtr( FitsFD *curFile,
				int colNum,
				int felem,
				int numrange,
				int range[][2],
				colStat *colstat,
				int statFlag );

extern DLLEXPORT void fitsRandomizeColData( colData columndata[], long numRows );
extern DLLEXPORT void fitsFreeRawColData  ( colData columndata[], long numRows );

extern DLLEXPORT Tcl_Obj *fitsTcl_Ptr2Lst( Tcl_Interp *interp, void *thePtr, char *undef,
				 int dataType, long nelem );

extern DLLEXPORT void *fitsTcl_Lst2Ptr( Tcl_Interp *interp, Tcl_Obj *dataLst,
			      int dataType, long *nelem, char **undef );

extern DLLEXPORT int fitsTcl_SetDims( Tcl_Interp *interp, Tcl_Obj **dimObj,
			    int naxis, long naxes[] );

extern DLLEXPORT int fitsTcl_GetDims( Tcl_Interp *interp, Tcl_Obj *dimObj,
			    long *nelem, int *naxis, long naxes[] );

extern DLLEXPORT void *fitsTcl_ReadPtrStr( Tcl_Obj *ptrObj );

/* Feb 18, 2004, Ziqin Pan add to support row selection */

extern DLLEXPORT int fitsDeleteRowlist(FitsFD *curFile,long* rowlist,int numRows );

extern DLLEXPORT int fitsDeleteRowsRange( FitsFD *curFile,char * rangelist);

extern DLLEXPORT int fitsCalculaterngColumn( FitsFD *curFile,char *colName,char *colForm, char *expr, int numrange, 
           int range[][2] );

extern DLLEXPORT int fitsSelectRowsExpr (FitsFD *curFile,char *expr,long firstrow,long nrows,
           long * n_good_rows,char * row_status);

extern DLLEXPORT LONGLONG fitsTcl_atoll (char *inputStr);

/**********************************
 *    fitsTcl command handlers    *
 **********************************/

int fitsTcl_close   ( FitsFD *curFile, int argc, Tcl_Obj *const argv[] );
int fitsTcl_move    ( FitsFD *curFile, int argc, Tcl_Obj *const argv[] );
int fitsTcl_dump    ( FitsFD *curFile, int argc, Tcl_Obj *const argv[] );
int fitsTcl_info    ( FitsFD *curFile, int argc, char *const argv[] );
int fitsTcl_get     ( FitsFD *curFile, int argc, char *const argv[] );
int fitsTcl_put     ( FitsFD *curFile, int argc, Tcl_Obj *const argv[] );
int fitsTcl_insert  ( FitsFD *curFile, int argc, char *const argv[] );
int fitsTcl_delete  ( FitsFD *curFile, int argc, char *const argv[] );
int fitsTcl_select  ( FitsFD *curFile, int argc, char *const argv[] );
int fitsTcl_load    ( FitsFD *curFile, int argc, char *const argv[] );
int fitsTcl_free    ( FitsFD *curFile, int argc, Tcl_Obj *const argv[] );
int fitsTcl_flush   ( FitsFD *curFile, int argc, Tcl_Obj *const argv[] );
int fitsTcl_copy    ( FitsFD *curFile, int argc, Tcl_Obj *const argv[] );
int fitsTcl_sascii  ( FitsFD *curFile, int argc, char *const argv[] );
int fitsTcl_sort    ( FitsFD *curFile, int argc, char *const argv[] );
int fitsTcl_add     ( FitsFD *curFile, int argc, char *const argv[] );
int fitsTcl_append  ( FitsFD *curFile, int argc, Tcl_Obj *const argv[] );
int fitsTcl_histo   ( FitsFD *curFile, int argc, Tcl_Obj *const argv[] );
int fitsTcl_create  ( FitsFD *curFile, int argc, Tcl_Obj *const argv[] );
int fitsTcl_smooth  ( FitsFD *curFile, int argc, Tcl_Obj *const argv[] );
int fitsTcl_checksum( FitsFD *curFile, int argc, Tcl_Obj *const argv[] );


#define FITS_MAX_OPEN_FILES  NIOBUF        /*  Set by CFITSIO  */

/*
 * This is the list of open Fits Files...
 */

extern DLLEXPORT FitsFD FitsOpenFiles[FITS_MAX_OPEN_FILES];

typedef struct {
   int    wcsSwap;
} fitsTclOptions;

extern DLLEXPORT fitsTclOptions userOptions;

#endif
