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

#include "psvideophot.h"

#define ESCAPE(MESSAGE) { \
  psError(PS_ERR_UNKNOWN, false, MESSAGE); \
  psFree(view); \
  pmFPAfileFreeSetStrict(false); \
  return false; \
}

bool psvideophotLoop(pmConfig *config, psvideophotOptions *options)
{
    psMetadata *stats = NULL;           // Statistics to output
    float timeDetrend = 0;              // Amount of time spent in detrend
    float timePhot = 0;                 // Amount of time spent in photometry

    if (options->doStats) {
        stats = psMetadataAlloc();
        psMetadataAddS32(stats, PS_LIST_TAIL, "QUALITY", 0, "No problems", 0);
    }

    bool status;                        // Status of MD lookup

    pmFPAfile *input = psMetadataLookupPtr(&status, config->files, "PSVIDEOPHOT.INPUT");
    
    if (!status) {
        psErrorStackPrint(stderr, "Can't find input data!\n");
        psvideophotCleanup(config, options);
        exit(PS_EXIT_PROG_ERROR);
    }

    pmConfigCamerasCull(config, NULL);
    pmConfigRecipesCull(config, "PSVIDEOPHOT,PPSTATS,PSPHOT,MASKS,PSASTRO,JPEG");

    pmFPAview *view = pmFPAviewAlloc(0);// View for level of interest
    pmHDU *lastHDU = NULL;              // Last HDU that was updated

    // files associated with the science image
    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
        ESCAPE("load failure for FPA");
    }

    pmChip *chip;                       // Chip from FPA
    while ((chip = pmFPAviewNextChip(view, input->fpa, 1)) != NULL) {
        psLogMsg ("psvideophotLoop", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
        if (!chip->process || !chip->file_exists) {
            continue;
        }
        if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
            ESCAPE("load failure for Chip");
        }


        psTimerStart(TIMER_DETREND);
        pmCell *cell;                   // Cell from chip
        while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
            psLogMsg ("psvideophotLoop", 5, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
            if (!cell->process || !cell->file_exists) {
                continue;
            }
            if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
                ESCAPE("load failure for Cell");
            }

            // Put version information into the header
            pmHDU *hdu = pmHDUGetHighest(input->fpa, chip, cell);
            if (hdu && hdu != lastHDU) {
                psvideophotVersionHeader(hdu->header);
                lastHDU = hdu;
            }

            // XXX for now, skip the video cells (cell->readouts->n > 1)
            if (cell->readouts->n <2) {
	      psWarning("Skipping Non-Video Cell for psvideophotDetrendReadout");
	      continue; 
	    }
	    psWarning("Found video cell\n");

            // process each of the readouts
            pmReadout *readout;         // Readout from cell
            while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
	      if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
                    ESCAPE("load failure for Readout");
	      }
	      
                if (!readout->data_exists) {
                    continue;
                }
		psWarning ( "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
            }
	    
	    

        }
        // free detrend images potentially in use: MASK, BIAS, DARK, SHUTTER, FLAT
        timeDetrend += psTimerClear(TIMER_DETREND);

        // we perform photometry on the readouts of this chip in the output

        psTimerStart(TIMER_PHOT);
        timePhot += psTimerClear(TIMER_PHOT);

        view->cell = -1;
	psWarning ("Got here\n");
	//  while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
	//  psWarning ( "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
	//  if (!cell->process || !cell->file_exists) {
	//       continue;
	//   }
	//   psWarning ("Got here: inner loop\n");
	    
        //    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
	//       ESCAPE("save failure for Cell");
	//   }
        //}

        // Close chip
        if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
            ESCAPE("save failure for Chip");
        }
    }
    
    if (psTraceGetLevel("psvideophot") >= 3) {
        psvideophotFileCheck(config);
    }
    
    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
        ESCAPE("save failure for FPA");
    }
    psFree(view);

    // Dump configuration
    psString dump_file = psMetadataLookupStr(&status, config->arguments, "DUMP_CONFIG");
    if (dump_file) {
        if (!pmConfigDump(config, dump_file)) {
            ESCAPE("Unable to dump configuration.");
        }
    }


    psFree (stats);

    return true;
}
