# include "psastroInternal.h"

bool psastroAnalysis (pmConfig *config) {

    bool status;
    int nStars;

    // measure the total elapsed time in psastroAnalysis.
    psTimerStart ("psastroAnalysis");

    // select the current recipe
    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSASTRO_RECIPE);
    if (!recipe) {
	psError(PSASTRO_ERR_CONFIG, true, "Can't find PSASTRO recipe");
	return false;
    }

    if (!psastroUseModel (config, recipe)) {
	psError (PSASTRO_ERR_UNKNOWN, false, "failed to set model astrometry\n");
	return false;
    }

    // interpret the available initial astrometric information
    // apply the initial guess
    if (!psastroAstromGuess (&nStars, config)) {
	psError (PSASTRO_ERR_UNKNOWN, false, "failed to determine initial astrometry guess\n");
	return false;
    }
    if (nStars == 0) {
	psLogMsg ("psastro", 2, "skipping astrometry analysis : no stars\n");
	return true;
    }

    // load the reference stars overlapping the data stars
    psArray *refs = psastroLoadRefstars(config);
    if (!refs) {
	psError (PSASTRO_ERR_UNKNOWN, false, "failed to load reference data\n");
	return false;
    }

    if (!psastroChooseRefstars (config, refs)) {
	psError (PSASTRO_ERR_UNKNOWN, false, "failed to select reference data for chips\n");
	return false;
    }

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

    if (chipastro) {
      if (!psastroChipAstrom (config)) {
	    psError (PSASTRO_ERR_UNKNOWN, false, "failed to perform single chip astrometry\n");
	    return false;
	}
    } 
    if (mosastro) {
	if (!psastroMosaicAstrom (config)) {
	    psError (PSASTRO_ERR_UNKNOWN, false, "failed to perform mosaic camera astrometry\n");
	    return false;
	}
    }

    // XXX how do we specify stack astrometry?
    // psastroStackAstrom (config, refs);

    psFree (refs);
    return true;
}
