# include "psphotInternal.h"

// generate mask and weight if not defined, additional mask for restricted subregion 
bool psphotSetMaskAndWeight (pmConfig *config, pmReadout *readout, psMetadata *recipe) {

    bool status;

    // ** Interpret the mask values:

    // single-bit named masks
    psMaskType maskMark = pmConfigMask("MARK",     config); // Mask value for marking
    psMetadataAddU8 (recipe, PS_LIST_TAIL, "MASK.MARK", PS_META_REPLACE, "user-defined mask", maskMark);

    psMaskType maskSat  = pmConfigMask("SAT", 	   config); // Mask value for saturated pixels
    psMetadataAddU8 (recipe, PS_LIST_TAIL, "MASK.SAT", PS_META_REPLACE, "user-defined mask", maskSat);

    psMaskType maskBad  = pmConfigMask("BAD", 	   config); // Mask value for bad pixels
    psMetadataAddU8 (recipe, PS_LIST_TAIL, "MASK.BAD", PS_META_REPLACE, "user-defined mask", maskBad);

    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
    psMaskType maskVal = psMetadataLookupU8(&status, recipe, "PSPHOT"); // Mask value for bad pixels
    if (!maskVal) {
      const char *maskValStr = psMetadataLookupStr(NULL, recipe, "MASKVAL"); // String with mask names
      if (!maskValStr) {
        psError(PSPHOT_ERR_CONFIG, false, "Missing recipe item: MASKVAL(STR)");
        return false;
      }
      maskVal = pmConfigMask(maskValStr, config); // Mask values to mask against
      psMetadataAddU8 (recipe, PS_LIST_TAIL, "MASK.PSPHOT", PS_META_REPLACE, "user-defined mask", maskVal);
      assert (maskVal);
    }

    // generate mask & weight images if they don't already exit
    if (!readout->mask) {
        if (!pmReadoutGenerateMask(readout, maskSat, maskBad)) {
            psError (PSPHOT_ERR_CONFIG, false, "trouble creating mask");
            return false;
        }
    }
    if (!readout->weight) {
        if (!pmReadoutGenerateWeight(readout, true)) {
            psError (PSPHOT_ERR_CONFIG, false, "trouble creating weight");
            return false;
        }
    }

    // mask the excluded outer pixels
    // these coordinates refer to the parent image
    // these bounds will saturate on the subimage
    // negative upper bounds will subtract from the *subimage*
    float XMIN  = psMetadataLookupF32 (&status, recipe, "XMIN");
    float XMAX  = psMetadataLookupF32 (&status, recipe, "XMAX");
    float YMIN  = psMetadataLookupF32 (&status, recipe, "YMIN");
    float YMAX  = psMetadataLookupF32 (&status, recipe, "YMAX");
    psRegion valid = psRegionSet (XMIN, XMAX, YMIN, YMAX);

    // restrict the supplied region above to the valid area on the image
    psRegion keep = psRegionForImage (readout->image, valid);

    // psImageKeepRegion assumes the region refers to the parent coordinates
    psImageKeepRegion (readout->mask, keep, "OR", maskBad);

    // test output of files at this stage
    if (psTraceGetLevel("psphot") >= 5) {
        psphotSaveImage (NULL, readout->image,  "image.fits");
        psphotSaveImage (NULL, readout->mask,   "mask.fits");
        psphotSaveImage (NULL, readout->weight, "weight.fits");
    }

    return true;
}
