unit GameMode.FeesSquad;

interface

uses
  System.Classes, System.Generics.Collections, QuadEngine, GameMode.Custom, Vec2f, Math,
  Units.Player, Windows, Units.Custom, CustomObject, Collision, Subject;

type
  TGameModeFeesSquad = class(TGameModeCustom)
  private
    FRectHeroList: T2DRect;
    FRectSubjectList: T2DRect;
    FPositionSubjectToHero: TVec2f;
    FPositionSquad: TVec2f;
    FRectGo: T2DRect;
    FRectBack: T2DRect;

    FDragPosition: TVec2f;

    FHeroesScroll: Integer;
    FHeroesHeight: Integer;
    FDragHero: TUnitsPlayer;
    FOldMouseDown: Boolean;
    FSquad: array[0..3] of TUnitsPlayer;

    FSubjectHeight: Integer;
    FSubjectsScroll: Integer;
    FDragSubject: TSubject;
    function ExistsHero(AHero: TUnitsPlayer): Boolean;
    function ExistsSubject(ASubject: TSubject): Boolean;
    function SquadCount: integer;
    function IsFull: Boolean;
  public
    constructor Create; override;
    destructor Destroy; override;
    procedure Process(const Delta: Double); override;
    procedure Draw; override;
    procedure Deactivation; override;
    procedure Activation; override;

  end;

implementation

uses
  Resources, GameMode.Planet, GameOverlay;

constructor TGameModeFeesSquad.Create;
var
  i, n: Integer;
begin
  inherited;
  FSubjectHeight := 64;

  FRectHeroList := T2DRect.Create(33, 64, 332, TGlobals.GHeight - 140);
  FRectSubjectList := T2DRect.Create(TGlobals.GWidth div 2 - 128, 64, 264, TGlobals.GHeight - 140);
  FPositionSquad := TVec2f.Create(1024 - 365, 64);
  FRectGo := T2DRect.Create(TGlobals.GWidth - 365, TGlobals.GHeight - 64, 332, 33 + 15);
  FRectBack := T2DRect.Create(33, TGlobals.GHeight - 64, 332, 33 + 15);

  FPositionSubjectToHero := TVec2f.Create(77, 88);

  FHeroesHeight := 102;
  FHeroesScroll := 0;
  FOldMouseDown := False;
  FDragHero := nil;
  for i := 0 to 3 do
    FSquad[i] := nil;
          {
  for n := 0 to 3 do
  begin
    FSquad[n] := TGlobals.Heroes[n];
    for i := 0 to FSquad[n].Inventory - 1 do
    begin
      FSquad[n].Subjects[i] := TGlobals.Subjects[0];
      TGlobals.Subjects.Delete(0);
    end;
  end; }
end;

procedure TGameModeFeesSquad.Activation;
var
  i, j: Integer;
begin
  for j := 0 to TGlobals.Heroes.Count - 1 do
    for i := 0 to TGlobals.Heroes[j].Inventory - 1 do
      if Assigned(TGlobals.Heroes[j].Subjects[i]) then
      begin
        TGlobals.Subjects.Add(TGlobals.Heroes[j].Subjects[i]);
        TGlobals.Heroes[j].Subjects[i] := nil;
      end;
end;

procedure TGameModeFeesSquad.Deactivation;
var
  i: Integer;
begin
  FOldMouseDown := False;
  FDragHero := nil;
  for i := 0 to 3 do
    FSquad[i] := nil;
end;

destructor TGameModeFeesSquad.Destroy;
begin

end;

function TGameModeFeesSquad.ExistsHero(AHero: TUnitsPlayer): Boolean;
var
  i: Integer;
begin
  for i := 0 to 3 do
    if Assigned(FSquad[i]) and (FSquad[i] = AHero) then
      Exit(True);
  Result := False;
end;

function TGameModeFeesSquad.ExistsSubject(ASubject: TSubject): Boolean;
var
  i, j: Integer;
begin
  for i := 0 to 3 do
    if Assigned(FSquad[i]) then
      for j := 0 to FSquad[i].Inventory - 1 do
        if FSquad[i].Subjects[j] = ASubject then
          Exit(True);
  Result := False;
end;

function TGameModeFeesSquad.IsFull: Boolean;
var
  i: Integer;
begin
  for i := 0 to 3 do
    if not Assigned(FSquad[i]) then
      Exit(False);
  Result := True;
end;

