unit rkCommon;

interface

uses
	Classes;

type
  // Base class for Lists that owns its objects.
  TOwnerList = class
  private
    FList: TList;
    function GetItem(Index: Integer): TObject;
    procedure SetItem(Index: Integer; Item: TObject);
    function GetCount: Integer;
  protected
    property Items[Index: Integer]: TObject read GetItem write SetItem; default;
    property List : TList read FList write FList;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    function Add(Item: TObject): Integer; virtual;
    procedure Clear; virtual;
    procedure Delete(Index: Integer); virtual;
    function IndexOf(Item: TObject): Integer; virtual;
    function Remove(Item: TObject): Integer;
    property Count: Integer read GetCount;
  end;

function strToken(var S: String; Seperator: Char): String;

implementation

{ TOwnerlist ------------------------------------------------------------------}

{ This class is similar to TList, except it owns the items in the
  list. Deleting an item deletes the object. Clearing the list deletes
  all the objects. }
constructor TOwnerList.Create;
begin
  inherited Create;
  FList := TList.Create;
end;

{------------------------------------------------------------------------------}

destructor TOwnerList.Destroy;
begin
  if FList <> nil then
    Clear;
  FList.Free;
  inherited Destroy;
end;

{------------------------------------------------------------------------------}

function TOwnerList.GetItem(Index: Integer): TObject;
begin
  Result := FList[Index]
end;

{------------------------------------------------------------------------------}

procedure TOwnerList.SetItem(Index: Integer; Item: TObject);
var
  OldItem: TObject;
begin
  OldItem := FList[Index];
  if OldItem <> Item then
  begin
    FList[Index] := nil;
    OldItem.Free;
  end;
  FList[Index] := Item;
end;

{------------------------------------------------------------------------------}

function TOwnerList.GetCount: Integer;
begin
  Result := FList.Count
end;

{------------------------------------------------------------------------------}

function TOwnerList.Add(Item: TObject): Integer;
begin
  Result := FList.Add(Item)
end;

{ Delete items starting at the end of the list because that is
  much faster than starting at the beginning of the list. }
{------------------------------------------------------------------------------}

procedure TOwnerList.Clear;
var
  I: Integer;
begin
  for I := FList.Count-1 downto 0 do
    Delete(I);
end;

{------------------------------------------------------------------------------}

procedure TOwnerList.Delete(Index: Integer);
var
  Item: TObject;
begin
  Item := FList[Index];
  FList.Delete(Index);
  Item.Free;
end;

{------------------------------------------------------------------------------}

function TOwnerList.IndexOf(Item: TObject): Integer;
begin
  Result := FList.IndexOf(Item);
end;

{------------------------------------------------------------------------------}

function TOwnerList.Remove(Item: TObject): Integer;
begin
  Result := IndexOf(Item);
  if Result >= 0 then
    Delete(Result);
end;

{------------------------------------------------------------------------------}

function strToken(var S: String; Seperator: Char): String;
var
  I               : Word;
begin
  I:=Pos(Seperator,S);
  if I<>0 then
  begin
    Result:=System.Copy(S,1,I-1);
    System.Delete(S,1,I);
  end else
  begin
    Result:=S;
    S:='';
  end;
end;

{------------------------------------------------------------------------------}

end.
