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

#include "dvoMakeCorr.h"

bool dvoMakeCorrUnbin (pmConfig *config, pmFPAview *view, char *outName, char *inName, char *refName) {
    
    bool status;

    pmFPAfile *inFile = psMetadataLookupPtr (&status, config->files, inName);
    pmFPAfile *refFile = psMetadataLookupPtr (&status, config->files, refName);
    pmFPAfile *outFile = psMetadataLookupPtr (&status, config->files, outName);
    assert (inFile);
    assert (refFile);
    assert (outFile);

    pmCell *refCell = pmFPAviewThisCell (view, refFile->fpa);
    assert (refCell);

    pmReadout *inData = pmFPAviewThisReadout (view, inFile->fpa);
    assert (inData);

    // determine the output array size based on the reference TRIMSEC values
    psRegion *trimsec = psMetadataLookupPtr(NULL, refCell->concepts, "CELL.TRIMSEC");
    assert (trimsec);

    // I have the fine and ruff image sizes, determine the binning factor
    psImageBinning *binning = psImageBinningAlloc();
    binning->nXruff = inData->image->numCols;
    binning->nYruff = inData->image->numRows;
    binning->nXfine = trimsec->x1 - trimsec->x0;
    binning->nYfine = trimsec->y1 - trimsec->y0;
    psImageBinningSetScale (binning, PS_IMAGE_BINNING_CENTER);
    psImageBinningSetSkip(binning, inData->image);

    // construct the supporing pmFPA/pmChip/pmCell structures
    pmReadout *outData = pmFPAviewThisReadout (view, outFile->fpa);
    if (outData == NULL) {
	pmChip *inChip = pmFPAviewThisChip (view, inFile->fpa);
	pmChip *outChip = pmFPAviewThisChip (view, outFile->fpa);

	pmChipCopyStructure (outChip, inChip, binning->nXbin, binning->nYbin);
	outData = pmFPAviewThisReadout (view, outFile->fpa);
	assert (outData != NULL);
    }

    // generate the output (fine-scale) image array
    psImageRecycle (outData->image, binning->nXfine, binning->nYfine, PS_TYPE_F32);

    // linear interpolation to full fine scale
    if (!psImageUnbin (outData->image, inData->image, binning)) {
	psError (PS_ERR_UNKNOWN, true, "failed to unbin image");
	psFree (binning);
	return false;
    }

    // the input image is in magnitudes.  convert here to a multiplicative factor...
    for (int j = 0; j < outData->image->numRows; j++) {
	for (int i = 0; i < outData->image->numCols; i++) {
	    float value = outData->image->data.F32[j][i]; 
	    outData->image->data.F32[j][i] = pow(10.0, -0.4*value);
	}
    }

    // psFits *fits = psFitsOpen ("tmp.fits", "w");
    // psFitsWriteImage (fits, NULL, outData->image, 0, NULL);
    // psFitsClose (fits);
    // exit (0);

    psFree (binning);
    return true;
}
