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

#include <stdio.h>
#include <assert.h>
#include "pslib.h"
#include "stac.h"

bool stacWriteMap(const char *mapName,  // Filename to write to
                  psPlaneTransform *map // Map to write
    )
{
    assert(mapName);

    FILE *mapFile = fopen(mapName, "w");
    if (!mapFile) {
        fprintf(stderr, "Unable to open map file: %s\n", mapName);
        return false;
    }

    psPolynomial2D *xMap = map->x;      // x transform
    psPolynomial2D *yMap = map->y;      // y transform

    // A crucial limitation of the current system --- the order of each polynomial must be the same
    assert(xMap->nX == xMap->nY && yMap->nX == yMap->nY && xMap->nX == yMap->nX);
    int order = xMap->nX;       // The polynomial order
    fprintf(mapFile, "%d\n", order);

    // x coefficients
    for (int k = 0; k <= order; k++) {
        for (int j = 0; j <= k; j++) {
            int i = k - j;
            if (xMap->mask[i][j]) {
                fprintf(mapFile, "0.0 ");
            } else {
                fprintf(mapFile, "%g ", xMap->coeff[i][j]);
            }
        }
    }
    fprintf(mapFile, "\n");

    // y coefficients
    for (int k = 0; k <= order; k++) {
        for (int j = 0; j <= k; j++) {
            int i = k - j;
            if (yMap->mask[i][j]) {
                fprintf(mapFile, "0.0 ");
            } else {
                fprintf(mapFile, "%g ", yMap->coeff[i][j]);
            }
        }
    }
    fprintf(mapFile, "\n");

    fclose(mapFile);

    return true;
}


bool stacWriteMaps(const psArray *names, // Filenames of the input images (will add ".map")
                   const psArray *maps  // Maps to write
    )
{
    assert(names);
    assert(maps);
    assert(names->n == maps->n);

    for (int i = 0; i < names->n; i++) {
        char mapName[MAXCHAR];          // Filename of error image
        sprintf(mapName, "%s.map", (const char*)names->data[i]);
        if (!stacWriteMap(mapName, maps->data[i])) {
            return false;
        }
    }

    return true;
}


