/*

CLASS {NATIVE_Random|_Cpp}, NATIVE:

*/

#ifdef SEPARATE_UNITS
    #include "NATIVE_Random.h"
#endif

#ifndef MSWINDOWS
    #include <sys/times.h>
#endif

AL4_random::AL4_random()
{
    #ifdef MSWINDOWS
    RandSeed = GetTickCount();
    #else
        tms tm;
        clock_t time = times(&tm);
        long res = sysconf(_SC_CLK_TCK);
        double f = (float)time/(float)res;
        RandSeed = (long int)f;
    #endif
}

unsigned int AL4_random::RandInt()
{
    RandSeed = RandSeed * 0x8088405 + 1;
    return (unsigned int)(RandSeed & 0xFFFFFFFF);
}

double AL4_random::RandDouble()
{
    return ((double)RandInt()) / (unsigned int)(0xFFFFFFFF);
}

std::vector<AL4_random*> AL4_random::All_random;
    
int AL4_random::New_random_object()
{
    int h = -1;
    for (int i = All_random.size()-1; i >= 0; i--)
        if (All_random[i] == nullptr)
        {
            h = i;
            break;
        }
    if (h < 0)
    {
        h = All_random.size();
        All_random.push_back(nullptr);
    }
    All_random[h] = new AL4_random();
    return h;
}

void AL4_random::Release_random_object(int H)
{
    AL4_random* r = All_random[H];
    All_random[H] = nullptr;
    delete r;
    while (All_random.size() > 0 && All_random[All_random.size()-1] == nullptr)
    {
		int  i = (int)(All_random.size()-1);
        All_random.erase(All_random.begin() + i);
    }
}

void AL4_random::Random_object_set_seed(int H, int Seed)
{
    AL4_random* r = All_random[H];
    All_random[H] = new AL4_random();
    All_random[H]->RandSeed = Seed;
    delete r;
}

int AL4_random::Random_object_next_in_range(int H, int Max)
{
    AL4_random* R = All_random[H];
    if (Max < 0) Max = 0;
    if (Max == 0) return R->RandInt();
    return R->RandInt() % Max;
}

double AL4_random::Random_object_probable_value(int H)
{
    AL4_random* R = All_random[H];
    return R->RandDouble();
}
/*
    
CONST STR:
    NATIVE_Random_import = @
    "#ifdef SEPARATE_UNITS"
    "       #include " #QU "NATIVE_Random.h" #QU
    "#endif"

    NATIVE_new_random_object = @
    "    RESULT = AL4_random::New_random_object();" 
                
    NATIVE_release_random_object = @
    "   AL4_random::Release_random_object(X_Handle);" 
    
    NATIVE_Set_seed = @
    "    AL4_random::Random_object_set_seed(X_Handle, X_Seed);" 
        
    NATIVE_Next = @
    "    RESULT = AL4_random::Random_object_next_in_range("
    "       X_Handle, X_Max);"
        
    NATIVE_Probable = @
    "    RESULT = AL4_random::Random_object_probable_value(X_Handle);"
    
    .
        
    
END
*/
