unit GameMode.Computer;

interface

uses
  System.Classes, System.Generics.Collections, QuadEngine, GameMode.Custom, SysUtils, windows,
  Vec2f, GlobalTypes, GameOverlay;

type
  TMethod = procedure(Index: Integer) of object;

  TButton = record
    Position: TVec2f;
    Size: TVec2f;
    OnClick: TMethod;
    Enabled: Boolean;
  end;

  TGameModeComputer = class(TGameModeCustom)
  const
    pt: array[TPlanetType] of string = ('Asteroid', 'Moon', 'Earth', 'Giant');
  var
    FShuttleLine: Double;
    FFTL: Single;
    FPlanet: TVec2f;
    FButtons: TList<TButton>;
    FPlanets: TList<TPlanet>;

    FFTLCount: Integer;
    FLevelCount: Integer;
    FStatus: TGateModeStatus;
    procedure AddButton(APosition: TVec2f; AOnClick: TMethod);
    procedure CreateDestinyLevel(Index: Integer);
    procedure CreatePlanetLevel(Index: Integer);
  public
    constructor Create; override;
    destructor Destroy; override;
    procedure Process(const Delta: Double); override;
    procedure Draw; override;
    procedure GeneratePlanets;
    procedure Activation; override;
  end;

implementation

uses
  Resources, Collision, GameMode.Planet;

{ TGameModeCustom }

procedure TGameModeComputer.Process(const Delta: Double);
var
  i: Integer;
begin
  FShuttleLine := FShuttleLine + Delta * 6;

  if FShuttleLine > 16 then
    FShuttleLine := FShuttleLine - 16;

  FFTL := FShuttleLine / 16;

  FPlanet.X := FPlanet.X + Delta / 10;
  FPlanet.Y := FPlanet.Y + Delta / 60;

  if (FStatus = gmsGo) then
  begin
    for i := 0 to FPlanets.Count - 1 do
      if (TGlobals.QuadInput.GetMousePosition.Distance(TVec2f.Create(650, 100 + i * 150)) < 50) and
         (TGlobals.QuadInput.IsMouseClick(mbLeft)) then
           CreatePlanetLevel(FPlanets[i].LevelNumber);
  end
  else
    if (FStatus = gmsIntro) and (TGameOverlay.GetDialogCount = 0) then
      FStatus := gmsGo;
end;

procedure TGameModeComputer.Activation;
begin
  if (FStatus = gmsIntro) then
  begin
    TGameOverlay.AddDialog(1, 'FTL? Раш, изъясняйтесь проще!', lEarth);
    TGameOverlay.AddDialog(0, 'Faster Than Light, мы летим быстрее скорости света!', lEarth);
    TGameOverlay.AddDialog(1, 'А это что? Отсеки корабля?', lEarth);
    TGameOverlay.AddDialog(0, 'Именно! Предлагаю начать исследование с них.', lEarth);
  end;
end;

procedure TGameModeComputer.Draw;
var
  i: Integer;
  r: Single;
  c: Cardinal;

  function BoolToYesNo(ABool: Boolean): string;
  begin
    if ABool then
      Result := 'YES'
    else
      Result := 'NO';
  end;

