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

#include <stdio.h>
#include <string.h>
#include <assert.h>

#include <pslib.h>

#include "pmFPA.h"
#include "pmConceptsUpdate.h"

bool pmConceptsUpdate(const pmFPA *fpa, const pmChip *chip, const pmCell *cell)
{
    if (fpa) {
        // Check for FPA concepts updates
    }

    if (chip) {
        // Check for chip concepts updates
    }

    if (cell) {
        // Check for cell concepts updates

        // CELL.TRIMSEC needs to be updated for the binning
        if (psMetadataLookup(cell->concepts, "CELL.TRIMSEC.UPDATE")) {
            bool xStatus, yStatus; // Status of MD lookups
            int xBin = psMetadataLookupS32(&xStatus, cell->concepts, "CELL.XBIN");
            int yBin = psMetadataLookupS32(&yStatus, cell->concepts, "CELL.YBIN");
            if (xStatus && yStatus && xBin != 0 && yBin != 0) {
                psRegion *trimsec = psMetadataLookupPtr(NULL, cell->concepts, "CELL.TRIMSEC"); // Trim section
                trimsec->x0 /= xBin;
                trimsec->x1 /= xBin;
                trimsec->y0 /= yBin;
                trimsec->y1 /= yBin;

                psMetadataRemoveKey(cell->concepts, "CELL.TRIMSEC.UPDATE");
            }
        }

        // CELL.BIASSEC needs to be updated for the binning
        if (psMetadataLookup(cell->concepts, "CELL.BIASSEC.UPDATE")) {
            bool xStatus, yStatus; // Status of MD lookups
            int xBin = psMetadataLookupS32(&xStatus, cell->concepts, "CELL.XBIN");
            int yBin = psMetadataLookupS32(&yStatus, cell->concepts, "CELL.YBIN");
            if (xStatus && yStatus && xBin != 0 && yBin != 0) {
                psList *biassecs = psMetadataLookupPtr(NULL, cell->concepts, "CELL.BIASSEC"); // Bias sections
                psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, true); // Iterator
                psRegion *bias; // Bias region, from iteration
                while ((bias = psListGetAndIncrement(biassecsIter))) {
                    bias->x0 /= xBin;
                    bias->x1 /= xBin;
                    bias->y0 /= yBin;
                    bias->y1 /= yBin;
                }
                psFree(biassecsIter);

                psMetadataRemoveKey(cell->concepts, "CELL.BIASSEC.UPDATE");
            }
        }

    }

    return true;
}
