/*****************************************************************************
    This routine must ensure that the psSpline1DAllocGeneric() function properly
    allocates the spline data structure.
 
    XXX: test bounds?
 *****************************************************************************/
#include <stdio.h>
#include "pslib.h"
#include "psTest.h"
#include "psMemory.h"
#include "psFunctions.h"

#define N 10
#define LINEAR 1
#define CUBIC 3

psS32 main()
{
    psS32 testStatus = true;
    psS32 memLeaks=0;
    psS32 i;
    psS32  currentId = psMemGetId();
    psSpline1D *tmpSpline;
    psVector *bounds;

    /****************************************************************************/
    /****************************************************************************/
    testStatus = true;
    printPositiveTestHeader(stdout,
                            "psFunction functions",
                            "psSpline1DAllocGeneric(): linear");
    bounds = psVectorAlloc(N+1, PS_TYPE_F32);
    for (i=0;i<N+1;i++) {
        bounds->data.F32[i] = (float) (3 * i);
    }

    tmpSpline = psSpline1DAllocGeneric(bounds, LINEAR);
    if (tmpSpline == NULL) {
        printf("ERROR: Could not allocate psSpline1D data structure\n");
        testStatus = false;
    }
    if (tmpSpline->spline == NULL) {
        printf("ERROR: Could not allocate psSpline1D->spline data structure\n");
        testStatus = false;
    }

    if (tmpSpline->n != N) {
        printf("ERROR: spline->n set incorrectly (%d)\n", tmpSpline->n);
        testStatus = false;
    }

    for (i=0;i<N;i++) {
        if (tmpSpline->spline[i] == NULL) {
            printf("ERROR: Could not allocate spline %d\n", i);
            testStatus = false;
        }
        if ((tmpSpline->spline[i])->n != LINEAR+1) {
            printf("ERROR: Spline created with order %d\n", (tmpSpline->spline[i])->n);
            testStatus = false;
        }
    }

    if (tmpSpline->knots == NULL) {
        printf("ERROR: Could not allocate psSpline1D->knots data structure\n");
        testStatus = false;
    }

    for (i=0;i<N+1;i++) {
        if (tmpSpline->knots->data.F32[i] != bounds->data.F32[i]) {
            printf("ERROR: psSpline1D->knots->data.F32[%d] is %f\n", i,
                   tmpSpline->knots->data.F32[i]);
        }
    }

    psFree(tmpSpline);
    psFree(bounds);
    psMemCheckCorruption(1);
    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
    if (0 != memLeaks) {
        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
    }

    printFooter(stdout,
                "psFunctions functions",
                "psSpline1DAllocGeneric(): linear",
                testStatus);
    /****************************************************************************/
    /****************************************************************************/
    testStatus = true;
    printPositiveTestHeader(stdout,
                            "psFunction functions",
                            "psSpline1DAllocGeneric(): cubic");
    bounds = psVectorAlloc(N+1, PS_TYPE_F32);
    for (i=0;i<N+1;i++) {
        bounds->data.F32[i] = (float) (3 * i);
    }

    tmpSpline = psSpline1DAllocGeneric(bounds, CUBIC);
    if (tmpSpline == NULL) {
        printf("ERROR: Could not allocate psSpline1D data structure\n");
        testStatus = false;
    }
    if (tmpSpline->spline == NULL) {
        printf("ERROR: Could not allocate psSpline1D->spline data structure\n");
        testStatus = false;
    }

    if (tmpSpline->n != N) {
        printf("ERROR: spline->n set incorrectly (%d)\n", tmpSpline->n);
        testStatus = false;
    }

    for (i=0;i<N;i++) {
        if (tmpSpline->spline[i] == NULL) {
            printf("ERROR: Could not allocate spline %d\n", i);
            testStatus = false;
        }
        if ((tmpSpline->spline[i])->n != CUBIC+1) {
            printf("ERROR: Spline created with order %d\n", (tmpSpline->spline[i])->n);
            testStatus = false;
        }
    }

    if (tmpSpline->knots == NULL) {
        printf("ERROR: Could not allocate psSpline1D->knots data structure\n");
        testStatus = false;
    }

    for (i=0;i<N+1;i++) {
        if (tmpSpline->knots->data.F32[i] != bounds->data.F32[i]) {
            printf("ERROR: psSpline1D->knots->data.F32[%d] is %f\n", i,
                   tmpSpline->knots->data.F32[i]);
        }
    }

    psFree(tmpSpline);
    psFree(bounds);
    psMemCheckCorruption(1);
    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
    if (0 != memLeaks) {
        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
    }

    printFooter(stdout,
                "psFunctions functions",
                "psSpline1DAllocGeneric(): cubic",
                testStatus);

    return (!testStatus);
}
