unit VertList;

interface

uses U3D, MiscRoutines;

type
  vector2_p=^vector2_t;
  vector2_t=record
    x,y : u3dval;
  end;
  vector2_array_t = array[0..MAXVERTEX-1] of vector2_t;
  vector2_array_p = ^vector2_array_t;

// =======================================================================

type
  TVertices             = object
  private
    TempStorage         : pointer;
    Storage             : pointer;
    Next                : integer;
    Capacity            : integer;
  public
    constructor         Create;
    destructor          Destroy; virtual;
    procedure           Clear;
    function            Count : integer;
  end;

// =======================================================================

type
  PPlainVertices        = ^TPlainVertices;
  TPlainVertices        = object(TVertices)
  private
    function            Get(Index:integer):vector2_t;
    function            GetP(Index:integer):vector2_p;
  public
    procedure           Add(x,y:u3dval);
    property            Items[Index:integer]:vector2_t read Get;
    property            Pointers[Index:integer]:vector2_p read GetP;
    procedure           Sort;
  end;

type
  PSurfaceVertices      = ^TSurfaceVertices;
  TSurfaceVertices      = object(TVertices)
  private
    function            Get(Index:integer):vector_t;
    function            GetP(Index:integer):vector_p;
  public
    procedure           Add(x,y,z:u3dval);
    property            Items[Index:integer]:vector_t read Get;
    property            Pointers[Index:integer]:vector_p read GetP;
  end;

// =======================================================================

implementation

const
  DefaultIncrement = 256;


constructor TVertices.Create;
begin
  Storage:=nil;
  Next:=0;
  Capacity:=0;
end;

procedure TVertices.Clear;
begin
  if(Storage<>nil) then
  begin
    FreeMem(Storage);
    Storage:=nil;
  end;
  Next:=0;
  Capacity:=0;
end;

destructor TVertices.Destroy;
begin
  Clear;
end;

function TVertices.Count:integer;
begin
  Result:=Next;
end;

procedure TPlainVertices.Add;
begin
  if(Next>=Capacity) then
  begin
    GetMem(TempStorage,(Capacity+DefaultIncrement)*sizeof(vector2_t));
    memCopyMemory(TempStorage,Storage,Capacity*sizeof(vector2_t));
    FreeMem(Storage);
    Storage:=TempStorage;
    Capacity:=Capacity+DefaultIncrement;
  end;
  vector2_array_p(Storage)^[Next].x:=x;
  vector2_array_p(Storage)^[Next].y:=y;
  Next:=Next+1;
end;

function TPlainVertices.Get;
begin
  Result:=vector2_array_p(Storage)^[Index];
end;

function TPlainVertices.GetP;
begin
  Result:=@(vector2_array_p(Storage)^[Index]);
end;

function FindMin(var Arr:vector2_array_t;Start,Last:integer):integer;
var
  i : integer;
begin
  Result:=Start;
  for i:=Start+1 to Last do
    if Arr[i].x<Arr[Result].x then
      Result:=i;
end;

procedure Swap(var Arr:vector2_array_t;One,Two : integer);
var
  t : u3dval;
begin
  t:=Arr[One].x;
  Arr[One].x:=Arr[Two].x;
  Arr[Two].x:=t;
  t:=Arr[One].y;
  Arr[One].y:=Arr[Two].y;
  Arr[Two].y:=t;
end;

procedure TPlainVertices.Sort;
var
  i : integer;
  p_arr : vector2_array_p;
begin
  p_arr:=vector2_array_p(Storage);
  for i:=0 to Count-2 do
    Swap(p_arr^,i,FindMin(p_arr^,i,Count-1));
end;

procedure TSurfaceVertices.Add;
begin
  if(Next>=Capacity) then
  begin
    GetMem(TempStorage,(Capacity+DefaultIncrement)*sizeof(vector_t));
    memCopyMemory(TempStorage,Storage,Capacity*sizeof(vector_t));
    FreeMem(Storage);
    Storage:=TempStorage;
    Capacity:=Capacity+DefaultIncrement;
  end;
  vector_array_p(Storage)^[Next].x:=x;
  vector_array_p(Storage)^[Next].y:=y;
  vector_array_p(Storage)^[Next].z:=z;
  Next:=Next+1;
end;

function TSurfaceVertices.Get;
begin
  Result:=vector_array_p(Storage)^[Index];
end;

function TSurfaceVertices.GetP;
begin
  Result:=@(vector_array_p(Storage)^[Index]);
end;

end.

