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

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

#include "ppStack.h"
#include "ppStackLoop.h"

bool ppStackCombinePrepare(const char *outName, const char *expName,
                           ppStackFileList files, ppStackThreadData *stack,
                           ppStackOptions *options, pmConfig *config)
{
    psAssert(stack, "Require stack");
    psAssert(options, "Require options");
    psAssert(config, "Require configuration");

    int row0, col0;                 // Offset for readout
    int numCols, numRows;           // Size of readout
    ppStackThread *thread = stack->threads->data[0]; // Representative thread
    if (!pmReadoutStackSetOutputSize(&col0, &row0, &numCols, &numRows, thread->readouts)) {
        psError(PPSTACK_ERR_ARGUMENTS, false, "problem setting output readout size.");
        return false;
    }

    pmFPAfileActivate(config->files, false, NULL);
    ppStackFileActivation(config, files, true);
    pmFPAview *view = ppStackFilesIterateDown(config); // View to readout
    if (!view) {
        return false;
    }

    pmCell *cell = pmFPAfileThisCell(config->files, view, outName); // Output cell
    options->outRO = pmReadoutAlloc(cell); // Output readout

    pmCell *expCell = pmFPAfileThisCell(config->files, view, expName); // Exposure cell
    options->expRO = pmReadoutAlloc(expCell); // Output readout

    psFree(view);

    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
    psAssert(recipe, "We've thrown an error on this before.");
    psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits to mask for bad
    psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels

    if (!pmReadoutStackDefineOutput(options->outRO, col0, row0, numCols, numRows, true, true, maskBad)) {
        psError(PPSTACK_ERR_ARGUMENTS, false, "Unable to prepare output.");
        return false;
    }

    if (!pmReadoutStackDefineOutput(options->expRO, col0, row0, numCols, numRows, true, true, 0)) {
        psError(PPSTACK_ERR_ARGUMENTS, false, "Unable to prepare output.");
        return false;
    }

    return true;
}
