#include <cstdlib>
#include "random.h"

#define RAND_SIZE 0xFFFF

namespace render{
namespace fx{

float urandom() noexcept
{
    return float(rand())/RAND_MAX;
}

float random() noexcept
{
    return urandom()*2.0f-1.0f;
}

vec3f random3() noexcept
{
    return vec3f(random(), random(), random());
}

vec2f random2() noexcept
{
    return vec2f(random(), random());
}

rnd::rnd()
{
    _cur = _cr = _cr2 = _cr3 = 0;
    _ur = new float[RAND_SIZE];
    for(uint32_t i = 0; i < RAND_SIZE; i++)
        _ur[i] = urandom();

    _r = new float[RAND_SIZE];
    for(uint32_t i = 0; i < RAND_SIZE; i++)
        _r[i] = random();

    _r2 = new vec2f[RAND_SIZE];
    for(uint32_t i = 0; i < RAND_SIZE; i++)
        _r2[i] = random2();

    _r3 = new vec3f[RAND_SIZE];
    for(uint32_t i = 0; i < RAND_SIZE; i++)
        _r3[i] = random3();
}

rnd::~rnd()
{
    delete _ur;
    delete _r;
    delete _r2;
    delete _r3;
}

float rnd::urand() noexcept
{
    if(_cur == RAND_SIZE)_cur = 0;
    return _ur[_cur++];
}

float rnd::rand() noexcept
{
    if(_cr == RAND_SIZE)_cr = 0;
    return _r[_cr++];
}

const vec2f &rnd::rand2() noexcept
{
    if(_cr2 == RAND_SIZE)_cr2 = 0;
    return _r2[_cr2++];
}

const vec3f &rnd::rand3() noexcept
{
    if(_cr3 == RAND_SIZE)_cr3 = 0;
    return _r3[_cr3++];
}

}}
