/*****************************************************************************
    This routine must ensure that PS_STAT_MAX is correctly computed
    by the procedure psVectorStats().
 *****************************************************************************/
#include <stdio.h>
#include "pslib.h"
#include "psTest.h"
#define N 10

int main()
{
    psStats *myStats    = NULL;
    int testStatus      = true;
    int globalTestStatus = true;
    int i               = 0;
    psVector *myVector  = NULL;
    psVector *maskVector= NULL;
    float max           = 0.0;
    float realMaxNoMask   = 0.0;
    float realMaxWithMask = 0.0;
    int currentId       = psMemGetId();
    int memLeaks        = 0;

    /*************************************************************************/
    /*  Allocate and initialize data structures                      */
    /*************************************************************************/
    myStats = psStatsAlloc(PS_STAT_MAX);
    myVector = psVectorAlloc(N, PS_TYPE_F32);
    myVector->n = N;
    maskVector = psVectorAlloc(N, PS_TYPE_U8);
    maskVector->n = N;

    // Set the appropriate values for the vector data.
    for (i=0;i<N;i++) {
        myVector->data.F32[i] = (float) i;
    }

    // Set the mask vector and calculate the expected maximum.
    for (i=0;i<N;i++) {
        if (myVector->data.F32[i] > realMaxNoMask) {
            realMaxNoMask = myVector->data.F32[i];
        }

        if (i < (N/2)) {
            maskVector->data.U8[i] = 0;

            if (myVector->data.F32[i] > realMaxWithMask) {
                realMaxWithMask = myVector->data.F32[i];
            }
        } else {
            maskVector->data.U8[i] = 1;
            printf("Masking element %d\n", i);
        }
    }

    /*************************************************************************/
    /*  Call psVectorStats() with no vector mask.                    */
    /*************************************************************************/
    printPositiveTestHeader(stdout,
                            "psStats functions",
                            "PS_STAT_MAX: no vector mask");

    myStats = psVectorStats(myStats, myVector, NULL, 0);
    max = myStats->max;

    printf("Called psVectorStats() on a vector with no elements masked.\n");
    printf("The expected max was %f; the calculated max was %f\n", realMaxNoMask, max);
    if (max == realMaxNoMask) {
        testStatus = true;
    } else {
        testStatus = false;
        globalTestStatus = false;
    }
    printFooter(stdout,
                "psVector functions",
                "PS_STAT_MAX: no vector mask",
                testStatus);

    /*************************************************************************/
    /*  Call psVectorStats() with vector mask.                       */
    /*************************************************************************/
    printPositiveTestHeader(stdout,
                            "psStats functions",
                            "PS_STAT_MAX: with vector mask");

    myStats = psVectorStats(myStats, myVector, maskVector, 1);
    max = myStats->max;
    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
    printf("The expected max was %f; the calculated max was %f\n", realMaxWithMask, max);
    if (max == realMaxWithMask) {
        testStatus = true;
    } else {
        testStatus = false;
        globalTestStatus = false;
    }

    printFooter(stdout,
                "psVector functions",
                "PS_STAT_MAX: with vector mask",
                testStatus);

    /*************************************************************************/
    /*  Deallocate data structures                                   */
    /*************************************************************************/
    printPositiveTestHeader(stdout,
                            "psStats functions",
                            "psStats(): deallocating memory");

    psFree(myStats);
    psFree(myVector);
    psFree(maskVector);

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

    printFooter(stdout,
                "psVector functions",
                "psStats(): deallocating memory",
                testStatus);

    return (!globalTestStatus);
}
