#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

# include "psphot.h"
# define RADIUS_TYPE float

static float PSF_FIT_NSIGMA;
static float PSF_FIT_PADDING;
static pmModelRadius modelRadiusPSF;

bool psphotInitRadiusPSF (psMetadata *recipe, pmModelType type) {

    bool status;

    PSF_FIT_NSIGMA   = psMetadataLookupF32 (&status, recipe, "PSF_FIT_NSIGMA");
    PSF_FIT_PADDING  = psMetadataLookupF32 (&status, recipe, "PSF_FIT_PADDING");

    // this function specifies the radius at this the model hits the given flux
    modelRadiusPSF       = pmModelRadius_GetFunction (type);
    return true;
}

bool psphotCheckRadiusPSF (pmReadout *readout, pmSource *source, pmModel *model) {

    pmMoments *moments = source->moments;
    if (moments == NULL) return false;

    // set the fit radius based on the object flux limit and the model
    model->radiusTMP = (RADIUS_TYPE) (modelRadiusPSF (model->params, PSF_FIT_NSIGMA*moments->dSky) + PSF_FIT_PADDING);
    if (isnan(model->radiusTMP)) psAbort ("apply_psf_model", "error in radius");
	
    if (source->mode & PM_SOURCE_MODE_SATSTAR) {
	model->radiusTMP *= 2;
    }

    bool status = pmSourceRedefinePixels (source, readout, model->params->data.F32[2], model->params->data.F32[3], model->radiusTMP);
    return status;
}

bool psphotCheckRadiusPSFBlend (pmReadout *readout, pmSource *source, pmModel *model, float dR) {

    pmMoments *moments = source->moments;
    if (moments == NULL) return false;

    // set the fit radius based on the object flux limit and the model
    model->radiusTMP = (RADIUS_TYPE) (modelRadiusPSF (model->params, PSF_FIT_NSIGMA*moments->dSky) + dR + PSF_FIT_PADDING);
    if (isnan(model->radiusTMP)) psAbort ("apply_psf_model", "error in radius");
	
    if (source->mode &  PM_SOURCE_MODE_SATSTAR) {
	model->radiusTMP *= 2;
    }

    bool status = pmSourceRedefinePixels (source, readout, model->params->data.F32[2], model->params->data.F32[3], model->radiusTMP);
    return status;
}

static float EXT_FIT_NSIGMA;
static float EXT_FIT_PADDING;
static pmModelRadius modelRadiusEXT;

bool psphotInitRadiusEXT (psMetadata *recipe, pmModelType type) {

    bool status;

    EXT_FIT_NSIGMA   = psMetadataLookupF32 (&status, recipe, "EXT_FIT_NSIGMA");
    EXT_FIT_PADDING  = psMetadataLookupF32 (&status, recipe, "EXT_FIT_PADDING");

    // this function specifies the radius at this the model hits the given flux
    modelRadiusEXT       = pmModelRadius_GetFunction (type);
    return true;
}

bool psphotCheckRadiusEXT (pmReadout *readout, pmSource *source, pmModel *model) {

    pmMoments *moments = source->moments;
    if (moments == NULL) return false;

    // set the fit radius based on the object flux limit and the model
    model->radiusTMP = (RADIUS_TYPE) (modelRadiusEXT (model->params, EXT_FIT_NSIGMA*moments->dSky) + EXT_FIT_PADDING);
    if (isnan(model->radiusTMP)) psAbort (__func__, "error in radius");

    // redefine the pixels if needed
    bool status = pmSourceRedefinePixels (source, readout, model->params->data.F32[2], model->params->data.F32[3], model->radiusTMP);
    return status;
}
