#ifndef PP_BG_RESTORE_H
#define PP_BG_RESTORE_H

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

#include <stdio.h>
#include <string.h>
#include <strings.h>  // for strcasecmp
#include <unistd.h>   // for unlink
#include "pslib.h"
#include "psmodules.h"
#include "psphot.h"
#include "psastro.h"
#include "ppStats.h"
#include "ppbgrestoreVersionDefinitions.h"

// Options for ppbgrestore processing
typedef struct {
    // actions which ppbgrestore should perform
    bool dummy;
#ifdef notdef
    bool doMaskBuild;                   // Build internal mask
    bool doVarianceBuild;               // Build internal variance map
    bool doMaskBurntool;                // mask potential burntool trails
    bool doMaskSat;                     // mask saturated pixels
    bool doMaskLow;                     // mask low pixels
    bool doMask;                        // Mask bad pixels
    bool doNonLin;                      // Non-linearity correction
    bool doOverscan;                    // Overscan subtraction
    bool doNoiseMap;                    // Bias subtraction
    bool doBias;                        // Bias subtraction
    bool doDark;                        // Dark subtraction
    bool doRemnance;                    // Remnance masking
    bool doShutter;                     // Shutter correction
    bool doFlat;                        // Flat-field normalisation
    bool doPattern;                     // Pattern noise subtraction
    bool doFringe;                      // Fringe subtraction
    bool doPhotom;                      // Source identification and photometry
    bool doBG;                          // Background subtraction
    bool doAstromChip;                  // per-chip Astrometry
    bool doAstromMosaic;                // full-mosaic Astrometry
    bool doStats;                       // call ppStats on the image
    bool checkCTE;                      // measure pixel-based variance
    bool applyParity;                   // Apply Cell parities

    bool doCrosstalkMeasure;            // measure crosstalk signal
    bool doCrosstalkCorrect;            // apply crosstalk correction

    // output files requested
    bool BaseFITS;
    bool BaseMaskFITS;
    bool BaseVarianceFITS;

    bool ChipFITS;
    bool ChipMaskFITS;
    bool ChipVarianceFITS;

    bool FPA1FITS;
    bool FPA2FITS;
    bool Bin1FITS;
    bool Bin1JPEG;
    bool Bin2FITS;
    bool Bin2JPEG;

    // make values for abstract concepts of masking
    psImageMaskType maskValue;          // apply this bit-mask to choose masked bits
    psImageMaskType markValue;          // apply this bit-mask to choose masked bits
    psImageMaskType satMask;            // Mask value to give saturated pixels
    psImageMaskType lowMask;            // Mask value to give bad pixels
    psImageMaskType flatMask;           // Mask value to give bad flat pixels
    psImageMaskType darkMask;           // Mask value to give bad dark pixels
    psImageMaskType blankMask;          // Mask value to give blank pixels
    psImageMaskType burntoolMask;       // Suspect pixels that fall where a burntool trail is expected.
    // non-linear correction parameters
    psDataType nonLinearType;
    psMetadataItem *nonLinearData;
    void *nonLinearSource;

    // options for the analysis
    pmOverscanOptions *overscan;        // Overscan options
    int burntoolTrails;
    // binning parameters
    int xBin1;                          // x-binning, scale 1
    int yBin1;                          // y-binning, scale 1
    int xBin2;                          // x-binning, scale 2
    int yBin2;                          // y-binning, scale 2

    // parameters used by the fringe analysis
    float fringeRej;                    // Fringe rejection limit
    int fringeIter;                     // Fringe iterations
    float fringeKeep;                   // Fringe keep fraction

    // Pattern noise subtraction
    int patternOrder;                   // Polynomial order
    int patternIter;                    // Clipping iterations
    float patternRej;                   // Clipping threshold
    float patternThresh;                // Ignore threshold
    psStatsOptions patternMean;         // Statistic for mean
    psStatsOptions patternStdev;        // Statistic for stdev

    int remnanceSize;                   // Size for remnance detection
    float remnanceThresh;               // Threshold for remnance detection

    char *normClass;                    // class to use for per-class normalization
#endif
} ppbgrestoreOptions;


ppbgrestoreOptions *ppbgrestoreOptionsAlloc(void);

// Determine the processing options
ppbgrestoreOptions *ppbgrestoreOptionsParse(pmConfig *config);

// Get the configuration
pmConfig *ppbgrestoreArguments(int argc, char **argv);

// Determine what type of camera, and initialise
ppbgrestoreOptions *ppbgrestoreParseCamera(pmConfig *config);

// Loop over the input
bool ppbgrestoreLoop(pmConfig *config, ppbgrestoreOptions *options);

// free memory, check for leaks
void ppbgrestoreCleanup (pmConfig *config, ppbgrestoreOptions *options);

// Subtract background from the chip-mosaicked image
bool ppbgrestoreRestoreBackground(
    pmConfig *config,                   // Configuration
    const pmFPAview *view,              // View to chip of interest
    const ppbgrestoreOptions *options       // Processing options
    );


/// Return short version information
psString ppbgrestoreVersion(void);

/// Return software source
psString ppbgrestoreSource(void);

/// Return long version information
psString ppbgrestoreVersionLong(void);

/// Populate the header with version information for all dependencies
bool ppbgrestoreVersionHeader(psMetadata *metadata ///< Header to populate
    );

/// Print version information
void ppbgrestoreVersionPrint(void);


void ppbgrestoreFileCheck(pmConfig *config);

#endif
