#include <amsmathutil25/amsmathutil25.hpp>

namespace ams
{
namespace amsmathutil25
{

void test_amsarray1()
{
    amsarray<float> a,b,c,q;
    int64_t I;

    printf("Tests for amsarray...\n");
    q.resize(10);
    q[0] = 1;
    q[9] = 5;
    for(I=0;I<10;I++)
    {
        printf("q[%ld] = %1.3f\n",I,q[I]);
    }

    q.resize(12);
    a = q;
    a = b = q;
    for(I=0;I<12;I++)
    {
        printf("a[%ld] = %1.3f\n",I,a[I]);
    }

    q.resize(8);
    a = q;
    a = b = q;
    for(I=0;I<8;I++)
    {
        printf("a[%ld] = %1.3f\n",I,a[I]);
    }
    
    a.resize(amsmathutil25_threadpsz + 10);
    a.setall(55);
    printf("a.length=%ld\n",a.length);

    b = a;
    for(I=amsmathutil25_threadpsz;I<b.length;I++)
    {
        printf("b[%ld] = %1.3f\n",I,b[I]);
    }

    return;
}

void test_amsarray2()
{
    amsarray<int64_t> a,b,c;
    amsarray<float> q;
    int64_t I;

    printf("Tests for amsarray...\n");

    a.resize(0);
    b = a;
    a.resize(-10);
    b = a;

    printf("a==b?%d\n",a==b);

    a.resize(10);
    b = a;

    printf("a==b?%d\n",a==b);

    a.resize(10000);
    b = a;

    printf("a==b?%d\n",a==b);

    a.setall(55);
    b = a;

    printf("a==b?%d\n",a==b);

    a[0] = 1;

    printf("a==b?%d\n",a==b);

    q = (amsarray<float>)a;
    for(I=q.length-10;I<q.length;I++)
    {
        printf("q[%ld]=%1.3f\n",I,q[I]);
    }
}

void test_amsarray_select()
{
    int I;
    amsarray<double> a;
    amsarray<amsarray_size_t> b;
    amsarray<double> c;

    a = ams::rand::amsarray_rand(100);

    for(I=0;I<10;I++)
    {
        printf("a[%d]=%1.3f\n",I,a[I]);
    }

    b = amsarray<amsarray_size_t>({1,3,5,7});

    c = a.select(b);

    for(I=0;I<b.length;I++)
    {
        printf("b[%d] = %d: a[%d]=%1.3f, c[%d] = %1.3f\n",I,(int)b[I],(int)b[I],a[b[I]],I,c[I]);
    }

    a = ams::rand::amsarray_rand(30000);
    b = (amsarray<amsarray_size_t>)ams::rand::amsarray_randintl(10000,0,a.length);
    c = a.select(b);

    for(I=b.length/2;I<b.length/2+10;I++)
    {
        printf("b[%d] = %d: a[%d]=%1.3f, c[%d] = %1.3f\n",I,(int)b[I],(int)b[I],a[b[I]],I,c[I]);
    }

    for(I=b.length-10;I<b.length;I++)
    {
        printf("b[%d] = %d: a[%d]=%1.3f, c[%d] = %1.3f\n",I,(int)b[I],(int)b[I],a[b[I]],I,c[I]);
    }



    return;
}

void test_amsarray_sort1()
{
    int I;
    amsarray<double> a,b;
    amsarray<amsarray_size_t> q;
    int K;
    //int J;
    amsarray_size_t bs;
    double t0,t1;

    ams::rand::seed_init_timer();


    for(K=0;K<10;K++)
    {
        a = ams::rand::amsarray_rand(10000);
        //_debug_amsarray_print(&a,1);
        a.sort();
        //_debug_amsarray_print(&a,1);

        bool ordertest = 1;
        for(I=0;I<a.length-1;I++)
        {
            if(a[I]>a[I+1])
            {
                ordertest = 0;
                break;
            }
        }
        if(ordertest==1)
            printf("ordering test: passed.\n");
        else
            printf("ordering test: failed.\n");
    }

    bs = 100;
    for(K=0;K<10;K++)
    {
        b = ams::rand::amsarray_rand(bs);
        t0 = time_msec();
        b.sort();
        t1 = time_msec();
        printf("sorted %ld in %1.3f msec.\n",bs,t1-t0);
        bs*=2;
    };
    //a.print();
    
    // q = permutation_identity(10000);


    for(I=0;I<a.length && I<10;I++)
    {
        printf("a[%d]=%1.5f\n",I,a[I]);
    }


}

void test_amsarray_insertdelete1()
{
    amsarray<int> q;
    int I,J,K;

    q.insert(0,1);
    q.print(); printf("\n");
    q.insert(0,2);
    q.print(); printf("\n");
    q.insert(0,3);
    q.print(); printf("\n");
    q.insert(-1,1);
    q.print(); printf("\n");
    q.insert(10,99);
    q.print(); printf("\n");

    I = 3;
    printf("q.find(%d)=%d\n",I,(int)q.find(I));
    I = 1;
    printf("q.find(%d)=%d\n",I,(int)q.find(I));
    I = 5;
    printf("q.find(%d)=%d\n",I,(int)q.find(I));
    I = 99;
    printf("q.find(%d)=%d\n",I,(int)q.find(I));

    I = 1;
    printf("q.findinsert(%d)=%d\n",I,(int)q.find_insert_ordered(I));
    I = -1;
    printf("q.findinsert(%d)=%d\n",I,(int)q.find_insert_ordered(I));
    I = 5;
    printf("q.findinsert(%d)=%d\n",I,(int)q.find_insert_ordered(I));
    I = 99;
    printf("q.findinsert(%d)=%d\n",I,(int)q.find_insert_ordered(I));
    I = 100;
    printf("q.findinsert(%d)=%d\n",I,(int)q.find_insert_ordered(I));

    q.erase(0);
    q.print(); printf("\n");
    q.erase(-1);
    q.print(); printf("\n");
    q.erase(q.length);
    q.print(); printf("\n");
    q.erase(q.length-1);
    q.print(); printf("\n");

    q.resize(0);
    for(I=0;I<25;I++)
    {
        J = ams::rand::randint(5,25);
        K = q.find_insert_ordered(J);
        q.insert(K,J);
        q.print(); printf("\n");
    }

    return;
}




}; //end namespace amsmathutil25
}; //end namespace ams