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

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

#include "ppSim.h"

pmFPAfile *ppSimCreate(pmConfig *config)
{
    PS_ASSERT_PTR_NON_NULL(config, NULL);

    pmFPA *fpa = pmFPAConstruct(config->camera); // FPA to contain the observation
    if (!fpa) {
        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to construct an FPA from camera configuration.");
        return NULL;
    }

    pmFPAfile *file = pmFPAfileDefineOutput(config, fpa, OUTPUT_FILE);
    psFree(fpa);
    if (!file) {
        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to create output file from %s.  "
                "Did you forget to specify the format?", OUTPUT_FILE);
        return NULL;
    }
    if (file->type != PM_FPA_FILE_IMAGE) {
        psError(PS_ERR_BAD_PARAMETER_TYPE, true, "%s type is not IMAGE", OUTPUT_FILE);
        psFree(file);
        return NULL;
    }
    file->save = true;

    pmFPALevel phuLevel = pmFPAPHULevel(file->format); // Level at which PHU goes

    pmFPAview *view = pmFPAviewAlloc(0);// View for current level

    if (phuLevel == PM_FPA_LEVEL_FPA) {
        if (!pmFPAAddSourceFromView(fpa, "Simulation", view, file->format)) {
            psError(PS_ERR_UNKNOWN, false, "Unable to add PHU to FPA.");
            psFree(fpa);
            psFree(view);
            return NULL;
        }
    }

    pmChip *chip;                       // Chip from FPA
    while ((chip = pmFPAviewNextChip(view, fpa, 1))) {
        if (phuLevel == PM_FPA_LEVEL_CHIP) {
            if (!pmFPAAddSourceFromView(fpa, "Simulation", view, file->format)) {
                psError(PS_ERR_UNKNOWN, false, "Unable to add PHU to FPA.");
                psFree(fpa);
                psFree(view);
                return NULL;
            }
        }

        pmCell *cell;                   // Cell from chip
        while ((cell = pmFPAviewNextCell(view, fpa, 1))) {
            if (phuLevel == PM_FPA_LEVEL_CELL) {
                if (!pmFPAAddSourceFromView(fpa, "Simulation", view, file->format)) {
                    psError(PS_ERR_UNKNOWN, false, "Unable to add PHU to FPA.");
                    psFree(fpa);
                    psFree(view);
                    return NULL;
                }
            }
        }
    }
    psFree(view);

    return file;
}