begin
  {$REGION 'Destiny & FTL'}
  TGlobals.QuadRender.SetBlendMode(qbmNone);
  TTextures.DestinyDisplay.Draw(TVec2f.Create(0, 0));
  TGlobals.QuadRender.SetBlendMode(qbmSrcAlphaAdd);
  TGlobals.QuadRender.RectangleEx(TVec2f.Create(417, 50 + FShuttleLine * 5), TVec2f.Create(538, 56 + FShuttleLine * 5), $FF000000, $FF000000, $FF996633, $FF996633);

  if TGlobals.Speed = stFTL then
  begin
    TGlobals.QuadRender.SetBlendMode(qbmSrcAlphaAdd);
    TGlobals.QuadRender.SetTextureAdressing(qtaWrap);

    TShaders.FTL.SetShaderState(True);
    TTextures.FTL.DrawMap(TVec2f.Create(50, 50), TVec2f.Create(436, 560) + TVec2f.Create(50, 50),
                          TVec2f.Create(0, 0), TVec2f.Create(1, 1),
                          $88FFFFFF);
    TTextures.FTL.DrawMap(TVec2f.Create(60, 20), TVec2f.Create(436, 500) + TVec2f.Create(35, 50),
                          TVec2f.Create(0, 0.0), TVec2f.Create(1, 1.0),
                          $448888FF);
    TShaders.FTL.SetShaderState(False);

    TGlobals.QuadRender.SetTextureAdressing(qtaClamp);
  end;
  {$ENDREGION}

  {$REGION 'Destiny Buttons'}
  TGlobals.QuadRender.SetBlendMode(qbmSrcAlphaAdd);

    for i := 0 to FButtons.Count - 1 do
    begin
     // TGlobals.EarthFont.TextOut(FButtons[i].Position, 0.5, PWideChar(IntToStr(i)));
      if (FStatus = gmsGo) and FButtons[i].Enabled and TCollision.PointRect(TGlobals.QuadInput.GetMousePosition, T2DRect.Create(FButtons[i].Position, FButtons[i].Size)) then
      begin
        TTextures.DestinyDisplayButton.Draw(FButtons[i].Position);
        if TGlobals.QuadInput.IsMouseClick(mbLeft) then
          if Assigned(FButtons[i].OnClick) then
            FButtons[i].OnClick(i);
      end
      else
        TTextures.DestinyDisplayButton.Draw(FButtons[i].Position, $FFFF0000);
    end;
  {$ENDREGION}

  {$REGION 'Planet Info'}


  if TGlobals.Speed = stSubLight then
  begin
    for i := 0 to FPlanets.Count - 1 do
    begin
      r := byte(FPlanets[i].&Type) / 8 + 0.1;
      c := $FFFFFFFF;

      if FPlanets[i].BioThreat and FPlanets[i].Storms then
        c := c - $FFFF
      else
        if FPlanets[i].BioThreat or FPlanets[i].Storms then
          c := c - $FF;


      TShaders.Planet.BindVariableToPS(0, @FPlanet, 1);
      TGlobals.QuadRender.SetTextureAdressing(qtaWrap);
      TGlobals.QuadRender.SetBlendMode(qbmSrcAlpha);
      TShaders.Planet.SetShaderState(True);
      TTextures.Planet.DrawRot(TVec2f.Create(650, 100 + i * 150), 0, r * 0.9, $88444444);
      TTextures.Planet.DrawRot(TVec2f.Create(650, 100 + i * 150), 0, r, c);
      if FPlanets[i].CanBreath then
      begin
        TGlobals.QuadRender.SetBlendMode(qbmSrcAlphaAdd);
        TTextures.Planet.DrawRot(TVec2f.Create(650, 100 + i * 150), 0, r * 1.2, $663399FF);
      end;
      TShaders.Planet.SetShaderState(False);
      TGlobals.QuadRender.SetTextureAdressing(qtaClamp);
      TGlobals.AncientsFont.TextOut(TVec2f.Create(730, 90 + i * 150), 0.5, PWideChar('ADRESS: ' + FPlanets[i].Adress));



      TGlobals.QuadRender.SetBlendMode(qbmSrcAlpha);
      if TGlobals.QuadInput.GetMousePosition.Distance(TVec2f.Create(650, 100 + i * 150)) < 50 then
      TGlobals.AncientsFont.TextOut(TVec2f.Create(600, 500), 0.5, PWideChar('^$WPlanet type: ' + pt[FPlanets[i].&Type] + #13#13 +
                                                                            '^$WGravity: ^$R' + FormatFloat('0.00', FPlanets[i].Gravity) + 'G'#13#13+
                                                                            '^$WCAN BREATHE: ^$Y' + BoolToYesNo(FPlanets[i].CanBreath) + #13#13+
                                                                            '^$WAVG TEMPERATURE: ^$Y'+ FormatFloat('0.00', FPlanets[i].AvgTemperature) + #13#13+
                                                                            '^$WDAYTIME: ' + FormatFloat('0.00', FPlanets[i].DayTime) + 'HOURS'#13#13+
                                                                            '^$WYEARTIME: ' + FormatFloat('0.00', FPlanets[i].YearTime) + 'YEARS'#13#13+
                                                                            '^$WSTORMS: ^$Y' + BoolToYesNo(FPlanets[i].Storms) + #13#13+
                                                                            '^$WBIO THREAT: ^$R' + BoolToYesNo(FPlanets[i].BioThreat)));
    end;
  end
  else
  begin

  end;
  {$ENDREGION}

  {$REGION 'Ready'}
  TGlobals.QuadRender.DrawCircle(TVec2f.Create(900, 600), 100, 97, $FF99CCFF);
  TGlobals.QuadRender.DrawCircle(TVec2f.Create(900, 600), 90, 84, $FF88BBFF);
  TGlobals.QuadRender.DrawCircle(TVec2f.Create(900, 600), 70, 69, $FF77AAFF);
  TGlobals.QuadRender.DrawCircle(TVec2f.Create(900, 600), 68, 66, $FF6699FF);

  TGlobals.AncientsFont.TextOut(TVec2f.Create(900, 620), 1.0, 'READY', $FFFFCC99, qfaCenter);
  {$ENDREGION}
end;

