//DJXEngine v1.0
unit DJXEngine;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DJXTextures, DJXTimer, DJX;


type
  TDJXEngine = class;
  TDJXEngineItem = class;

  TDJXEngine = class(TObject)
  private
    m_List: TList;
  protected
    function GetItem(Index: integer): TDJXEngineItem;
    procedure SetItem(Index: integer; Value: TDJXEngineItem);
    function GetCount: integer;
  public
    constructor Create; virtual; 
    destructor Destroy; override;
    property Items[Index: integer]: TDJXEngineItem read GetItem write SetItem;
    property Count: integer read GetCount;
    procedure Draw;
    procedure Process(SpeedFactor: single = 1);
    procedure Add(Item: TDJXEngineItem);
    procedure Insert(Index: integer; Item: TDJXEngineItem);
    procedure Remove(Item: TDJXEngineItem);
    procedure Delete(Index: integer);
    procedure FreeItems;
  end;

  TDJXEngineItem = class(TObject)
  private
    m_X: double;
    m_Y: double;
    m_Z: double;
    m_Engine: TDJXEngine;
    m_Dead: boolean;
    m_Sort: integer;
  protected
    procedure SetSort(Value: integer);
  public
    constructor Create(Engine: TDJXEngine); virtual;
    destructor Destroy; override;
    property X: double read m_X write m_X;
    property Y: double read m_Y write m_Y;
    property Z: double read m_Z write m_Z;
    property Sort: integer read m_Sort write SetSort;
    procedure Process(SpeedFactor: single); virtual;
    procedure Draw; virtual;
    procedure Dead;
  end;

implementation

//DJXEngineItem BEGIN
constructor TDJXEngineItem.Create(Engine: TDJXEngine);
begin
  inherited Create;
  m_Engine := Engine;
  if m_Engine <> nil then m_Engine.Add(self);
  m_X := 0;
  m_Y := 0;
  m_Z := 0;
  m_Dead := false;
  Sort := 0;
end;
destructor TDJXEngineItem.Destroy;
begin
  inherited Destroy;
end;
procedure TDJXEngineItem.SetSort(Value: integer);
var
  l, h, dif, m: integer;
begin
  if m_Engine=nil then exit;
  m_Engine.Remove(self);
  m_Sort := Value;
  l := 0;
  h := m_Engine.Count - 1;
  while l <= h do
  begin
    m := (l + h) div 2;
    dif := TDJXEngineItem(m_Engine.m_List.Items[m]).m_Sort - m_Sort;
    if dif < 0 then l := m + 1
    else h := m - 1;
  end;
  m_Engine.Insert(l, self);
end;
procedure TDJXEngineItem.Dead;
begin
  m_Dead := true;
end;
procedure TDJXEngineItem.Process(SpeedFactor: single);
begin

end;
procedure TDJXEngineItem.Draw;
begin

end;
//DJXEngineItem END

//DJXEngine BEGIN
constructor TDJXEngine.Create;
begin
  inherited Create;
  m_List := TList.Create;
end;
destructor TDJXEngine.Destroy;
begin
  m_List.Free;
  inherited Destroy;
end;
procedure TDJXEngine.FreeItems;
var
  Item: TDJXEngineItem;
begin
  while Count>0 do
  begin
    Item := Items[0];
    Remove(Item);
    Item.Free;
  end;
end;
procedure TDJXEngine.Add(Item: TDJXEngineItem);
begin
  m_List.Add(Item);
end;
procedure TDJXEngine.Insert(Index: integer; Item: TDJXEngineItem);
begin
  m_List.Insert(Index, Item);
end;
procedure TDJXEngine.Remove(Item: TDJXEngineItem);
begin
  m_List.Remove(Item);
end;
procedure TDJXEngine.Delete(Index: integer);
begin
  m_List.Delete(Index);
end;
procedure TDJXEngine.Draw;
var
  i: integer;
begin
  for i := 0 to m_List.Count - 1 do
  TDJXEngineItem(m_List.Items[i]).Draw;
end;
procedure TDJXEngine.Process(SpeedFactor: single = 1);
var
  i,j: integer;
begin
  i := 0;
  j := m_List.Count - 1;
  while i <= j do
  begin
    TDJXEngineItem(m_List.Items[i]).Process(SpeedFactor);
    if TDJXEngineItem(m_List.Items[i]).m_Dead then
    begin
      TDJXEngineItem(m_List.Items[i]).Destroy;
      Remove(TDJXEngineItem(m_List.Items[i]));
      dec(j);
    end
    else
    inc(i);
  end;
end;
function TDJXEngine.GetCount: integer;
begin
  Result := m_List.Count;
end;
function TDJXEngine.GetItem(Index: integer): TDJXEngineItem;
begin
  Result := TDJXEngineItem(m_List.Items[Index]);
end;
procedure TDJXEngine.SetItem(Index: integer; Value: TDJXEngineItem);
begin
  m_List.Items[Index] := Value;
end;
//DJXEngine END

end.