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

#include "ppImage.h"

bool ppImageMosaicChip(pmConfig *config, const ppImageOptions *options, const pmFPAview *view,
                       const char *outFile, const char *inFile)
{
    bool status;                        // Status of MD lookup

    pmFPAfile *in = psMetadataLookupPtr(&status, config->files, inFile); // Input file
    if (!status) {
        psErrorStackPrint(stderr, "Can't find required I/O file!\n");
        exit(EXIT_FAILURE);
    }

    pmFPAfile *out = psMetadataLookupPtr(&status, config->files, outFile); // Output file
    if (!status) {
        psErrorStackPrint(stderr, "Can't find required I/O file!\n");
        exit(EXIT_FAILURE);
    }

    pmChip *outChip = pmFPAviewThisChip(view, out->fpa);
    pmChip *inChip = pmFPAviewThisChip(view, in->fpa);
    if (!outChip->hdu && !outChip->parent->hdu) {
        const char *name = psMetadataLookupStr(&status, in->fpa->concepts, "FPA.OBS"); // Name of FPA
        pmFPAAddSourceFromView(out->fpa, name, view, out->format);
    }

    psTrace("pmChipMosaic", 5, "mosaic chip %s to %s (xbin,ybin: %d,%d to %d,%d)\n",
            in->name, out->name, in->xBin, in->yBin, out->xBin, out->yBin);

    // Mosaic the chip, making a deep copy.  This has the side effect of making the output
    // image products pure trimmed images, but also increases the memory footprint.
    status = pmChipMosaic(outChip, inChip, true, options->blankMask);
    return status;
}

bool ppImageMosaicFPA (pmConfig *config, const ppImageOptions *options, const char *outFile,
                       const char *inFile)
{
    bool status;                        // Status of MD lookup

    pmFPAfile *in = psMetadataLookupPtr(&status, config->files, inFile); // Input file
    if (!status) {
        psErrorStackPrint(stderr, "Can't find required I/O file!\n");
        exit(EXIT_FAILURE);
    }

    pmFPAfile *out = psMetadataLookupPtr(&status, config->files, outFile); // Output file
    if (!status) {
        psErrorStackPrint(stderr, "Can't find required I/O file!\n");
        exit(EXIT_FAILURE);
    }

    // XXX test printing of all concepts
    #if 0
    for (int i = 0; i < in->fpa->chips->n; i++) {
        pmChip *chip = in->fpa->chips->data[i];
        for (int j = 0; j < chip->cells->n; j++) {
            pmCell *cell = chip->cells->data[j];
            psMetadataPrint(stdout, cell->concepts, 2);
        }
    }
    #endif

    const char *name = psMetadataLookupStr(&status, in->fpa->concepts, "FPA.OBS"); // Name of FPA

    pmFPAview *view = pmFPAviewAlloc(0);
    pmFPAAddSourceFromView(out->fpa, name, view, out->format);
    psFree(view);

    psTrace ("pmFPAMosaic", 5, "mosaic fpa %s to %s (xbin,ybin: %d,%d to %d,%d)\n",
             in->name, out->name, in->xBin, in->yBin, out->xBin, out->yBin);
    return pmFPAMosaic(out->fpa, in->fpa, false, options->blankMask);
}
