unit MDArray_SRC;

interface
uses
   Measure_SRC;

type
  MDBound = record
    Size : LongInt;
    TotalBefore : LongInt;
  end;

  TMDArray = class
  private
    FSize : integer;
    FBounds : array of MDBound;
    FValues : array of PValueCell;
    function CalcAddress(Addr : array of integer) : integer;
  public
    constructor Create(Bound : array of integer);
    destructor Destroy; override;
    function GetValue(idx: array of integer): PValueCell;
    procedure SetValue(idx: array of integer; const Value: PValueCell);
  end;

implementation

{ TMDArray }

function TMDArray.CalcAddress(Addr: array of integer): integer;
var
   i : integer;
begin
Result := 0;
for i := 0 to High(Addr) do
    begin
    if (Addr[i] < FBounds[i].Size) then
       Result := Word(Result) + FBounds[i].TotalBefore * Word(Addr[i])
    else
       begin
       Result := -1;
       Exit;
       end;
    end;
end;

constructor TMDArray.Create(Bound: array of integer);
var
   i : integer;
   sz : integer;
begin
FSize := 0;
SetLength(FBounds,High(Bound)+1);
sz := 1;
for i := 0 to High(Bound) do
    begin
    FBounds[i].Size := Bound[i];
    FBounds[i].TotalBefore := sz;
    sz := sz * Bound[i];
    end;
SetLength(FValues,sz);

//for i := 0 to sz - 1 do
//    FValues[i] := i;
FSize := sz;
end;

destructor TMDArray.Destroy;
begin
  SetLength(FValues,0);
  SetLength(FBounds,0);
  inherited;
end;

function TMDArray.GetValue(idx: array of integer): PValueCell;
begin
Result := FValues[CalcAddress(idx)];
end;

procedure TMDArray.SetValue(idx: array of integer; const Value: PValueCell);
begin
FValues[CalcAddress(idx)] := Value;
end;

end.
