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

#include <stdio.h>
#include <pslib.h>
#include <psmodules.h>

#include "pswarp.h"

bool pswarpPixelFraction(const pmReadout *readout, psMetadata *stats, const pmConfig *config)
{
    PS_ASSERT_PTR_NON_NULL(readout, false);
    PS_ASSERT_IMAGE_NON_NULL(readout->image, false);
    PS_ASSERT_IMAGE_TYPE(readout->image, PS_TYPE_F32, false);
    if (!readout->mask) {
        // Can't do anything
        return true;
    }
    PS_ASSERT_IMAGE_NON_NULL(readout->mask, false);
    PS_ASSERT_IMAGES_SIZE_EQUAL(readout->mask, readout->image, false);
    PS_ASSERT_IMAGE_TYPE(readout->mask, PS_TYPE_MASK, false);

    if (stats) {
        PS_ASSERT_METADATA_NON_NULL(stats, false);
    }
    PS_ASSERT_PTR_NON_NULL(config, false);
    PS_ASSERT_METADATA_NON_NULL(config->arguments, false);

    float minFrac = psMetadataLookupF32(NULL, config->arguments, "ACCEPT.FRAC"); // Minimum fraction
    psMaskType maskPoor = psMetadataLookupU8(NULL, config->arguments, "MASK.POOR"); // Mask for "poor" data
    psMaskType maskBad = psMetadataLookupU8(NULL, config->arguments, "MASK.BAD"); // Mask for bad data
    psMaskType maskVal = maskPoor | maskBad; // Mask to apply

    psImage *image = readout->image;    // Image of interest
    psImage *mask = readout->mask;      // Mask image

    int numCols = image->numCols, numRows = image->numRows; // Size of image
    long numPix = numCols * numRows;

    long numBad = 0;                     // Number of bad pixels
    for (int y = 0; y < numRows; y++) {
        for (int x = 0; x < numCols; x++) {
            if (mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal) {
                numBad++;
            }
        }
    }

    float goodFrac = (numPix - numBad) / (float)numPix; // Fraction of good pixels
    bool accept = (goodFrac >= minFrac ? true : false); // Accept this readout?

    if (stats) {
        psMetadataAddBool(stats, PS_LIST_HEAD, "ACCEPT", 0, "Accept this readout?", accept);
    }

    return accept;
}