function TGameModeFeesSquad.SquadCount: integer;
var
  i: Integer;
begin
  Result := 0;
  for i := 0 to 3 do
    if Assigned(FSquad[i]) then
      Inc(Result);
end;

procedure TGameModeFeesSquad.Process(const Delta: Double);
var
  i, n: Integer;
  Rect: T2DRect;
begin
  if TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, FRectHeroList) then
    FHeroesScroll := FHeroesScroll - Round(TGlobals.QuadInput.GetMouseWheel.Y * 0.5);

  FHeroesScroll := Min(Max(0, (FHeroesHeight + 4) * (TGlobals.Heroes.Count - SquadCount) - 4 - Round(FRectHeroList.Size.Y)), Max(0, FHeroesScroll));

  if TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, FRectSubjectList) then
    FSubjectsScroll := FSubjectsScroll - Round(TGlobals.QuadInput.GetMouseWheel.Y * 0.5);

  n := TGlobals.Subjects.Count div 4;
  if TGlobals.Subjects.Count mod 4 > 0 then
    Inc(n);
  FSubjectsScroll := Min(Max(0, FSubjectHeight * n - Round(FRectSubjectList.Size.Y)), Max(0, FSubjectsScroll));

  //////////////////////////////////////////////
  Rect.Size.X := FSubjectHeight;
  Rect.Size.Y := FSubjectHeight;
  if not FOldMouseDown and TGlobals.QuadInput.IsMouseDown(mbLeft) then
  begin
    if {not IsFull and} TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, FRectSubjectList) then
    begin
      n := 0;
      Rect.Position := FRectSubjectList.Position + TVec2f.Create(0, -FSubjectsScroll);
      for i := 0 to TGlobals.Subjects.Count - 1 do
      //  if not ExistsSubject(TGlobals.Subjects[i]) then
        begin
          if TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, Rect) then
          begin
            FDragSubject := TGlobals.Subjects[i];
            FDragPosition := TGlobals.QuadInput.GetMousePosition - Rect.Position;
            Break;
          end;
          Rect.Position.X := Rect.Position.X + FSubjectHeight;
          inc(n);
          if n > 3 then
          begin
            n := 0;
            Rect.Position := TVec2f.Create(FRectSubjectList.Position.X, Rect.Position.Y + FSubjectHeight);
          end;
        end;
    end;

    for i := 0 to 3 do
    begin
      if Assigned(FDragSubject) then
        Break;

      Rect.Position := FPositionSquad + TVec2f.Create(0, (FHeroesHeight + 55) * i);
      if Assigned(FSquad[i]) then
      begin
        Rect.Position := Rect.Position + FPositionSubjectToHero;
        for n := 0 to FSquad[i].Inventory - 1 do
        begin
          if Assigned(FSquad[i].Subjects[n]) and TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, Rect) then
          begin
            FDragSubject := FSquad[i].Subjects[n];
            FSquad[i].Subjects[n] := nil;
            FDragPosition := TGlobals.QuadInput.GetMousePosition - Rect.Position;
            Break;
          end;
          Rect.Position := Rect.Position + TVec2f.Create(64 , 0);
        end;
      end;
    end;

  end
  else
  if Assigned(FDragSubject) and FOldMouseDown and not TGlobals.QuadInput.IsMouseDown(mbLeft) then
  begin
    for i := 0 to 3 do
    begin
      if not Assigned(FDragSubject) then
        Break;

      Rect.Position := FPositionSquad + TVec2f.Create(0, (FHeroesHeight + 55) * i);
      if Assigned(FSquad[i]) then
      begin
        Rect.Position := Rect.Position + FPositionSubjectToHero;
        for n := 0 to FSquad[i].Inventory - 1 do
        begin
          if not Assigned(FSquad[i].Subjects[n]) then
            if TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, Rect) then
            begin
              FSquad[i].Subjects[n] := FDragSubject;
              TGlobals.Subjects.Remove(FDragSubject);

              if (FSquad[i].MaxStamina = 150) and (FDragSubject.SubjectType = stGunUMP) and (random(3) = 1) then
                TGameOverlay.AddDialog(FSquad[i].Portrait, 'Вот этот ствол мне по душе!', lEarth);

              if (FSquad[i].MaxStamina = 120) and (FDragSubject.SubjectType = stGunBeretta92F) and (random(3) = 1) then
                TGameOverlay.AddDialog(FSquad[i].Portrait, 'В самый раз', lEarth);

              if (FSquad[i].MaxStamina = 100) and (FDragSubject.SubjectType = stSpaceSuit) and (random(3) = 1) then
                TGameOverlay.AddDialog(FSquad[i].Portrait, 'Без скафанда я никуда не пойду!', lEarth);

              FDragSubject := nil;
              Break;
            end;
          Rect.Position := Rect.Position + TVec2f.Create(64 , 0);
        end;
      end;
    end;


    if Assigned(FDragSubject) and (TGlobals.Subjects.IndexOf(FDragSubject) < 0) then
      TGlobals.Subjects.Add(FDragSubject);

    FDragSubject := nil;
  end;

  //////////////////////////////////////////////
  if not Assigned(FDragSubject) then
  begin
    Rect.Size.X := FRectHeroList.Size.X;
    Rect.Size.Y := FHeroesHeight;
    if not FOldMouseDown and TGlobals.QuadInput.IsMouseDown(mbLeft) then
    begin
      if not IsFull and TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, FRectHeroList) then
      begin
        Rect.Position.X := FRectHeroList.Position.X;
        n := 0;
        for i := 0 to TGlobals.Heroes.Count - 1 do
          if not ExistsHero(TGlobals.Heroes[i]) then
          begin
            Rect.Position.Y := FRectHeroList.Position.Y + (FHeroesHeight + 4) * n - FHeroesScroll;
            if TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, Rect) then
            begin
              FDragHero := TGlobals.Heroes[i];
              FDragPosition := TGlobals.QuadInput.GetMousePosition - Rect.Position;
              Break;
            end;
            Inc(n);
          end;
      end;

      Rect.Position.X := FPositionSquad.X;
      for i := 0 to 3 do
      begin
        Rect.Position.Y := FPositionSquad.Y + (FHeroesHeight + 50) * i;
        if TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, Rect) then
        begin
          FDragHero := FSquad[i];
          FSquad[i] := nil;
          FDragPosition := TGlobals.QuadInput.GetMousePosition - Rect.Position;
          Break;
        end;
      end;
    end
    else
    if Assigned(FDragHero) and FOldMouseDown and not TGlobals.QuadInput.IsMouseDown(mbLeft) then
    begin
      Rect.Position.X := FPositionSquad.X;
      for i := 0 to 3 do
      begin
        Rect.Position.Y := FPositionSquad.Y + (FHeroesHeight + 50) * i;
        if TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, Rect) then
        begin
          FSquad[i] := FDragHero;
          FDragHero := nil;
          Break;
        end;
      end;

      if Assigned(FDragHero) then
        for i := 0 to FDragHero.Inventory - 1 do
          if Assigned(FDragHero.Subjects[i]) then
          begin
            TGlobals.Subjects.Add(FDragHero.Subjects[i]);
            FDragHero.Subjects[i] := nil;
          end;

      FDragHero := nil;
    end;
  end;
  //////////////////////////////////////////////

  if (SquadCount > 0) and (
    TGlobals.QuadInput.IsKeyPress(VK_RETURN) or
    (TGlobals.QuadInput.IsMouseClick(mbLeft) and TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, FRectGo))) then
  begin
    TGlobals.LevelHeroes.Clear;
    for i := 0 to 3 do
      if Assigned(FSquad[i]) then
        TGlobals.LevelHeroes.Add(FSquad[i]);
    TGlobals.GameModes.Level.Init;
    TGlobals.GameModeManager.SetActiveGameMode(TGlobals.GameModes.Level);
  end;

  if TGlobals.QuadInput.IsKeyPress(VK_ESCAPE) or (TGlobals.QuadInput.IsMouseClick(mbLeft)
    and TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, FRectBack)) then
    TGlobals.GameModeManager.SetActiveGameMode(TGlobals.GameModes.Computer);

  FOldMouseDown := TGlobals.QuadInput.IsMouseDown(mbLeft);
