#ifndef PP_STACK_H
#define PP_STACK_H

#define PPSTACK_RECIPE "PPSTACK"        // Name of the recipe
#define PPSTACK_INSPECT_PIXELS "PPSTACK.PIXELS" // Name of rejected pixels metadata items

#include <psmodules.h>

// Setup command-line arguments
bool ppStackArgumentsSetup(int argc, char *argv[], // Command-line arguments
                           pmConfig *config  // Configuration
    );

// Parse command-line arguments
bool ppStackArgumentsParse(pmConfig *config  // Configuration
    );

// Parse cameras
bool ppStackCamera(pmConfig *config     // Configuration
    );

// Loop over the inputs, doing the combination
bool ppStackLoop(pmConfig *config       // Configuration
    );

// Determine target PSF for input images
pmPSF *ppStackPSF(const pmConfig *config, // Configuration
                  int numCols, int numRows, // Size of image
                  const psArray *psfs   // List of input PSFs
    );

// Perform stacking on a readout
bool ppStackReadoutInitial(const pmConfig *config,   // Configuration
                    pmReadout *outRO,   // Output readout
                    const psArray *readouts, // Input readouts
                    const psArray *regions, // Array with array of regions used in each PSF matching
                    const psArray *kernels // Array with array of kernels used in each PSF matching
    );

// Perform stacking on a readout
bool ppStackReadoutFinal(const pmConfig *config,   // Configuration
                         pmReadout *outRO,   // Output readout
                         const psArray *readouts, // Input readouts
                         const psArray *rejected // Array with pixels rejected in each image
    );

// Perform photometry on stack
bool ppStackPhotometry(pmConfig *config, // Configuration
                       const pmReadout *readout, // Readout to be photometered
                       const pmFPAview *view // View to readout
    );

// Return software version
psString ppStackVersion(void);

// Return long description of software version
psString ppStackVersionLong(void);

// Supplement metadata with software version
void ppStackVersionMetadata(psMetadata *metadata // Metadata to supplement
    );

/// Convolve image to match specified seeing
bool ppStackMatch(pmReadout *readout, ///< Readout to be convolved; replaced with output
                  psArray **regions, // Array of regions used in each PSF matching, returned
                  psArray **kernels, // Array of kernels used in each PSF matching, returned
                  const psArray *sources, ///< Array of sources
                  const pmPSF *psf,     ///< Target PSF
                  psRandom *rng,        ///< Random number generator
                  const pmConfig *config ///< Configuration
    );


/// Add sources to source lists, removing duplicates and solving for magnitude differences
///
/// Corrects the sources to have consistent magnitudes.  Returns the source lists.
psArray *ppStackSourceListAdd(psArray *lists, ///< List to which to add, or NULL
                              psArray *sources, ///< Sources to add
                              const pmConfig *config ///< Configuration
    );

/// Combine source lists to yield a set of unique sources.
///
/// Corrects the sources to have consistent magnitudes where possible.  Returns the sources
psArray *ppStackSourceListCombine(psArray *lists, ///< Source lists
                                  const pmConfig *config ///< Configuration
    );

/// Print sources into a ds9 regions file
void ppStackSourcesPrint(const psArray *sources ///< Sources to print
    );

#endif
