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

# include "ppImage.h"

// this function is mostly equivalent to the top-level of psastro, with some
// modifications since the data has already been loaded.
bool ppImageAstrom (pmConfig *config) {

    bool status;

    // select recipe options supplied on command line
    // XXX move these options to the "PSASTRO" recipe?
    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSASTRO_RECIPE);

    // find or define a pmFPAfile PSPHOT.INPUT
    pmFPAfile *input = psMetadataLookupPtr (&status, config->files, "PSASTRO.INPUT");
    if (!status) {
	// psphotReadout requires a pmFPAfile supplied with the name PSASTRO.INPUT
	// create a pmFPAfile which points at PSPHOT.OUTPUT
	// mode is 'REFERENCE' to prevent double frees of the fpa
	pmFPAfile *output = psMetadataLookupPtr (&status, config->files, "PSPHOT.OUTPUT");
	input = pmFPAfileDefineInput (config, output->fpa, "PSASTRO.INPUT");
	input->mode = PM_FPA_MODE_REFERENCE;

	pmFPAfileDefineOutput (config, input->fpa, "PSASTRO.OUTPUT");
    }

    // convert the output sources created by psphot into astrometry objects
    if (!psastroConvertFPA (input->fpa, recipe)) {
	psErrorStackPrint(stderr, "error loading input data\n");
	exit (1);
    }

    // interpret the available initial astrometric information
    // apply the initial guess
    if (!psastroAstromGuess (config)) {
	psErrorStackPrint(stderr, "failed to determine initial astrometry guess\n");
	exit (1);
    }

    // load the reference stars overlapping the data stars
    psArray *refs = psastroLoadRefstars(config);
    if (!refs) {
	psErrorStackPrint(stderr, "failed to load reference data\n");
	exit (1);
    }

    if (!psastroChooseRefstars (config, refs)) {
	psErrorStackPrint(stderr, "failed to select reference data for chips\n");
	exit (1);
    }

    // XXX does this check the recipe??
    bool chipastro = psMetadataLookupBool (NULL, config->arguments, "PSASTRO.CHIP.MODE");
    bool mosastro  = psMetadataLookupBool (NULL, config->arguments, "PSASTRO.MOSAIC.MODE");
    if (!chipastro && !mosastro) {
	psLogMsg ("psastro", 3, "no astrometry mode selected, assuming chip mode\n");
	chipastro= true;
    }

    if (chipastro) {
      if (!psastroChipAstrom (config, refs)) {
	    psErrorStackPrint(stderr, "failed to perform single chip astrometry\n");
	    exit (1);
	}
    } 
    if (mosastro) {
	if (!psastroMosaicAstrom (config, refs)) {
	    psErrorStackPrint(stderr, "failed to perform mosaic camera astrometry\n");
	    exit (1);
	}
    }

    // XXX should this be left to the ppImageLoop?
    psastroDataSave (config);

    psFree (refs);
    return true;
}
