# include <stdio.h>
# include <strings.h>  // for strcasecmp
# include <unistd.h>   // for unlink
# include <pslib.h>
# include <psmodules.h>

#include "psphotErrorCodes.h"

# define PSPHOT_RECIPE "PSPHOT"

// top-level psphot functions
const char *psphotCVSName(void);

pmConfig       *psphotArguments (int argc, char **argv);
bool            psphotParseCamera (pmConfig *config);
bool            psphotImageLoop (pmConfig *config);

bool            psphotModelTest (pmReadout *readout, psMetadata *recipe);
bool            psphotReadout (pmConfig *config, pmFPAview *view);
void            psphotCleanup (pmConfig *config);

psArray        *psphotFakeSources ();

// psphotReadout functions
bool            psphotImageMedian (pmConfig *config, pmFPAview *view);
psArray        *psphotFindPeaks (pmReadout *readout, psMetadata *recipe);
psArray        *psphotSourceStats (pmReadout *readout, psMetadata *recipe, psArray *allpeaks);
bool            psphotRoughClass (psArray *sources, psMetadata *recipe);
bool            psphotBasicDeblend (psArray *sources, psMetadata *recipe);
pmPSF          *psphotChoosePSF (pmReadout *readout, psArray *sources, psMetadata *recipe);
bool            psphotPSFstats (pmReadout *readout, psMetadata *recipe, pmPSF *psf);
bool            psphotMomentsStats (pmReadout *readout, psMetadata *recipe, psArray *sources);
bool            psphotEnsemblePSF (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, bool final);
bool            psphotBlendFit (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf);
bool            psphotReplaceUnfit (psArray *sources);
bool            psphotApResid (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf);
bool            psphotMagnitudes (psArray *sources, psMetadata *recipe, pmPSF *psf);
bool            psphotSkyReplace (pmConfig *config, pmFPAview *view);
bool            psphotReadoutCleanup (pmConfig *config, pmReadout *readout, psMetadata *recipe, pmPSF *psf, psArray *sources);

// basic support functions
void            psphotModelGroupInit (void);
int             psphotSortBySN (const void **a, const void **b);
int             psphotSortByY (const void **a, const void **b);
bool            psphotGrowthCurve (pmReadout *readout, pmPSF *psf);
void            psphotTestArguments (int *argc, char **argv);
bool            psphotMaskReadout (pmReadout *readout, psMetadata *recipe);
void            psphotSourceFreePixels (psArray *sources);

// functions to set the correct source pixels
bool            psphotInitRadiusPSF (psMetadata *recipe, pmModelType type);
bool            psphotCheckRadiusPSF (pmReadout *readout, pmSource *source, pmModel *model);
bool            psphotCheckRadiusPSFBlend (pmReadout *readout, pmSource *source, pmModel *model, float dR);
bool            psphotInitRadiusEXT (psMetadata *recipe, pmModelType type);
bool            psphotCheckRadiusEXT (pmReadout *readout, pmSource *source, pmModel *model);

// output functions
bool            psphotDumpMoments (psMetadata *recipe, psArray *sources);
psMetadata     *psphotDefineHeader (psMetadata *recipe);
bool            psphotWeightBias (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf);
int             psphotSaveImage (psMetadata *header, psImage *image, char *filename);

// PSF / DBL / EXT evaluation functions
bool            psphotEvalPSF (pmSource *source, pmModel *model);
bool            psphotEvalDBL (pmSource *source, pmModel *model);
bool            psphotEvalEXT (pmSource *source, pmModel *model);

//  functions to support the source fitting process
bool            psphotInitLimitsPSF (psMetadata *recipe);
bool            psphotInitLimitsEXT (psMetadata *recipe);
bool            psphotFitBlend (pmReadout *readout, pmSource *source, pmPSF *psf);
bool            psphotFitBlob (pmReadout *readout, pmSource *source, psArray *sources, pmPSF *psf);
bool            psphotFitPSF (pmReadout *readout, pmSource *source, pmPSF *psf);
pmModel        *psphotFitEXT (pmReadout *readout, pmSource *source);
psArray        *psphotFitDBL (pmReadout *readout, pmSource *source);

// functions to support simultaneous multi-source fitting
bool            psphotFitSet (pmSource *oneSrc, pmModel *oneModel, char *fitset, pmSourceFitMode mode);

