#include <stdio.h>
#include <math.h>
#include "psMemory.h"
#include "psError.h"
#include "psErrorText.h"
#include "psRegion.h"

psRegion *psRegionAlloc(float x0,
                        float x1,
                        float y0,
                        float y1)
{
    psRegion *region = psAlloc(sizeof(psRegion)); // New region, to be returned
    // No complex structures, so no special deallocator
    *region = psRegionSet(x0, x1, y0, y1);
    return region;
}

psRegion psRegionSet(float x0,
                     float x1,
                     float y0,
                     float y1)
{
    psRegion out;

    out.x0 = x0;
    out.y0 = y0;
    out.x1 = x1;
    out.y1 = y1;

    return out;
}

psRegion psRegionFromString(const char* region)
{
    psS32 col0;
    psS32 col1;
    psS32 row0;
    psS32 row1;

    // section should be of the form '[col0:col1,row0:row1]'
    if (region == NULL) {
        return psRegionSet(0,0,0,0);
    }

    if (sscanf(region,"[%d:%d,%d:%d]",&col0,&col1,&row0,&row1) < 4) {
        psError(PS_ERR_BAD_PARAMETER_NULL, true,
                PS_ERRORTEXT_psImage_SUBSECTION_INVALID,
                region);
        return psRegionSet(NAN,NAN,NAN,NAN);
    }

    if (col0 > col1 || row0 > row1) {
        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                PS_ERRORTEXT_psImage_SUBSET_RANGE_MALFORMED,
                col0,col1,row0,row1);
        return psRegionSet(NAN,NAN,NAN,NAN);
    }

    return psRegionSet(col0-1,col1,row0-1,row1);
}

psString psRegionToString(const psRegion region)
{
    char tmpText[256]; // big enough to store any region as text

    snprintf(tmpText,256,"[%g:%g,%g:%g]",
             region.x0+1, region.x1,
             region.y0+1, region.y1);

    return psStringCopy(tmpText);
}


// define a square region centered on the given coordinate
psRegion psRegionForSquare(double x,
                           double y,
                           double radius)
{
    psRegion region;
    region = psRegionSet (x - radius, x + radius + 1,
                          y - radius, y + radius + 1);
    return (region);
}