procedure TGameModeComputer.CreatePlanetLevel(Index: Integer);
begin
  if not Assigned(TGlobals.GameModes.PlanetLevels[FPlanets[Index].LevelNumber]) then
    TGlobals.GameModes.PlanetLevels[FPlanets[Index].LevelNumber] := TGameModePlanet.Create('Maps\Planet' + IntToStr(FPlanets[Index].LevelNumber), wtSnow);
  TGlobals.GameModes.Level := TGlobals.GameModes.PlanetLevels[FPlanets[Index].LevelNumber];
  TGlobals.GameModes.StarGate.Restart;
  TGlobals.GameModeManager.SetActiveGameMode(TGlobals.GameModes.StarGate);
end;

procedure TGameModeComputer.CreateDestinyLevel(Index: Integer);
begin
  if not Assigned(TGlobals.GameModes.DestinyLevels[Index]) then
    TGlobals.GameModes.DestinyLevels[Index] := TGameModePlanet.Create('Maps\Destiny' + IntToStr(Index + 1), wtDestiny);
  TGlobals.GameModes.Level := TGlobals.GameModes.DestinyLevels[Index];
  TGlobals.GameModeManager.SetActiveGameMode(TGlobals.GameModes.FeesSquad);
end;

constructor TGameModeComputer.Create;
begin
  inherited;
  FStatus := gmsIntro;
  FButtons := TList<TButton>.Create;
  FPlanets := TList<TPlanet>.Create;

  TShaders.FTL.BindVariableToPS(0, @FFTL, 1);
  FFTLCount := 0;
  FLevelCount := 0;
  {$REGION 'Add Buttons'}
  AddButton(TVec2f.Create(395, 429), CreateDestinyLevel);
  AddButton(TVec2f.Create(137, 424), CreateDestinyLevel);
  AddButton(TVec2f.Create(424, 388), CreateDestinyLevel);
  AddButton(TVec2f.Create(135, 383), CreateDestinyLevel);
  AddButton(TVec2f.Create(358, 364), CreateDestinyLevel);
  AddButton(TVec2f.Create(161, 354), CreateDestinyLevel);
 // AddButton(TVec2f.Create(373, 319), CreateDestinyLevel);
  {AddButton(TVec2f.Create(180, 306), nil);
  AddButton(TVec2f.Create(323, 297), nil);
  AddButton(TVec2f.Create(165, 281), nil);
  AddButton(TVec2f.Create(348, 276), nil);
  AddButton(TVec2f.Create(386, 257), nil);
  AddButton(TVec2f.Create(204, 247), nil);
  AddButton(TVec2f.Create(357, 216), nil);
  AddButton(TVec2f.Create(203, 194), nil);
  AddButton(TVec2f.Create(165, 166), nil);
  AddButton(TVec2f.Create(319, 128), nil);
  AddButton(TVec2f.Create(343, 81), nil);  }
  {$ENDREGION}
end;

destructor TGameModeComputer.Destroy;
begin
  FButtons.Free;
  FPlanets.Free;

  inherited;
end;

procedure TGameModeComputer.AddButton(APosition: TVec2f; AOnClick: TMethod);
var
  b: TButton;
  Index: Integer;
begin
  b.Position := APosition;
  b.Size := TVec2f.Create(46, 20);
  b.OnClick := AOnClick;
  Index := FButtons.Add(b);

  b.Enabled := true;// (Index > 0) and (Index <= 6); //FileExists('Maps\Destiny' + IntToStr(Index) + '.png') and FileExists('Maps\Destiny' + IntToStr(Index) + '.ini');
end;

procedure TGameModeComputer.GeneratePlanets;
var
  pl: TPlanet;
  i: Integer;
  Count: Integer;
begin
  FPlanets.Clear;

  case FFTLCount of
    0: Count := 2;
    1: Count := 1;
    else Count := 0;
  end;

  for i := 0 to {random(2) + 1} Count - 1 do
  begin
    pl.&Type := TPlanetType(random(4));
    pl.Gravity := random(30) / 10 * byte(pl.&Type);
    pl.CanBreath := Random(2) = 1;
    pl.AvgTemperature := random(1500) / 10 - 75;
    pl.DayTime := random(6400) / 100 + 12;
    pl.YearTime := random(6400) / 100 + 12;
    pl.Storms := Random(2) = 1;
    pl.BioThreat := Random(2) = 1;
    pl.Adress := Chr(Random(26) + ord('A')) + Chr(Random(10) + ord('0')) +
                 Chr(Random(26) + ord('A')) + Chr(Random(10) + ord('0')) +
                 Chr(Random(26) + ord('A')) + Chr(Random(10) + ord('0'));

    pl.LevelNumber := FLevelCount;
    FPlanets.Add(pl);
    Inc(FLevelCount);
  end;
  Inc(FFTLCount);
end;

end.
