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

# include "psphot.h"

// define the needed / desired I/O files
bool psphotParseCamera (pmConfig *config) {

    bool status = false;

    // the input image defines the camera
    pmFPAfile *input = pmFPAfileDefineFromArgs (&status, config, "PSPHOT.INPUT", "INPUT");
    if (!status) {
	psError(PSPHOT_ERR_CONFIG, false, "Failed to build FPA from PSPHOT.INPUT");
	return status;
    }

    // select recipe options supplied on command line
    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes,   "PSPHOT");
    psMetadata *options = psMetadataLookupPtr (&status, config->arguments, "PSPHOT.OPTIONS");
    psMetadataCopy (recipe, options);

    // set default recipe values here
    psMetadataAddStr (recipe, PS_LIST_TAIL, "FITMODE",         PS_META_NO_REPLACE, "default fitting mode", "NONE");
    psMetadataAddStr (recipe, PS_LIST_TAIL, "PHOTCODE",        PS_META_NO_REPLACE, "default photcode",     "NONE");
    psMetadataAddStr (recipe, PS_LIST_TAIL, "BREAK_POINT",     PS_META_NO_REPLACE, "default break point",  "NONE");
    psMetadataAddF32 (recipe, PS_LIST_TAIL, "ZERO_PT",         PS_META_NO_REPLACE, "default zero point",    25.00);
    psMetadataAddS32 (recipe, PS_LIST_TAIL, "BACKGROUND.XBIN", PS_META_NO_REPLACE, "default binning",          64);
    psMetadataAddS32 (recipe, PS_LIST_TAIL, "BACKGROUND.YBIN", PS_META_NO_REPLACE, "default binning",          64);

    // these calls bind the I/O handle to the specified fpa
    if (!psMetadataLookup(recipe, "SAVE.OUTPUT") ||
	psMetadataLookupBool(NULL, recipe, "SAVE.OUTPUT")) {
	if (!pmFPAfileDefineOutput (config, input->fpa, "PSPHOT.OUTPUT")) {
	    psError(PS_ERR_IO, false, "Cannot find a rule for PSPHOT.OUTPUT");
	    return false;
	}
    }

    // optionally save the residual image 
    if (psMetadataLookupBool(NULL, recipe, "SAVE.RESID")) {
	pmFPAfileDefineOutput (config, input->fpa, "PSPHOT.RESID");
    }

    int DX = psMetadataLookupS32 (&status, recipe, "BACKGROUND.XBIN");
    int DY = psMetadataLookupS32 (&status, recipe, "BACKGROUND.YBIN");

    // these calls construct a new fpa for the I/O handle 

    // optionally save the background model (small FITS image)
    if (psMetadataLookupBool(NULL, recipe, "SAVE.BACKMDL")) {
	pmFPAfileDefineFromFPA (config, input->fpa, DX, DY, "PSPHOT.BACKMDL");
    }
    // optionally save the full background image
    if (psMetadataLookupBool(NULL, recipe, "SAVE.BACKGND")) {
	pmFPAfileDefineFromFPA (config, input->fpa,  1,  1, "PSPHOT.BACKGND");
    }
    // optionally save the background-subtracted image
    if (psMetadataLookupBool(NULL, recipe, "SAVE.BACKSUB")) {
	pmFPAfileDefineFromFPA (config, input->fpa,  1,  1, "PSPHOT.BACKSUB");
    }
    // optionally save the PSF Model
    if (psMetadataLookupBool(NULL, recipe, "SAVE.PSF")) {
	pmFPAfileDefineOutput (config, input->fpa, "PSPHOT.PSF.SAVE");
    }
    // optionally load the PSF Model
    if (psMetadataLookupBool(NULL, recipe, "LOAD.PSF")) {
	pmFPAfileDefineInput (config, input->fpa, "PSPHOT.PSF.LOAD");
    }

    // pmFPAfileConstruct (config->files, format, config->camera, "PSPHOT.PSF_SAMPLE");

    // Chip selection: turn on only the chips specified (pass status to suppress missing-key log msg)
    char *chipLine = psMetadataLookupStr(&status, config->arguments, "CHIP_SELECTIONS");
    psArray *chips = psStringSplitArray (chipLine, ",", false);
    if (chips->n > 0) {
	pmFPASelectChip (input->fpa, -1, true); // deselect all chips
	for (int i = 0; i < chips->n; i++) {
	    int chipNum = atoi(chips->data[i]);
	    if (! pmFPASelectChip(input->fpa, chipNum, false)) {
		psError(PS_ERR_IO, false, "Chip number %d doesn't exist in camera.\n", chipNum);
		return false;
	    }
        }
    }
    psFree (chips);

    psTrace(__func__, 1, "Done with psphotParseCamera...\n");

    psErrorClear();			// some metadata lookup may have failed

    return true;
}
