#include <stdio.h>
#include "pslib.h"
#include "stac.h"


int main(int argc, char **argv)
{

#if 0
    psMemAllocateCallbackSet(stacMemPrint);
    psMemAllocateCallbackSetID(185);
    psMemFreeCallbackSet(stacMemPrint);
    psMemFreeCallbackSetID(185);
#endif

    // Set trace levels
    psTraceSetLevel(".",0);
    psTraceSetLevel("stac.checkMemory",10);
    psTraceSetLevel("stac.config",10);
    psTraceSetLevel("stac.read",10);
    psTraceSetLevel("stac.invertMaps",10);
    psTraceSetLevel("stac.errors",10);
    psTraceSetLevel("stac.transform",10);
    psTraceSetLevel("stac.combine",10);
    psTraceSetLevel("stac.rejection",10);

    // Set logging level
    psLogSetLevel(9);

    // Parse command line
    stacConfig *config = stacParseConfig(argc, argv);

    // Read input files
    psArray *inputs = stacReadImages(config);

    // Read maps
    psArray *maps = stacReadMaps(config);

    // Invert maps
    psArray *inverseMaps = stacInvertMaps(maps);

    // Generate errors
    psArray *errors = stacErrorImages(inputs, config);

    // Transform inputs and errors
    psArray *transformedErrors = NULL;
    psArray *transformed = stacTransform(inputs, inverseMaps, errors, &transformedErrors, NULL, config);

    // Combine with rejection
    psArray *rejected = NULL;
    psImage *combined = stacCombine(transformed, transformedErrors, 1,  &rejected, config);

#ifdef TESTING
    char prefile[MAXCHAR];		// Filename of precombined image
    sprintf(prefile,"%s.pre",config->output);
    psImageWriteSection(combined,0,0,0,NULL,0,prefile);
#endif

    // Transform rejected pixels to source frame
    psArray *rejectedSource = stacRejection(inputs, transformed, combined, maps, rejected, config);

    // Redo transformation with the mask
    psFree(transformed);
    psFree(transformedErrors);
    psArray *transformedErrorsNew = NULL;
    psArray *transformedNew = stacTransform(inputs, inverseMaps, errors, &transformedErrorsNew,
					    rejectedSource, config);

    // Combine the newly-transformed CR-free images, no rejection
    psFree(combined);
    psFree(rejected);
    rejected = NULL;
    combined = stacCombine(transformedNew, transformedErrorsNew, 0,  &rejected, config);

    // Write output image
    psImageWriteSection(combined,0,0,0,NULL,0,config->output);

    // Free everything I've used
    stacConfigFree(config);
    psFree(inputs);
    psFree(maps);
    psFree(inverseMaps);
    psFree(errors);
    psFree(transformedErrors);
    psFree(transformedNew);
    psFree(rejectedSource);
    psFree(combined);

    // Check memory for leaks, corruption
    stacCheckMemory();
}
