unit ant_hud;

//
//  Renders rose of wind and resource bar.
//

{$MODE FPC}
{$MODESWITCH AUTODEREF}
{$MODESWITCH DEFAULTPARAMETERS}
{$MODESWITCH OUT}
{$MODESWITCH RESULT}

interface

uses
  {$I deng_app_units.inc},
  DDrawTex,
  dvector2f,
  dvector2i,
  dvector4f,
  drect2i,
  ant_config,
  ant_resources,
  ant_text;

const
  STATE_REPRODUCTION  = 0;
  STATE_EXPANDING     = 1;
  STATE_FOOD          = 2;
  STATE_ATTACK        = 3;

type
PAntHillState = ^TAntHillState;
TAntHillState = object
  State: Int32;
  Food: Int64;
  AntsCount: Int64;
  LastSwitchTime: Int32;
  MaxFood: Int64;
  TerritorySize: Single;
  procedure Init;
  procedure Done;
end;

PDrawTex = ^TDrawTex;

THUD = object
  Tex: array[0 .. 3] of PDrawTex;
  Color: array[0 .. 3] of TVec4f;
  procedure Init;
  procedure Done;

  procedure DrawRose(State: PAntHillState; BarWidth, BarHeight: Single);
  procedure DrawBar(State: PAntHillState; Damaged: Boolean; BarWidth, BarHeight: Single);

  procedure Draw(State: PAntHillState; Damaged, Won: Boolean);
  // should be called in 2d state
end;

implementation

procedure TAntHillState.Init;
begin
  State := STATE_REPRODUCTION;
  Food := 5000;
  AntsCount := 0;
  LastSwitchTime := Low(Int32);
  MaxFood := Config.MaxFood;
  TerritorySize := 40;
end;

procedure TAntHillState.Done;
begin
end;

procedure THUD.Init;
begin
  Tex[STATE_FOOD] := @Res.Icon.Resource;
  Tex[STATE_REPRODUCTION] := @Res.Icon.Plus;
  Tex[STATE_ATTACK] := @Res.Icon.Sword;
  Tex[STATE_EXPANDING] := @Res.Icon.Arrows;
  Color[STATE_EXPANDING] := Vec4f(0, 0, 0.5, 1.0);
  Color[STATE_REPRODUCTION] := Vec4f(128/255, 100/255, 219/255, 1.0);
  Color[STATE_ATTACK] := Vec4f(0.5, 0, 0, 1.0);
  Color[STATE_FOOD] := Vec4f(90/255, 0, 157/255, 1.0);
end;

procedure THUD.Done;
begin
end;

procedure THUD.DrawRose(State: PAntHillState; BarWidth, BarHeight: Single);
var
  RoseSize: Single;
  RoseThick: Single;
  Delta: Single;
  Radius: Single;
  I: Int32;

  procedure DrawIcon(Index: Int32; const Pos: TVec2f);
  var
    F: Single;
  begin
    F := 2 * Pos.X / RoseSize;
    if F > 1 then
      F := 1;
    if F < 0.5 then
      F := 0.5;
    Eng.Draw.RGBA(128, 128, 128, 255);
    Eng.Draw.CircleFilled(Pos, (1 - Sqr(1 - F)) * Radius / 2 * Sqrt(2));
    F := 1.0;
    Eng.Draw.Color(Vec4f(Color[Index].X * F, Color[Index].Y * F, Color[Index].Z * F, Color[Index].W));
    Tex[Index]^.Draw(@Eng, Pos, Vec2f(Radius, Radius));
  end;
begin
  if State^.Food <= 0 then
    Exit;
  Eng.Draw.RGBA(128, 128, 128, 255);
  RoseSize := BarWidth / 20 * 3;
  RoseThick := BarHeight / 5;
  Radius := RoseSize / 3;
  Eng.Draw.PushMatrix;
  Eng.Draw.Translate(Vec2f(0, BarHeight / 2.0));
  // Eng.Draw.Scale(RoseSize / 3 / 256);
  Delta := (Eng.Time - State^.LastSwitchTime) / 200;
  if (0 <= Delta) and (Delta < 1.0) then begin
    Eng.Draw.Rotate(- (1 - Delta) * 90);
  end;
  Eng.Draw.RectFilled(drect2i.Rect2i(Vec2i(Round(-RoseSize/2), Round(-RoseThick/2)), Vec2i(Round(RoseSize), Round(RoseThick))));
  Eng.Draw.RectFilled(drect2i.Rect2i(Vec2i(Round(-RoseThick/2), Round(-RoseSize/2)), Vec2i(Round(RoseThick), Round(RoseSize))));
  I := State^.State;
  DrawIcon(I, Vec2f(RoseSize/2, 0));
  DrawIcon((I + 3) mod 4, Vec2f(0, RoseSize/2));
  DrawIcon((I + 2) mod 4, Vec2f(-RoseSize/2, 0));
  DrawIcon((I + 1) mod 4, Vec2f(0, -RoseSize/2));
  Eng.Draw.PopMatrix;
end;

procedure THUD.DrawBar(State: PAntHillState; Damaged: Boolean; BarWidth, BarHeight: Single);
begin
  if State^.State = STATE_FOOD then begin
    Eng.Draw.RGBA(0, 128, 0, 255);
  end else
    Eng.Draw.RGBA(128, 0, 0, 255);
  if State^.Food <= 0 then
    Eng.Draw.RGBA(0, 0, 0, 255);
  Eng.Draw.Rect(drect2i.Rect2i(Vec2i(0, 0), Vec2i(Round(BarWidth), Round(BarHeight))));
  if (State^.Food > 0) and Damaged then
    Eng.Draw.RGBA(255, 255, 255, 255);
  Eng.Draw.RectFilled(drect2i.Rect2i(Vec2i(0, 0), Vec2i(Round(BarWidth * State^.Food / State^.MaxFood), Round(BarHeight))));
end;

procedure THUD.Draw(State: PAntHillState; Damaged, Won: Boolean);
const
  BAR_WIDTH = 0.3;
var
  BarWidth, BarHeight: Single;
begin
  BarWidth := Eng.Width * BAR_WIDTH;
  BarHeight := BarWidth / 12;
  DrawBar(State, Damaged, BarWidth, BarHeight);
  DrawRose(State, BarWidth, BarHeight);
  Eng.Draw.RGBA(255, 255, 255, 255);
  if State^.Food <= 0 then
    AntText(Vec2f(0, BarHeight), 'Press R for restart');
  if Won then begin
    Eng.Draw.RGBA(Random(255), Random(255), Random(255), 255);
    AntText(Vec2f(0, BarHeight), 'Congratulations!!! You are last standing! Press R for another game');
  end;
  Eng.Draw.RGBA(255, 255, 255, 255);
end;

end.
