unit Subject;

interface

uses
  System.SysUtils, QuadEngine, Vec2f, CustomGun;

type
  TSubjectType = (
    stNone = 0,
    stSpaceSuit = 1,
    stWater = 2,
    stGunUMP = 3,
    stGunBeretta92F = 4,
    stIPAD = 5,
    stKino = 6,
    stRepairDrone = 7,
    stCommDevice = 8,
    stFlashLight = 9,
    stWolfTreasure = 10
  );

  TSubjectDrawType = (
    sdtNone = 0,
    sdtAction = 1
  );

  TSubject = class
  private
    FCount: Integer;
    FSubjectType: TSubjectType;
    FHP: Integer;
    FIsAction: Boolean;
    FGun: TCustomGun;
  public
    class procedure Draw(ASubject: TSubject; APosition: TVec2f; ADrawType: TSubjectDrawType = sdtNone);
    constructor Create(ASubjectType: TSubjectType; ACount: Integer);
    function Add(ASubject: TSubject): TSubject;
    procedure Damage(ADamage: Integer);
    procedure Process(const Delta: Double);
    function GetMaxCount: Integer;
    property Count: Integer read FCount;
    property SubjectType: TSubjectType read FSubjectType;
    property IsAction: Boolean read FIsAction write FIsAction;

    property Gun: TCustomGun read FGun;
  end;

implementation

uses
  Resources, Math, GunBeretta92F, GunUMP;

constructor TSubject.Create(ASubjectType: TSubjectType; ACount: Integer);
begin
  FSubjectType := ASubjectType;
  FCount := GetMaxCount;
  FHP := 100;
  FIsAction := False;
  case FSubjectType of
    stGunUMP: FGun := TGunUMP.Create;
    stGunBeretta92F: FGun := TGunBeretta92F.Create;
  end;
  if Assigned(FGun) then
  begin
    FGun.SetProc(
      function: boolean
      begin
        Result := FCount > 0;
        if Result then
          Dec(FCount);
      end,
      function(ACapacity: Integer): Integer
      begin
        Result := Min(ACapacity, FCount);
      end
    );
    FGun.Init;
  end;
end;

function TSubject.GetMaxCount: Integer;
begin
  case FSubjectType of
    stWater: Result := 10;
    stGunUMP: Result := 81;
    stGunBeretta92F: Result := 35;
    else Result := 1;
  end;
end;

procedure TSubject.Process(const Delta: Double);
begin
  if Assigned(FGun) then
    FGun.Process(Delta);
end;

procedure TSubject.Damage(ADamage: Integer);
begin
  FHP := FHP - ADamage;
end;

function TSubject.Add(ASubject: TSubject): TSubject;
var
  MaxCount: Integer;
begin
  MaxCount := GetMaxCount;
  if FCount + ASubject.Count > MaxCount then
  begin
    FCount := MaxCount;
    ASubject.FCount := FCount + ASubject.Count - MaxCount;
    Result := ASubject;
  end
  else
  begin
    FCount := FCount + ASubject.Count;
    ASubject.Free;
    Result := nil;
  end;
end;

class procedure TSubject.Draw(ASubject: TSubject; APosition: TVec2f; ADrawType: TSubjectDrawType = sdtNone);
begin
  if not Assigned(ASubject) then
    ADrawType := sdtNone;
  if Assigned(ASubject) and ASubject.IsAction then
    ADrawType := sdtAction;

  case ADrawType of
    sdtNone: TTextures.Subjects.DrawFrame(APosition, 0);
    sdtAction: TTextures.Subjects.DrawFrame(APosition, 1, $FF00FF00);
  end;
  //TGlobals.QuadRender.Rectangle(APosition + TVec2f.Create(1, 1), APosition + TVec2f.Create(64-2, 64-2), $88000000);
  if not Assigned(ASubject) then
    Exit;

  TTextures.Subjects.DrawFrame(APosition, Integer(ASubject.SubjectType) + 1, $FFFFFFFF);
  if ASubject.Count > 1 then
    TGlobals.EarthFont.TextOut(APosition + TVec2f.Create(6, 58), 0.5, PWideChar(IntToStr(ASubject.Count)));

end;

end.
