/*****************************************************************************
    This routine must ensure that the psSpline1DAlloc() function properly
    allocates the spline data structure.  It allocates both linear and cubic
    splines with a variety of min/max ranges.
 *****************************************************************************/
#include <stdio.h>
#include "pslib.h"
#include "psTest.h"
#include "psMemory.h"
#include "psFunctions.h"

#define N 4
#define LINEAR 1
#define CUBIC 3

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

    /****************************************************************************/
    /****************************************************************************/
    testStatus = true;
    printPositiveTestHeader(stdout,
                            "psFunction functions",
                            "psSpline1DAlloc(): linear, normal");

    tmpSpline = psSpline1DAlloc(N, LINEAR, 1.0, 10.0);
    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->domains == NULL) {
        printf("ERROR: Could not allocate psSpline1D->domains data structure\n");
        testStatus = false;
    }

    for (i=0;i<N+1;i++) {
        printf("psSpline1D->domains[%d] is %f\n", i, tmpSpline->domains[i]);
    }

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

    printFooter(stdout,
                "psFunctions functions",
                "psSpline1DAlloc(): linear, normal",
                testStatus);

    /****************************************************************************/
    /****************************************************************************/
    testStatus = true;
    printPositiveTestHeader(stdout,
                            "psFunction functions",
                            "psSpline1DAlloc(): linear, min/max are equal");

    tmpSpline = psSpline1DAlloc(N, LINEAR, 1.0, 1.0);

    if (tmpSpline != NULL) {
        printf("ERROR: allocated psSpline1D data structure when min==max\n");
        testStatus = false;
    }

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

    printFooter(stdout,
                "psFunctions functions",
                "psSpline1DAlloc(): linear, min/max are equal",
                testStatus);

    /****************************************************************************/
    /****************************************************************************/
    testStatus = true;
    printPositiveTestHeader(stdout,
                            "psFunction functions",
                            "psSpline1DAlloc(): linear, min > max.");

    tmpSpline = psSpline1DAlloc(N, LINEAR, 1.0, -1.0);
    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->domains == NULL) {
        printf("ERROR: Could not allocate psSpline1D->domains data structure\n");
        testStatus = false;
    }

    for (i=0;i<N+1;i++) {
        printf("psSpline1D->domains[%d] is %f\n", i, tmpSpline->domains[i]);
    }

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

    printFooter(stdout,
                "psFunctions functions",
                "psSpline1DAlloc(): linear, min > max.",
                testStatus);

    /****************************************************************************/
    /****************************************************************************/
    testStatus = true;
    printPositiveTestHeader(stdout,
                            "psFunction functions",
                            "psSpline1DAlloc(), cubic, normal");

    tmpSpline = psSpline1DAlloc(N, CUBIC, 1.0, 10.0);
    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->domains == NULL) {
        printf("ERROR: Could not allocate psSpline1D->domains data structure\n");
        testStatus = false;
    }

    for (i=0;i<N+1;i++) {
        printf("psSpline1D->domains[%d] is %f\n", i, tmpSpline->domains[i]);
    }

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

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

    /****************************************************************************/
    /****************************************************************************/
    testStatus = true;
    printPositiveTestHeader(stdout,
                            "psFunction functions",
                            "psSpline1DAlloc(): cubic, min/max are equal");

    tmpSpline = psSpline1DAlloc(N, CUBIC, 1.0, 1.0);

    if (tmpSpline != NULL) {
        printf("ERROR: allocated psSpline1D data structure when min==max\n");
        testStatus = false;
    }

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

    printFooter(stdout,
                "psFunctions functions",
                "psSpline1DAlloc(): cubic, min/max are equal",
                testStatus);

    /****************************************************************************/
    /****************************************************************************/
    testStatus = true;
    printPositiveTestHeader(stdout,
                            "psFunction functions",
                            "psSpline1DAlloc(): cubic, min > max.");

    tmpSpline = psSpline1DAlloc(N, CUBIC, 1.0, -1.0);
    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->domains == NULL) {
        printf("ERROR: Could not allocate psSpline1D->domains data structure\n");
        testStatus = false;
    }

    for (i=0;i<N+1;i++) {
        printf("psSpline1D->domains[%d] is %f\n", i, tmpSpline->domains[i]);
    }

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

    printFooter(stdout,
                "psFunctions functions",
                "psSpline1DAlloc(): cubic, min > max.",
                testStatus);

    return (!testStatus);
}
