#ifndef PP_MOPS_H
#define PP_MOPS_H

#include <pslib.h>
#include <pmSourceMasks.h>

#define IN_EXTNAME "SkyChip.psf"        // Extension name for data in input
#define OBSERVATORY_CODE "F51"          // IAU Observatory Code
#define OUT_EXTNAME "MOPS_TRANSIENT_DETECTIONS" // Extension name for data in output
#define SOURCE_MASK (PM_SOURCE_MODE_FAIL | PM_SOURCE_MODE_BADPSF | PM_SOURCE_MODE_SATURATED | \
                     PM_SOURCE_MODE_CR_LIMIT | PM_SOURCE_MODE_SKY_FAILURE) // Flags to exclude

#define PS1_DV_FORMAT "PS1_DV%d"

// Configuration data
typedef struct {
  psArray *input;                     // Input filenames
  psString exp_name;                  // Exposure name
  psS64 exp_id;                       // Exposure identifier
  psS64 chip_id;                      // Chip stage identifier
  psS64 cam_id;                       // Camera stage identifier
  psS64 fake_id;                      // Fake stage identifier
  psS64 warp_id;                      // Warp stage identifier
  psS64 diff_id;                      // Diff stage identifier
  bool positive;                      // Sense of subtraction, T=positive, F=negative
  float zp, zpErr;                    // Magnitude zero point and error
  float rmsAstrom;                    // Astrometric solution RMS
  psString output;                    // Output filename
  psU16 version;                      // Version (for parameters)
} ppMopsArguments;

#if 0
#warning "IS THERE ANYTHING TO BE MODIFIED HERE?"
TTYPE19 = 'PSF_CHISQ'          / label for field  19
TFORM19 = '1E      '           / data format of field: 4-byte REAL
TTYPE20 = 'CR_NSIGMA'          / label for field  20
TFORM20 = '1E      '           / data format of field: 4-byte REAL
TTYPE21 = 'EXT_NSIGMA'         / label for field  21
TFORM21 = '1E      '           / data format of field: 4-byte REAL
TTYPE22 = 'PSF_MAJOR'          / label for field  22
TFORM22 = '1E      '           / data format of field: 4-byte REAL
TTYPE23 = 'PSF_MINOR'          / label for field  23
TFORM23 = '1E      '           / data format of field: 4-byte REAL
TTYPE24 = 'PSF_THETA'          / label for field  24
TFORM24 = '1E      '           / data format of field: 4-byte REAL
TTYPE25 = 'PSF_QF  '           / label for field  25
TFORM25 = '1E      '           / data format of field: 4-byte REAL
TTYPE26 = 'PSF_NDOF'           / label for field  26
TFORM26 = '1J      '           / data format of field: 4-byte INTEGER
TTYPE27 = 'PSF_NPIX'           / label for field  27
TFORM27 = '1J      '           / data format of field: 4-byte INTEGER
TTYPE28 = 'MOMENTS_XX'         / label for field  28
TFORM28 = '1E      '           / data format of field: 4-byte REAL
TTYPE29 = 'MOMENTS_XY'         / label for field  29
TFORM29 = '1E      '           / data format of field: 4-byte REAL
TTYPE30 = 'MOMENTS_YY'         / label for field  30
TFORM30 = '1E      '           / data format of field: 4-byte REAL
#endif

/// Parse arguments
ppMopsArguments *ppMopsArgumentsParse(int argc, char *argv[]);

typedef struct {
  psString component;                 // skycell_id for these detections
  psString raBoresight, decBoresight; // RA,Dec of telescope boresight
  psString filter;                    // Filter for exposure
  float airmass;                      // Airmass of exposure
  float exptime;                      // Exposure time
  double posangle;                    // Position angle
  double alt, az;                     // Telescope altitude and azimuth
  double mjd;                         // Modified Julian Date
  float seeing;                       // Seeing of exposure
  int   naxis1, naxis2;               // size of the image
  long num;                           // Number of detections
  long numGood;                       // Number of "good" detections
  psS64 diffSkyfileId;                // unique id for input skyfile
  psMetadata *table;                  // Columns from the input file
  psVector *x, *y;                    // Image coordinates
  psVector *ra, *dec;                 // Sky coordinates
  psVector *raErr, *decErr;           // Error in sky coordinates
  psVector *mask;                     // Mask for detections
} ppMopsDetections;

ppMopsDetections *ppMopsDetectionsAlloc();

/// Copy a detection
bool ppMopsDetectionsCopySingle(ppMopsDetections *target, const ppMopsDetections *source, long index);

/// Purge the detections list of masked detections
bool ppMopsDetectionsPurge(ppMopsDetections *detections);

/// Read detections
psArray *ppMopsRead(ppMopsArguments *args);

/// Merge detections
// ppMopsDetections *ppMopsMerge(const psArray *detections);
bool ppMopsPurgeDuplicates(const psArray *detections);

/// Write detections
bool ppMopsWrite(const psArray *detections, const ppMopsArguments *args);

/// Get the version contained in EXTTYPE of the "SkyChip.psf" table:
/// @returns 1 if EXTTYPE of "SkyChip.psf" is PS1_DV1
/// @returns 2 if EXTTYPE of "SkyChip.psf" is PS1_DV2
/// @returns 0 otherwise
int ppMopsGetSkyChipPsfVersion(const psFits* fits);

#endif
