# include "ppSim.h"

// XXX this function is currently disabled -- need to update code below to distinguish the fake
// and force positions, etc
bool ppSimPhotomReadoutFake(pmConfig *config, const pmFPAview *view) {

    psTimerStart ("psphotReadout");

    // select the current recipe
    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
    if (!recipe) {
        psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSPHOT_RECIPE);
        return false;
    }

    // *** in this section, perform the photometry for real + fake sources on PPSIM.FAKE.CHIP ***

    // find the currently selected readout.
    // we always perform photometry on the mosaiced chip
    pmReadout  *readout = pmFPAfileThisReadout (config->files, view, "PPSIM.FAKE.CHIP");
    PS_ASSERT_PTR_NON_NULL (readout, false);

    // the previously measured real sources are loaded into the PPSIM.REAL.SOURCES pmFPAfile
    psArray *realMeasuredSources = ppSimSelectSources (config, view, "PPSIM.REAL.SOURCES");
    PS_ASSERT_PTR_NON_NULL (realMeasuredSources, false);

    // the newly injected fake sources are saved on the PPSIM.OUTPUT pmFPAfile
    psArray *injectedSources = ppSimSelectSources (config, view, "PPSIM.OUTPUT");
    PS_ASSERT_PTR_NON_NULL (injectedSources, false);

    // Generate the mask and variance images, including the user-defined analysis region of interest
    psphotSetMaskAndVariance (config, view);

    // XXX need to define the source pixels
    ppSimDefinePixels (realMeasuredSources, readout, recipe);
    ppSimDefinePixels (injectedSources, readout, recipe);

    // make a copy of the injected fake-source parameters so these can be saved independently
    // from the measured fake-source parameters
    psArray *fakeSources = psArrayAlloc (injectedSources->n);
    for (int i = 0; i < injectedSources->n; i++) {
      fakeSources->data[i] = pmSourceCopy (injectedSources->data[i]);
    }

    // make a copy of the measured real-source parameters so these can be fitted here and in
    // ppSimPhotomReadoutForce, if desired.
    psArray *realSources = psArrayAlloc (realMeasuredSources->n);
    for (int i = 0; i < realMeasuredSources->n; i++) {
        realSources->data[i] = pmSourceCopy (realMeasuredSources->data[i]);
    }

    // load the psf model, if suppled.  FWHM_X,FWHM_Y,etc are saved in the recipe
    // this function uses PSPHOT.PSF.LOAD as the pmFPAfile
    psphotLoadPSF (config, view);

    // remove all sources
    psphotRemoveAllSources (realSources, recipe);

    // generate a background model (median, smoothed image)
    if (!psphotModelBackgroundReadoutFileIndex (config, view, "PPSIM.FAKE.CHIP", 0)) {
        return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);
    }
    if (!psphotSubtractBackgroundReadout (config, view, "PPSIM.FAKE.CHIP", 0, recipe)) {
        return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);
    }

    // add noise for real (subtracted) objects
    psphotAddNoise (readout, realSources, recipe);

    // XXX fake sources should measure peak->x,y, force sources should not
    psImageMaskType maskVal = 0xff;
    psImage *significance = psphotSignificanceImage (readout, recipe, 1, maskVal);
    ppSimDetections (significance, recipe, fakeSources);
    psFree (significance);

    // remove noise for subtracted objects (ie, return to normal noise level)
    psphotSubNoise (readout, realSources, recipe);

    // replace all sources
    psphotReplaceAllSources (realSources, recipe);

    // construct an initial model for each object
    psphotGuessModels (config, readout, realSources, psf);
    psphotGuessModels (config, readout, fakeSources, psf);

    // linear fit to real + fake sources
    psArray *sources = ppSimMergeSources (realSources, fakeSources);
    psphotFitSourcesLinear (readout, sources, recipe, psf, FALSE); // XXX option to NOT subtract
    psphotReplaceAllSources (sources, recipe);
    psFree (sources); // only frees the merged references

    // calculate source magnitudes (for which set??)
    psphotMagnitudes(config, readout, view, fakeSources, psf);

    // drop the references to the image pixels held by each source
    psphotSourceFreePixels (realSources);
    psphotSourceFreePixels (fakeSources);

    // create the exported-metadata and free local data
    // XXX this places the sources on readout->analysis as PSPHOT.SOURCES.  modify?
    // (or don't supply the sources, and do this with a different function)
    psphotReadoutCleanup(config, readout, recipe, NULL, psf, NULL);

    pmCell    *fakeCell    = pmFPAfileThisCell (config->files, view, "PPSIM.FAKE.SOURCES"); psAssert (fakeCell, "no cell?");
    pmChip    *fakeChip    = pmFPAfileThisChip (config->files, view, "PPSIM.FAKE.SOURCES"); psAssert (fakeChip, "no chip?");
    pmReadout *fakeReadout = pmFPAfileThisReadout (config->files, view, "PPSIM.FAKE.SOURCES");
    if (!fakeReadout) {
        fakeReadout = pmReadoutAlloc (fakeCell);
        psFree (fakeReadout); // there is a copy on 'cell' as well
    }
    psAssert (fakeReadout, "no fakeReadout?");
    pmChipSetDataStatus (fakeChip, true);

    pmDetections *detections = pmDetectionsAlloc();
    detection->allSources = fakeSources;

    psMetadataAddArray (fakeReadout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE, "fake photometry ", detections);
    psFree(detections);

    return true;
}
