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

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

#include "ppMerge.h"
#include "ppMergeConfig.h"
#include "ppMergeData.h"
#include "ppMergeOptions.h"
#include "ppMergeCheckInputs.h"
#include "ppMergeCombine.h"
#include "ppMergeScaleZero.h"
#include "ppMergeMask.h"

//#include "ppMem.h"

// Yet to do:
//
// 1. Mask pixels with less than the minimum number of electrons
// 2. Sampling factor for background measurement
// 3. On/off pairs

int main(int argc, char **argv)
{
    psLibInit(NULL);
    psMemSetThreadSafety(false);           // Turn off thread safety, for more
    psTimerStart(TIMERNAME);

    // Parse the configuration and arguments
    // Open the input image(s)
    // Determine camera, format from header if not already defined
    // Construct camera in preparation for reading
    pmConfig *config = ppMergeConfig(argc, argv);

    // Set various tasks (define optional operations)
    ppMergeOptions *options = ppMergeOptionsParse(config);

    // Check the inputs
    ppMergeData *data = ppMergeCheckInputs(options, config);
    if (!data) {
        psError(PS_ERR_IO, false, "Not enough valid input files.\n");
        exit(EXIT_FAILURE);
    }

    if (options->mask) {
        // Generate a mask
        ppMergeMask(data, options, config);
    } else {

        psImage *scale = NULL;              // The scalings
        psImage *zero = NULL;               // The zeros
        psArray *shutters = NULL;           // The shutter correction data

        // Measure the background in each image
        ppMergeScaleZero(&scale, &zero, &shutters, data, options, config);

        // Do the combination and write
        ppMergeCombine(scale, zero, shutters, data, options, config);

        psFree(scale);
        psFree(zero);
        psFree(shutters);
    }

    // Output the statistics
    if (data->statsFile) {
        psString statsOut = psMetadataConfigFormat(data->stats); // String to write out
        fprintf(data->statsFile, "%s", statsOut);
        psFree(statsOut);
    }

#if 0
    pmFPAPrint(stdout, data->out, true, true);
#endif

    // Cleaning up
    psFree(data);
    psFree(options);
    psFree(config);

    pmConceptsDone();
    pmConfigDone();
    psLibFinalize();

//    ppMemCheck();

    return EXIT_SUCCESS;
}
