#include <amscppnarray/amscppnarray.hpp>

namespace ams
{
namespace narray
{

template<> void narray<float>::print(const int printstyle)
{
    narray_size_t I;

    printf("{");
    for(I=0;I<this->length-1;I++)
    {
        printf("%1.3f,",this->data[I]);
    }
    if(this->length>=1) printf("%1.3f",this->data[this->length-1]);
    printf("}");

    return;
}

template<> void narray<double>::print(const int printstyle)
{
    narray_size_t I;

    printf("{");
    for(I=0;I<this->length-1;I++)
    {
        printf("%1.3f,",this->data[I]);
    }
    if(this->length>=1) printf("%1.3f",this->data[this->length-1]);
    printf("}");

    return;
}

template<> void narray<int>::print(const int printstyle)
{
    narray_size_t I;

    printf("{");
    for(I=0;I<this->length-1;I++)
    {
        printf("%d,",this->data[I]);
    }
    if(this->length>=1) printf("%d",this->data[this->length-1]);
    printf("}");

    return;
}

template<> void narray<long>::print(const int printstyle)
{
    narray_size_t I;

    printf("{");
    for(I=0;I<this->length-1;I++)
    {
        printf("%ld,",this->data[I]);
    }
    if(this->length>=1) printf("%ld",this->data[this->length-1]);
    printf("}");

    return;
}

void test_narray1()
{
    int I;
    narray<float> a;
    narray<float> *b = NULL;
    narray<float> tmp;

    b = new(std::nothrow) narray<float>();
    a.resize(100);
    b->resize(100000);
    a.setall(2.5f);
    b->setall(3.0f);

    for(I=0;I<100000;I++)
    {
        if(b->at(I)!=3.0f)
        {
            printf("Error: b[%d]=%1.3f, not %1.3f\n",I,b->at(I),3.0f);
            break;
        }
    }

    a.resize(100000);

    tmp = a;
    a = *b;
    *b = tmp;

    *b = tmp+a;
    for(I=0;I<b->length;I++)
    {
        if(b->at(I) != tmp[I] + a[I])
        {
            printf("addition error in index %d",I);
        }
    }

    printf("threaded boolean test: %d\n", (*b==(a+tmp)));



    delete b;

    return;
}

void test_narray2()
{
    int I;
    narray<float> a,b,c,d;

    a.resize(100000); a.setall(1.0f);
    b.resize(100000); for(I=0;I<b.length;I++) b[I] = 0.5f*I;
    c.resize(100000); c.setall(2.0f);

    d = -a*(b+c);
    for(I=0;I<5;I++)
    {
        printf("d[%d]=%1.3f\n",I,d[I]);

    }

    printf("d==-a*(b+c):%d\n",d==(-a*(b+c)));
    d[50000] = 0.0f;
    printf("d==-a*(b+c):%d\n",d==(-a*(b+c)));
    
}


void test_narray3()
{
    int I;
    narray<float> a,b,c,d;

    a.resize(5); a.setall(1.0f);
    b = {0,0.25,0.5,0.675,0.8675};
    c.resize(5); c.setall(2.0f);

    d = -a*(b+c*2+2);
    for(I=0;I<5;I++)
    {
        printf("d[%d]=%1.3f\n",I,d[I]);

    }

    printf("d==-a*(b+c*2+2):%d\n",d==(-a*(b+c*2+2)));
    d[4] = 0.0f;
    printf("d==-a*(b+c*2+2):%d\n",d==(-a*(b+c*2+2)));
    d = d.applyfn(::sinf);

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

    }

    d = d.subarray(0,1);
    for(I=0;I<d.length;I++)
    {
        printf("d[%d]=%1.3f\n",I,d[I]);

    }
}

void test_insertdelete1()
{
    narray<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 = rand::dpr32_randint(5,25);
        K = q.find_insert_ordered(J);
        q.insert(K,J);
        q.print(); printf("\n");
    }

    return;
}

}; //end namespace narray
}; //end namespace ams