#if !defined(PM_FOOTPRINT_H)
#define PM_FOOTPRINT_H
//
// Describe a segment of an image
//
typedef struct {
    int y;                              //!< Row that span's in
    int x0;                             //!< Starting column (inclusive)
    int x1;                             //!< Ending column (inclusive)
} pmSpan;

pmSpan *pmSpanAlloc(int y, int x1, int x2);
bool pmSpanTest(const psPtr ptr);
int pmSpanSortByYX (const void **a, const void **b);

typedef struct {
    const int id;                       //!< unique ID
    int npix;                           //!< number of pixels in this pmFootprint
    psArray *spans;                     //!< the pmSpans
    psRegion bbox;                      //!< the pmFootprint's bounding box
    psArray *peaks;                     //!< the peaks lying in this footprint
    psRegion region;   //!< A region describing the psImage the footprints live in
    bool normalized;                    //!< Are the spans sorted? 
} pmFootprint;

pmFootprint *pmFootprintAlloc(int nspan, const psImage *img);
bool pmFootprintTest(const psPtr ptr);

pmFootprint *pmFootprintNormalize(pmFootprint *fp);
int pmFootprintSetNpix(pmFootprint *fp);
void pmFootprintSetBBox(pmFootprint *fp);

pmSpan *pmFootprintAddSpan(pmFootprint *fp,	// the footprint to add to
			   const int y, // row to add
			   int x0,      // range of
			   int x1);    //          columns

psArray *pmFootprintsFind(const psImage *img, const float threshold, const int npixMin);
pmFootprint *pmFootprintsFindAtPoint(const psImage *img,
                                    const float threshold,
                                    const psArray *peaks,
                                    int row, int col);

psArray *pmFootprintArrayGrow(const psArray *footprints, int r);
psArray *pmFootprintArraysMerge(const psArray *footprints1, const psArray *footprints2,
                                const int includePeaks);

psImage *pmSetFootprintArrayIDs(const psArray *footprints, const bool relativeIDs);
psImage *pmSetFootprintID(psImage *idImage, const pmFootprint *fp, const int id);
void pmSetFootprintArrayIDsForImage(psImage *idImage,
				    const psArray *footprints, // the footprints to insert
				    const bool relativeIDs); // show IDs starting at 0, not pmFootprint->id

psErrorCode pmFootprintsAssignPeaks(psArray *footprints, const psArray *peaks);

psErrorCode pmFootprintArrayCullPeaks(const psImage *img, const psImage *weight, psArray *footprints,
                                 const float nsigma, const float threshold_min);
psErrorCode pmFootprintCullPeaks(const psImage *img, const psImage *weight, pmFootprint *fp,
                                 const float nsigma, const float threshold_min);

psArray *pmFootprintArrayToPeaks(const psArray *footprints);

typedef struct {
  psArray *footprints;	      // collection of footprints in the image
  psArray *peaks;	      // collection of all peaks contained by the footprints
  psArray *oldPeaks;	      // collection of all peaks previously found
  int last;
} pmDetections;

pmDetections *pmDetectionsAlloc ();


#endif
