# include "psphotInternal.h"

bool psphotFindFootprints (pmDetections *detections, psImage *significance, pmReadout *readout, psMetadata *recipe, const int pass, psMaskType maskVal) {

    bool status;

    psTimerStart ("footprints");

    int npixMin = psMetadataLookupS32(&status, recipe, "FOOTPRINT_NPIXMIN");
    PS_ASSERT (status, false);

    float FOOTPRINT_NSIGMA_LIMIT;
    if (pass == 1) {
	FOOTPRINT_NSIGMA_LIMIT = psMetadataLookupS32(&status, recipe, "FOOTPRINT_NSIGMA_LIMIT");
    } else {
	FOOTPRINT_NSIGMA_LIMIT = psMetadataLookupS32(&status, recipe, "FOOTPRINT_NSIGMA_LIMIT_2");
    }
    PS_ASSERT (status, false);

    // XXX do we need to use the same threshold here as for peaks?  does it make sense for
    // these to be different?

    float threshold = PS_SQR(FOOTPRINT_NSIGMA_LIMIT);

    int growRadius = 0;
    if (pass == 1) {
	growRadius = psMetadataLookupS32(&status, recipe, "FOOTPRINT_GROW_RADIUS");
    } else {
	growRadius = psMetadataLookupS32(&status, recipe, "FOOTPRINT_GROW_RADIUS_2");
    }
    PS_ASSERT (status, false);

    // find the raw footprints & assign the peaks to those footprints 
    psArray *footprints = pmFootprintsFind (significance, threshold, npixMin);

    pmFootprintsAssignPeaks(footprints, detections->peaks);
    // XXX handle the error conditions here

    // footprints now owns the peaks; after culling (below), we will rebuild the peaks array
    psFree (detections->peaks); 

    psLogMsg ("psphot", PS_LOG_DETAIL, "found %ld footprints: %f sec\n", footprints->n, psTimerMark ("footprints"));

    // optionally grow footprints isotropically by growRadius pixels
    if (growRadius > 0) {
	psArray *tmp = pmFootprintArrayGrow(footprints, growRadius);
	psLogMsg ("psphot", PS_LOG_DETAIL, "grow footprint coverage by %d pixels, %ld footprints become %ld footprints: %f sec\n", growRadius, footprints->n, tmp->n, psTimerMark ("footprints"));
	psFree(footprints);
	footprints = tmp;
    }

    if (pass == 2) {
	// merge in old peaks;
	const int includePeaks = 0x0 | 0x2; // i.e. just from newFootprints
	
	// XXX EAM : still not sure I understand this: are we double-couning or undercounting peaks

	psArray *mergedFootprints = pmFootprintArraysMerge(detections->footprints, footprints, includePeaks);
	psLogMsg ("psphot", PS_LOG_DETAIL, "merged %ld new footprints with %ld existing ones: %f sec\n", footprints->n, detections->footprints->n, psTimerMark ("footprints"));

	psFree(footprints);
	psFree(detections->footprints);
	detections->footprints = mergedFootprints;
    } else {
	detections->footprints = footprints;
    }

    psphotCullPeaks(readout->image, readout->weight, recipe, detections->footprints);
    detections->peaks = pmFootprintArrayToPeaks(detections->footprints);
    psLogMsg ("psphot", PS_LOG_INFO, "%ld peaks, %ld total footprints: %f sec\n", detections->peaks->n, detections->footprints->n, psTimerMark ("footprints"));

    return detections;
}
