# include "ppMerge.h"

ppMergeFileGroup *ppMergeReadChunk (psArray *fileGroups, pmConfig *config, int numChunk) {

    // select an available fileGroup
 
    bool haveMasks = psMetadataLookupBool(&mdok, arguments, "INPUTS.MASKS"); // Do we have masks?
    bool haveWeights = psMetadataLookupBool(&mdok, arguments, "INPUTS.WEIGHTS"); // Do we have weights?

    while (1) {
	// check for any fileGroups which can read data
	for (int j = 0; j < fileGroups->n; j++) {
	    ppMergeFileGroup *fileGroup = fileGroups->data[j];
	    if (fileGroup->read) continue;

	    psArray *readouts = fileGroup->readouts;

	    psTrace("ppStack", 2, "Reading data for chunk %d into fileGroup %d....n", numChunk, j);
	    for (int i = 0; i < readouts->n; i++) {
		pmReadout *inRO = readouts->data[i]; // Input readout

		// Read a chunk from a file
		pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT", i); 
		if (!pmReadoutReadChunk(inRO, file->fits, 0, rows, 0, config)) { 
		    psError(PS_ERR_IO, false, "Unable to read chunk %d for file PPMERGE.INPUT %d", numChunk, i);
		    return NULL;
		}							

		if (haveMasks) {
		    pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT.MASK", i); 
		    if (!pmReadoutReadChunkMask(inRO, file->fits, 0, rows, 0, config)) { 
			psError(PS_ERR_IO, false, "Unable to read chunk %d for file PPMERGE.INPUT.MASK %d", numChunk, NAME, i);
			return NULL;
		    }							
		}

		if (haveWeights) {
		    pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT.WEIGHT", i); 
		    if (!pmReadoutReadChunkWeight(inRO, file->fits, 0, rows, 0, config)) {
			psError(PS_ERR_IO, false, "Unable to read chunk %d for file PPMERGE.INPUT.WEIGHT %d", numChunk, NAME, i);
			return NULL;
		    }							
		}
	    }
	    fileGroup->read = fileGroup->busy = true;
	    return fileGroup;
	}

	// check for any fileGroups which are done processing
	bool wait = true;
	bool more = true;
	for (int j = 0; j < fileGroups->n; j++) {
	    ppMergeFileGroup *fileGroup = fileGroups->data[j];
	    if (!fileGroup->read || fileGroup->busy) continue;
	    
	    wait = false;
	    psArray *readouts = fileGroup->readouts;
	    // any more data to be read?
	    for (int i = 0; i < readouts->n && more; i++) {
		pmReadout *inRO = readouts->data[i];

		pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT", i);
		more &= pmReadoutMore(inRO, file->fits, 0, rows, config);

		if (haveMasks) {
		    pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT.MASK", i);
		    more &= pmReadoutMoreMask(inRO, file->fits, 0, rows, config);
		}
		if (haveWeights) {
		    pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT.WEIGHT", i);
		    more &= pmReadoutMoreWeight(inRO, file->fits, 0, rows, config);
		}
	    }
	    fileGroup->read = false;
	}
	if (!more) return NULL;

	if (wait) usleep (10000);
    }
    return NULL;
}
