// (c) 2002-2007 Electronic Arts Inc.

#if defined(_MSC_VER)
#pragma warning(push,1)
#include <windows.h>
#pragma warning(pop)
#endif

#include "realsystem.h"
#include "ranger.h"

#define USEEXPR 0

int CPUisrdts=1;
int main(int argc, char *argv[])
{
    double v;
    RANGER *r;
    EXPR *expr;
    int t0;
    int t1;
    int t2;
    int t3;
    int t4;
    int more;
    int pass;
    int ok;
    int count=0;
    double closearg=15.2;
    double closeround;
    double closefloor;
    double closeceiling;
    double rmin;
    double rmax;
    INT64 rcount;
    int passes=2;
    char *x="10..20+=.1";
    if (argc>1)
        x = argv[1];
    if (argc>2)
        closearg = atof(argv[2]);
    if (argc>3)
        passes = atoi(argv[3]);

    // *************************************************************
    // print range information
    // *************************************************************

#if USEEXPR
    expr = EXPR_open();
    EXPR_set(expr,"apple",65);
    EXPR_set(expr,"zebra",97);
#else
    expr = NULL;
#endif
    r=RANGER_open(expr,x,0.0,100.0);

    ok = RANGER_info(r, &rmin, &rmax, &rcount);
    printf("RANGE_info: min %.2f max %.2f count %" FORMAT64 "d\n", rmin,rmax,rcount);
    if (!ok)
        printf("rangeinfo returned 0.  error in range\n");

    closeround = RANGER_closest(r, closearg, RANGER_ROUND_CLOSEST);
    closefloor = RANGER_closest(r, closearg, RANGER_ROUND_FLOOR);
    closeceiling = RANGER_closest(r, closearg, RANGER_ROUND_CEILING);
    printf("RANGE_close: close to %.2f round %.2f floor %.2f ceiling %.2f\n", closearg,closeround,closefloor,closeceiling);

    count = 0;
    do
    {
        more = RANGER_next(r,&v);
        if (more)
        {
            ++count;
            if (count<20 || count>rcount-10)
                    printf("%.3f\n",v);
                else if (count==20)
                    printf("...\n");
        }
    } while (more);

    RANGER_close(r);
#if USEEXPR
    EXPR_close(expr);
#endif


    // *************************************************************
    // benchmark
    // *************************************************************


#if defined(_MSC_VER)
    SetThreadPriority(0, THREAD_PRIORITY_ABOVE_NORMAL);
//    _disable();
#endif


    for (pass=0; pass<passes; ++pass)
    {
#if USEEXPR
        expr = EXPR_open();
        EXPR_set(expr,"apple",65);
        EXPR_set(expr,"zebra",97);
#else
        expr = NULL;
#endif
        t0 = CPU_getcycle();
        r=RANGER_open(expr,x,0.0,100.0);
        t0 = CPU_getcycle()-t0;

        t3 = CPU_getcycle();
        ok = RANGER_info(r, &rmin, &rmax, &rcount);
        t3 = CPU_getcycle()-t3;

        t4 = CPU_getcycle();
        closeround = RANGER_closest(r, closearg, RANGER_ROUND_CLOSEST);
        closefloor = RANGER_closest(r, closearg, RANGER_ROUND_FLOOR);
        closeceiling = RANGER_closest(r, closearg, RANGER_ROUND_CEILING);
        t4 = CPU_getcycle()-t4;

        count = 0;
        t1 = CPU_getcycle();
        do
        {
            more = RANGER_next(r,&v);
        } while (more);
        t1 = CPU_getcycle()-t1;

        t2 = CPU_getcycle();
        RANGER_close(r);
        t2 = CPU_getcycle()-t2;
#if USEEXPR
        EXPR_close(expr);
#endif
        if (pass==1)
            printf("time open %d close %d, info %d, closest %d, next %.2f\n",t0,t2,t3,t4/3,(float)t1/rcount);
    }

}