end;

procedure TGameModeFeesSquad.Draw;

  procedure DrawHeroes(AHero: TUnitsPlayer; APosition: TVec2f);
  begin
    TTextures.Panel.Hero.Draw(APosition);
    if not Assigned(AHero) then
      Exit;

    TTextures.Portraits.DrawRotFrame(APosition + TVec2f.Create(41, FHeroesHeight / 2), 0, 1, AHero.Portrait);

   // TGlobals.QuadRender.Rectangle(APosition + TVec2f.Create(10, 10), APosition + TVec2f.Create(80, FHeroesHeight - 10), $FFFFFFFF);

    TGlobals.EarthFont.TextOut(APosition + TVec2f.Create(85, 30), 0.7, PWideChar(AHero.Name));
  end;

var
  i, n: Integer;
  Position: TVec2f;
begin
  TGlobals.QuadRender.SetBlendMode(qbmSrcAlpha);
  TGlobals.QuadRender.Rectangle(TVec2f.Zero, TVec2f.Create(TGlobals.GWidth, TGlobals.GHeight), $FF42332c);

  TGlobals.QuadRender.FlushBuffer;
  TGlobals.QuadRender.SetClipRect(
    Round(FRectSubjectList.Position.X), Round(FRectSubjectList.Position.Y),
    Round(FRectSubjectList.Position.X + FRectSubjectList.Size.X), Round(FRectSubjectList.Position.Y + FRectSubjectList.Size.Y)
  );


  n := 0;
  Position := FRectSubjectList.Position + TVec2f.Create(0, -FSubjectsScroll);
  for i := 0 to TGlobals.Subjects.Count - 1 do
    //if not ExistsSubject(TGlobals.Subjects[i]) then
    begin
      if TGlobals.Subjects[i] <> FDragSubject then
      TSubject.Draw(TGlobals.Subjects[i], Position);

      Position.X := Position.X + FSubjectHeight;
      inc(n);
      if n > 3 then
      begin
        n := 0;
        Position := TVec2f.Create(FRectSubjectList.Position.X, Position.Y + FSubjectHeight);
      end;
    end;

  TGlobals.QuadRender.FlushBuffer;
  TGlobals.QuadRender.SkipClipRect;
  TGlobals.QuadRender.SetClipRect(Round(FRectHeroList.Position.X), Round(FRectHeroList.Position.Y), Round(FRectHeroList.Size.X + FRectHeroList.Position.X), Round(FRectHeroList.Size.Y + FRectHeroList.Position.Y));

  n := 0;
  for i := 0 to TGlobals.Heroes.Count - 1 do
    if not ExistsHero(TGlobals.Heroes[i]) then
    begin
      if FDragHero <> TGlobals.Heroes[i] then
        DrawHeroes(TGlobals.Heroes[i], FRectHeroList.Position + TVec2f.Create(0, (FHeroesHeight + 4) * n - FHeroesScroll));
      inc(n);
    end;
  TGlobals.QuadRender.FlushBuffer;
  TGlobals.QuadRender.SkipClipRect;

  for i := 0 to 3 do
  begin
    Position := FPositionSquad + TVec2f.Create(0, (FHeroesHeight + 55) * i);
    DrawHeroes(FSquad[i], Position);
    if Assigned(FSquad[i]) then
    begin
    //  Position := Position + TVec2f.Create(300 - FSquad[i].Inventory * 64 - 10, 90);
      for n := 0 to FSquad[i].Inventory - 1 do
        TSubject.Draw(FSquad[i].Subjects[n], Position + FPositionSubjectToHero + TVec2f.Create(n * 64 , 0));
    end;
  end;

  if Assigned(FDragHero) then
  begin
    Position := TGlobals.QuadInput.GetMousePosition - FDragPosition;
    DrawHeroes(FDragHero, Position);
    for n := 0 to FDragHero.Inventory - 1 do
      TSubject.Draw(FDragHero.Subjects[n], Position + FPositionSubjectToHero + TVec2f.Create(n * 64 , 0));
  end;

  if Assigned(FDragSubject) then
    TSubject.Draw(FDragSubject, TGlobals.QuadInput.GetMousePosition - FDragPosition);

  if (SquadCount > 0) then
  begin
    TGlobals.QuadRender.Rectangle(FRectGo.Position, FRectGo.Position + FRectGo.Size, $88000000);
    TGlobals.EarthFont.TextOut(FRectGo.Position + FRectGo.Size / 2 + TVec2f.Create(0, 8), 0.8, 'Отправить отряд', $FFFFFFFF, qfaCenter);
  end;

  TGlobals.QuadRender.Rectangle(FRectBack.Position, FRectBack.Position + FRectBack.Size, $88000000);
  TGlobals.EarthFont.TextOut(FRectBack.Position + FRectBack.Size / 2 + TVec2f.Create(0, 8), 0.8, 'Назад', $FFFFFFFF, qfaCenter);


end;

end.
