(*
/*

CLASS {NATIVE_Random|_Delphi}, NATIVE,
ABSTRACT :

*/
*)
unit NATIVE_Random;

interface 

//{$DEFINE FMX} - do not change / modify this line

uses {$IFDEF KOL} KOL, Windows
	 {$ELSE}
		{$IFDEF LINUX} SysUtils,
		{$ELSE}	
			{$IFDEF FMX} WinApi.Windows, System.SysUtils,
			{$ELSE} Windows, SysUtils,
			{$ENDIF}
		{$ENDIF} 
	 	{$IFDEF FMX} System.Classes {$ELSE} Classes {$ENDIF}
	 {$ENDIF};

type 
{$IFDEF KOL}
	TRandom = Integer;
{$ELSE}
    TRandom = class 
        Seed: LongInt; // In Delphi, LongInt = Integer
    end;
{$ENDIF}
    
var All_random: {$IFDEF KOL}PList{$ELSE}TList{$ENDIF};
function New_random_object: Integer;
procedure Release_random_object(H: Integer);
procedure Random_object_set_seed(H: Integer; Seed: Integer);
function Random_object_next_in_range(H: Integer; Max: Integer): Integer;
function Random_object_probable_value(H: Integer): Double;

implementation

function New_random_object: Integer;
begin
    if All_random = nil then
       All_random := {$IFDEF KOL}NewList{$ELSE}TList.Create{$ENDIF};
    Result := All_random.IndexOf(nil);
    if Result < 0 then 
    begin 
        Result := All_random.Count;
        All_random.Add(nil);
    end;
    {$IFDEF KOL}
    All_random.Items[Result] := Pointer(GetTickCount);
    {$ELSE}
    All_random[Result] := TRandom.Create;
    TRandom(All_random[Result]).Seed := GetTickCount;
    {$ENDIF}
end;
    
procedure Release_random_object(
	H: Integer);
begin
	{$IFDEF KOL}
		// nothing to do - its just Integer
	{$ELSE}
    TObject(All_random.Items[H]).Free;
    All_random.Items[H] := nil;
    while (All_random.Count > 0) and 
          (All_random.Items[All_random.Count-1] = nil) do
          All_random.Delete(All_random.Count-1);
	{$ENDIF}
end;
    
procedure Random_object_set_seed(
	H: Integer; Seed: Integer);
begin    
	{$IFDEF KOL}
    All_random.Items[H] := Pointer(Seed);
    {$ELSE}
    TRandom(All_random.Items[H]).Seed := Seed;
    {$ENDIF}
end;
    
function Random_object_next_in_range(
	H: Integer; Max: Integer): Integer;
var R: TRandom;
begin
    R := TRandom(All_random{$IFDEF KOL}.Items{$ENDIF}[H]);
    if Max < 0 then Max := 0;
    {$IFDEF KOL}
    RandSeed := R;
    Result := System.Random(Max);
    All_random.Items[H] := Pointer(RandSeed);
    {$ELSE}
    RandSeed := R.Seed;
    Result := System.Random(Max);
    R.Seed := RandSeed;
    {$ENDIF}
end;
    
function Random_object_probable_value(
	H: Integer): Double;
var R: TRandom;
begin
    R := TRandom(All_random{$IFDEF KOL}.Items{$ENDIF}[H]);
    {$IFDEF KOL}
    RandSeed := R;
    Result := System.Random;
    All_random.Items[H] := Pointer(RandSeed);
    {$ELSE}
    RandSeed := R.Seed;
    Result := System.Random;
    R.Seed := RandSeed;
	{$ENDIF}
end;

(*
/*

CONST STR:
    NATIVE_Random_import = "uses NATIVE_Random;"

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

end.
