# include "psphotInternal.h"

# define CHECK_STATUS(S,MSG) { \
  if (!status) { \
    psError(PSPHOT_ERR_CONFIG, false, "missing PSF Clump entry: %s\n", MSG); \
    return false; \
  } }

// 2006.02.02 : no leaks
bool psphotRoughClass (psArray *sources, psMetadata *recipe, const bool havePSF) {

    bool status;
    static pmPSFClump psfClump;

    psTimerStart ("psphot");

    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
    psMaskType maskSat = psMetadataLookupU8(&status, recipe, "MASK.SAT"); // Mask value for bad pixels
    assert (maskSat);

    if (!havePSF) {
        // determine the PSF parameters from the source moment values
        psfClump = pmSourcePSFClump (sources, recipe);
	psMetadataAddF32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.X",  PS_META_REPLACE, "psf clump center", psfClump.X);
	psMetadataAddF32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.Y",  PS_META_REPLACE, "psf clump center", psfClump.Y);
	psMetadataAddF32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.DX", PS_META_REPLACE, "psf clump center", psfClump.dX);
	psMetadataAddF32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.DY", PS_META_REPLACE, "psf clump center", psfClump.dY);
    } else {
        // pull FWHM_X,Y from the recipe, use to define psfClump.X,Y
        psfClump.X  = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.X");  CHECK_STATUS (status, "PSF.CLUMP.X");
        psfClump.Y  = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.Y");  CHECK_STATUS (status, "PSF.CLUMP.Y");
        psfClump.dX = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.DX");  CHECK_STATUS (status, "PSF.CLUMP.DX");
        psfClump.dY = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.DY");  CHECK_STATUS (status, "PSF.CLUMP.DY");
    }

    if (psfClump.X < 0) {
        psError(PSPHOT_ERR_PROG, false, "programming error calling pmSourcePSFClump");
        return false;
    }
    if (!psfClump.X || !psfClump.Y) {
        psError(PSPHOT_ERR_DATA, true, "Failed to find a valid PSF clump");
        return false;
    }
    psLogMsg ("psphot", 3, "psf clump  X,  Y: %f, %f\n", psfClump.X, psfClump.Y);
    psLogMsg ("psphot", 3, "psf clump DX, DY: %f, %f\n", psfClump.dX, psfClump.dY);

    // group into STAR, COSMIC, EXTENDED, SATURATED, etc.
    if (!pmSourceRoughClass (sources, recipe, psfClump, maskSat)) {
        psError(PSPHOT_ERR_PROG, false, "programming error calling pmSourceRoughClass");
        return false;
    }

    // optional printout of source moments only
    psphotDumpMoments (recipe, sources);

    psLogMsg ("psphot.roughclass", PS_LOG_INFO, "rough classification: %f sec\n", psTimerMark ("psphot"));

    return true;
}

