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

# include "ppImage.h"

// In this function, we perform the psphot analysis routine for the chip-mosaicked images
bool ppImageReplaceBackground (pmConfig *config, pmFPAview *view, ppImageOptions *options) {

    bool status;
    pmCell *cell;
    pmReadout *readout;

    // find the reference source image
    pmFPAfile *input = psMetadataLookupPtr (&status, config->files, "PPIMAGE.CHIP");
    if (!status) {
        psError(PSPHOT_ERR_CONFIG, false, "PSPHOT.INPUT I/O file is not defined");
        return false;
    }

    // find the model data, if it exists yet (if not, we build it below)
    pmFPAfile *modelFile = psMetadataLookupPtr(&status, config->files, "PSPHOT.BACKMDL");

    // select the appropriate recipe information
    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);

    // define the mask value to be used in ppImage
    psMaskType maskVal  = options->satMask | options->badMask | options->flatMask | options->blankMask;

    float meanValue = psMetadataLookupF32 (&status, recipe, "SKY_MEAN");

    // iterate over the cells and readout for this chip
    while ((cell = pmFPAviewNextCell (view, input->fpa, 1)) != NULL) {
	psLogMsg ("ppImagePhotom", 5, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
	if (! cell->process || ! cell->file_exists) { continue; }

	// process each of the readouts
	while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
	    if (! readout->data_exists) { continue; }
	    if (! readout->mask) { continue; }

	    // replace masked pixels with values from model (unbinning not needed)

	    // we are using this pmFPAfile as an I/O file: select readout or create
	    pmReadout *modelReadout = NULL;
	    if (modelFile) {
		modelReadout = pmFPAviewThisReadout (view, modelFile->fpa);
	    }
	    if (!modelReadout) {
		psphotModelBackground (config, view, "PPIMAGE.CHIP");
		modelFile = psMetadataLookupPtr(&status, config->files, "PSPHOT.BACKMDL");
		assert (modelFile);
		if (modelFile->mode == PM_FPA_MODE_INTERNAL) {
		  modelReadout = modelFile->readout;
		} else {
		  modelReadout = pmFPAviewThisReadout (view, modelFile->fpa);
		}
		assert (modelReadout);
	    }

	    psImageBinning *binning = psMetadataLookupPtr(&status, recipe, "PSPHOT.BACKGROUND.BINNING");

	    psImage *mask = readout->mask;
	    psImage *image = readout->image;
	    psImage *model = modelReadout->image;

	    for (int iy = 0; iy < image->numRows; iy++) {
		for (int ix = 0; ix < image->numCols; ix++) {
		    if (!(mask->data.U8[iy][ix] && maskVal)) continue;
		    if (1) {
			image->data.F32[iy][ix] = meanValue;
		    } else {
			image->data.F32[iy][ix] = psImageUnbinPixel_V2(ix, iy, model, binning);
		    }
		}
	    }
	}
    }
    pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL");
    pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL.STDEV");
    return true;
}
