unit uGmGUI;

interface

uses
  zglHeader, uGmData, uGmTypes, uGmArena, uGmCreature, uGmSprite, uGmUtils, uGmPathfind;

type
  TCurState = ( CUR_CURSOR, CUR_WALK, CUR_ATACK, CUR_SHOOT, CUR_FLY, CUR_NONE );

var
  CurState  : TCurState;
  CurAng    : integer;

type
  PBuyCrBtn = ^TBuyCrBtn;
  TBuyCrBtn = record
     X, Y       : integer;
     Width      : integer;
     Height     : integer;
     CrPat      : PCrPat;
     MouseOver  : boolean;
  end;

type
  TStatsWnd = record
     X, Y       : integer;
     CrPat      : PCrPat;
     Cr         : TCreature;
     Visible    : boolean;
  end;

type
  PGmButton = ^TGmButton;
  TGmButton = record
     Name       : string;
     X, Y       : integer;
     Width      : integer;
     Height     : integer;
     Tex        : zglPTexture;
     Caption    : string;
     MouseOver  : boolean;
     Visible    : boolean;
     Enabled    : boolean;
     Clicked    : boolean;
  end;

var
  BuyCrBtn     : array of TBuyCrBtn;
  BuyCrBtnCnt  : integer;
  bcbN, bcbDN  : integer;
  mxdwn, mydwn : integer;
  StatsWnd     : TStatsWnd;
  StatsCrFace  : TBuyCrBtn;
  GmButtons    : array of TGmButton;
  GmButtonsCnt : integer;
  ShowText     : boolean = True;
  ExitConfirm  : boolean = False;
  EndTurnBtn   : PGmButton;

function GmButton_Get( BName : string ): PGmButton;
procedure GmGUI_Init;
procedure GmGUI_Draw;
procedure GmGUI_Update;
procedure GmShopGUI_Init;

implementation

//==============================================================================
procedure BuyCrBtn_Draw( cb : PBuyCrBtn; DrawCost : boolean = True );
var
  cx, cy, w : integer;
  clr : LongWord;
  CanBuy : boolean;
begin
  CanBuy := ( cb.CrPat.Cost <= Arena.Money );
  if DrawCost = False then CanBuy := True;

  if CanBuy then fx2d_SetVCA( $0099FF, $0099FF, $88DDFF, $88DDFF, 255, 255, 255, 255 )
    else fx2d_SetVCA( $888888, $888888, $DDDDDD, $DDDDDD, 255, 255, 255, 255 );
  pr2d_Rect( cb.X, cb.Y, cb.Width, cb.Height, $0099FF, 255, PR2D_FILL or FX2D_VCA );

  cx := cb.X + cb.Width div 2;
  cy := cb.Y + cb.Height div 2;

  scissor_Begin( cb.X, cb.Y, cb.Width, cb.Height );
  if CanBuy then Sprite_Draw( @cb.CrPat.StandSpr, cx - 4, cy + 16, 0 )
    else Sprite_Draw( @cb.CrPat.StandSpr, cx - 4, cy + 16, 0, False, 150 );
  scissor_End;

  if DrawCost then
  begin
    if CanBuy then pr2d_Rect( cb.X, cb.Y + cb.Height, cb.Width, 14, $3366CC, 255, PR2D_FILL )
      else pr2d_Rect( cb.X, cb.Y + cb.Height, cb.Width, 14, $696969, 255, PR2D_FILL );

    w := Round( text_GetWidth( Font2, u_IntToStr( cb.CrPat.Cost ) ) );
    text_Draw( Font2, cx - w div 2, cb.Y + cb.Height + 2, u_IntToStr( cb.CrPat.Cost ) );

    ssprite2d_Draw( CoinTex, cx + w div 2 - 1, cb.Y + cb.Height - 1, 16, 16, 0 );
  end;

  clr := $330099;
  if cb.MouseOver then clr := $EEEEFF;
  pr2d_Rect( cb.X, cb.Y, cb.Width, cb.Height, clr, 255 );
end;

//==============================================================================
procedure StatsWnd_Draw;
var
  w, sx, sy, sw, sh : integer;
  scl : single;
  Pat : PCrPat;
  str : string;
begin
  sw := 190;
  sh := 220;
  sx := StatsWnd.X - sw div 2;
  sy := StatsWnd.Y - sh div 2;
  if sy + sh > 600 then sy := 600 - sh;
  pr2d_Rect( sx, sy, sw, sh, $997755, 255, PR2D_FILL );
  pr2d_Rect( sx, sy, sw, sh, $333300, 255 );
  ssprite2d_Draw( NoiseTex, sx, sy, sw, sh, 0, 20 );

  scl := 0.6;
  Pat := StatsWnd.CrPat;
  if StatsWnd.Cr <> nil then Pat := StatsWnd.Cr.Pat;
  w := Round( text_GetWidth( Font, AnsiToUtf8( Pat.Name ) ) * scl );
  text_DrawEx( Font, StatsWnd.X - w div 2, sy + 15, scl, 0, AnsiToUtf8( Pat.Name ) );

  if StatsWnd.Cr = nil then
  begin
    w := Round( text_GetWidth( Font, u_IntToStr( Pat.Health ) ) * scl );
    text_DrawEx( Font, sx + 20, sy + 120, scl, 0, AnsiToUtf8( 'Здоровье:' ) );
    text_DrawEx( Font, sx + sw - 20 - w, sy + 120, scl, 0, u_IntToStr( Pat.Health ) );
  end else
  begin
    str := u_IntToStr( StatsWnd.Cr.Health ) + '/' + u_IntToStr( Pat.Health );
    w := Round( text_GetWidth( Font, str ) * scl );
    text_DrawEx( Font, sx + 20, sy + 120, scl, 0, AnsiToUtf8( 'Здоровье:' ) );
    text_DrawEx( Font, sx + sw - 20 - w, sy + 120, scl, 0, str );
  end;
  w := Round( text_GetWidth( Font, u_IntToStr( Pat.Damage ) ) * scl );
  text_DrawEx( Font, sx + 20, sy + 150, scl, 0, AnsiToUtf8( 'Урон:' ) );
  text_DrawEx( Font, sx + sw - 20 - w, sy + 150, scl, 0, u_IntToStr( Pat.Damage ) );
  w := Round( text_GetWidth( Font, u_IntToStr( Pat.Speed ) ) * scl );
  text_DrawEx( Font, sx + 20, sy + 180, scl, 0, AnsiToUtf8( 'Скорость:' ) );
  text_DrawEx( Font, sx + sw - 20 - w, sy + 180, scl, 0, u_IntToStr( Pat.Speed - 1 ) );

  StatsCrFace.CrPat := Pat;
  StatsCrFace.X := StatsWnd.X - 32;
  StatsCrFace.Y := sy + 46;
  BuyCrBtn_Draw( @StatsCrFace, False );
end;

//==============================================================================
function GmButton_Create( Name : string; X, Y, Width, Height : integer; Tex : zglPTexture; Caption : string = ''; Visible : boolean = True ): PGmButton;
var
  btn : PGmButton;
begin
  INC( GmButtonsCnt );
  SetLength( GmButtons, GmButtonsCnt );
  btn := @GmButtons[ GmButtonsCnt - 1 ];
  btn.Name    := Name;
  btn.X       := X;
  btn.Y       := Y;
  btn.Width   := Width;
  btn.Height  := Height;
  btn.Tex     := Tex;
  btn.Caption := Caption;
  btn.Visible := Visible;
  btn.Enabled := True;
  Result      := btn;
end;

//==============================================================================
procedure GmButton_Draw( btn : PGmButton );
var
  cx, cy, w : integer;
  scl : single;
  a : byte;
begin
  if btn.Visible = False then Exit;
  a := 255;
  if btn.Enabled = False then a := 100;
  scl := 0.6;

  if btn.Clicked = False then
  begin
    if btn.MouseOver then fx2d_SetVCA( $A0A07E, $A0A07E, $7E7E5C, $7E7E5C, 255, 255, 255, 255 )
      else fx2d_SetVCA( $999977, $999977, $777755, $777755, 255, 255, 255, 255 );
    pr2d_Rect( btn.X, btn.Y, btn.Width, btn.Height, $99AA99, 255, PR2D_FILL or FX2D_VCA );
    pr2d_Rect( btn.X, btn.Y, btn.Width, btn.Height, $333300, 255 );
    pr2d_Line( btn.X + 1, btn.Y + 1, btn.X + btn.Width - 1, btn.Y + 1, $BBBB99 );
    pr2d_Line( btn.X + 1, btn.Y + 1, btn.X + 1, btn.Y + btn.Height - 1, $BBBB99 );
    if btn.Tex <> nil then
    begin
      cx := btn.X + btn.Width div 2 - btn.Tex.Width div 2;
      cy := btn.Y + btn.Height div 2 - btn.Tex.Height div 2;
      ssprite2d_Draw( btn.Tex, cx, cy, btn.Tex.Width, btn.Tex.Height, 0, a );
    end;
    if btn.Caption <> '' then
    begin
      w  := Round( text_GetWidth( Font, AnsiToUtf8( btn.Caption ) ) * scl );
      cx := btn.X + btn.Width div 2 - w div 2;
      cy := btn.Y + btn.Height div 2 - 10;
      text_DrawEx( Font, cx, cy, scl, 0, AnsiToUtf8( btn.Caption ) );
    end;
  end else
  begin
    fx2d_SetVCA( $777755, $777755, $888867, $888867, 255, 255, 255, 255 );
    pr2d_Rect( btn.X, btn.Y, btn.Width, btn.Height, $99AA99, 255, PR2D_FILL or FX2D_VCA );
    pr2d_Rect( btn.X, btn.Y, btn.Width, btn.Height, $333300, 255 );
    pr2d_Line( btn.X + 1, btn.Y + 1, btn.X + btn.Width - 1, btn.Y + 1, $555533 );
    pr2d_Line( btn.X + 1, btn.Y + 1, btn.X + 1, btn.Y + btn.Height - 1, $555533 );
    if btn.Tex <> nil then
    begin
      cx := btn.X + btn.Width div 2 - btn.Tex.Width div 2 + 1;
      cy := btn.Y + btn.Height div 2 - btn.Tex.Height div 2 + 1;
      ssprite2d_Draw( btn.Tex, cx, cy, btn.Tex.Width, btn.Tex.Height, 0, a );
    end;
    if btn.Caption <> '' then
    begin
      w  := Round( text_GetWidth( Font, AnsiToUtf8( btn.Caption ) ) * scl );
      cx := btn.X + btn.Width div 2 - w div 2 + 1;
      cy := btn.Y + btn.Height div 2 - 10 + 1;
      text_DrawEx( Font, cx, cy, scl, 0, AnsiToUtf8( btn.Caption ) );
    end;
  end;
end;

//==============================================================================
function GmButton_Get( BName : string ): PGmButton;
var
  i : integer;
begin
  Result := nil;
  for i := 0 to GmButtonsCnt - 1 do
    if GmButtons[ i ].Name = BName then
    begin
      Result := @GmButtons[ i ];
      Exit;
    end;
end;

//==============================================================================
procedure GmButton_Click( btn : PGmButton );
begin
  if btn.Name = 'Exit' then zgl_Exit;
  if btn.Name = 'FScreen' then
  begin
    FullScr := not( FullScr );
    scr_SetOptions( 800, 600, REFRESH_MAXIMUM, FullScr, False );
    if FullScr then btn.Tex := FScrBtnTex2 else btn.Tex := FScrBtnTex;
  end;

  if btn.Name = 'New Game' then
  begin
    btn.Visible := False;
    GmButton_Get( 'Exit' ).Visible := False;
    GmButton_Get( 'FScreen' ).Visible := False;
    GmButton_Get( 'Fight' ).Visible := True;
    GameState := 'Shop';
    LevN := 1;
    Arena.LoadLev( '.\Data\Levels\Level1.lev' );
    Arena.StartLev;
    GmShopGUI_Init;
    if Arena.TextCnt > 0 then GmButton_Get( 'Close Text' ).Visible := True;
  end;

  if btn.Name = 'Close Text' then
  begin
    btn.Visible := False;
    ShowText := False;
  end;

  if btn.Name = 'Exit Yes' then zgl_Exit;
  if btn.Name = 'Exit No' then
  begin
    ExitConfirm := False;
    GmButton_Get( 'Exit Yes' ).Visible := False;
    GmButton_Get( 'Exit No' ).Visible := False;
  end;

  if btn.Name = 'End Turn' then
  begin
    if Selcr.PlayerN = 1 then Selcr.Pohodil := True;
  end;

  if btn.Name = 'Fight' then
  begin
    GmButton_Get( 'Close Text' ).Visible := False;
    GmButton_Get( 'End Turn' ).Visible := True;
    GameState := 'Fight';
    btn.Visible := False;
    SelCr := Arena.GetNextCr;
    if SelCr.PlayerN = 1 then CreateWave( SelCr.TX, SelCr.TY, SelCr.Pat.Speed, SelCr.Pat.CanFly );
  end;

  if btn.Name = 'Next' then
  begin
    INC( LevN );
    if file_Exists( '.\Data\Levels\Level' + u_IntToStr( LevN ) + '.lev' ) then
    begin
      Winner := 0;
      GmButton_Get( 'Next' ).Visible := False;
      GmButton_Get( 'End Turn' ).Visible := False;
      GmButton_Get( 'Fight' ).Visible := True;
      GameState := 'Shop';
      Arena.Free;
      Arena := TArena.Create;
      Arena.LoadLev( '.\Data\Levels\Level' + u_IntToStr( LevN ) + '.lev' );
      Arena.StartLev;
      GmShopGUI_Init;
      if Arena.TextCnt > 0 then GmButton_Get( 'Close Text' ).Visible := True;
      ShowText := True;
    end else btn.Visible := False;
  end;

  if btn.Name = 'Restart' then
  begin
    Winner := 0;
    GmButton_Get( 'Restart' ).Visible := False;
    GmButton_Get( 'End Turn' ).Visible := False;
    GmButton_Get( 'Fight' ).Visible := True;
    GameState := 'Shop';
    Arena.Free;
    Arena := TArena.Create;
    Arena.StartLev;
    if ShowText then
      if Arena.TextCnt > 0 then GmButton_Get( 'Close Text' ).Visible := True;
  end;
end;

//==============================================================================
procedure GmGUI_DrawText;
var
  i : integer;
begin
  pr2d_Rect( 400 - 210, 350, 420, 214, $997755, 255, PR2D_FILL );
  pr2d_Rect( 400 - 210, 350, 420, 214, $333300, 255 );
  ssprite2d_Draw( NoiseTex, 400 - 210, 350, 420, 214, 0, 10 );
  for i := 0 to Arena.TextCnt - 1 do
  begin
    text_DrawEx( Font, 190 + 10, 350 + 10 + i * 24, 0.6, 0, AnsiToUtf8( Arena.Text[ i ] ) );
  end;
end;

//==============================================================================
procedure GmGUI_Init;
begin
  bcbN  := -1;
  bcbDN := -1;
  StatsWnd.Visible := False;
  StatsCrFace.Width := 64;
  StatsCrFace.Height := 64;

  GmButton_Create( 'New Game', 400 - 90, 300, 180, 50, nil, 'Новая игра' );
  GmButton_Create( 'Exit', 400 - 90, 370, 180, 50, nil, 'Выход' );
  GmButton_Create( 'FScreen', 700, 520, 70, 58, FScrBtnTex );

  GmButton_Create( 'Close Text', 494, 514, 100, 36, nil, 'Закрыть', False );

  GmButton_Create( 'Exit Yes', 290, 310, 100, 36, nil, 'Да', False );
  GmButton_Create( 'Exit No', 410, 310, 100, 36, nil, 'Нет', False );

  GmButton_Create( 'Restart', 400 - 75, 390, 150, 42, nil, 'Заново', False );
  GmButton_Create( 'Next', 400 - 75, 390, 150, 42, nil, 'Продолжить', False );

  GmButton_Create( 'Fight', 700, 520, 74, 64, FightBtnTex, '', False );
  EndTurnBtn := GmButton_Create( 'End Turn', 700, 520, 74, 64, HourglassTex, '', False );
end;

//==============================================================================
procedure GmGUI_Draw;
var
  i, bx, by, w : integer;
begin
  if GameState = 'Main Menu' then
  begin
    pr2d_Rect( 0, 0, 800, 600, $99AA99, 255, PR2D_FILL ); 
    ssprite2d_Draw( TitleTex, 400 - 256, 20, 512, 256, 0 );
  end;

  if Winner = 1 then
  begin
    pr2d_Rect( 400 - 200, 180, 400, 280, $997755, 255, PR2D_FILL );
    pr2d_Rect( 400 - 200, 180, 400, 280, $333300, 255 );
    pr2d_Rect( 400 - 128 - 5, 240 - 5, 256 + 10, 128 + 10, $333300, 50, PR2D_FILL );
    ssprite2d_Draw( NoiseTex, 400 - 200, 180, 400, 280, 0, 10 );
    ssprite2d_Draw( WinTex, 400 - 128, 240, 256, 128, 0 );
    text_Draw( Font, 338, 192, AnsiToUtf8( 'Победа!' ) );
  end;
  if Winner = 2 then
  begin
    pr2d_Rect( 400 - 200, 180, 400, 280, $997755, 255, PR2D_FILL );
    pr2d_Rect( 400 - 200, 180, 400, 280, $333300, 255 );
    pr2d_Rect( 400 - 128 - 5, 240 - 5, 256 + 10, 128 + 10, $333300, 50, PR2D_FILL );
    ssprite2d_Draw( NoiseTex, 400 - 200, 180, 400, 280, 0, 10 );
    ssprite2d_Draw( DefeatTex, 400 - 128, 240, 256, 128, 0 );
    text_Draw( Font, 304, 192, AnsiToUtf8( 'Поражение!' ) );
  end;

  if GameState = 'Shop' then
  begin
    //------ рисуем денюжки -----------------------
    bx := 350;
    by := 20;
    fx2d_SetVCA( $777755, $777755, $999977, $999977, 255, 255, 255, 255 );
    pr2d_Rect( bx, by, 100, 35, $99AA99, 255, PR2D_FILL or FX2D_VCA );
    fx2d_SetVCA( $999977, $999977, $777755, $777755, 255, 255, 255, 255 );
    pr2d_Rect( bx, by + 35, 100, 35, $99AA99, 255, PR2D_FILL or FX2D_VCA );
    pr2d_Rect( bx, by, 100, 70, $333300, 255 );
    ssprite2d_Draw( GoldTex, bx + 16, by - 5, 64, 64, 0 );
    w := Round( text_GetWidth( Font2, u_IntToStr( Arena.Money ) ) );
    text_Draw( Font2, bx + 50 - w div 2, by + 52, u_IntToStr( Arena.Money ) );

    //------ рисуем иконки существ -----------------
    for i := 0 to BuyCrBtnCnt - 1 do
      BuyCrBtn_Draw( @BuyCrBtn[ i ] );

    //------ рисуем текст -----------------
    if ( Arena.TextCnt > 0 ) and ( ShowText ) then GmGUI_DrawText
  end;

  if ExitConfirm then
  begin
    pr2d_Rect( 400 - 200, 230, 400, 140, $997755, 255, PR2D_FILL );
    pr2d_Rect( 400 - 200, 230, 400, 140, $333300, 255 );
    ssprite2d_Draw( NoiseTex, 400 - 200, 230, 400, 140, 0, 10 );
    text_DrawEx( Font, 400 - 200 + 36, 270, 0.6, 0, AnsiToUtf8( 'Вы действительно хотите выйти?' ) );
  end;

  //------ рисуем кнопки -----------------------
  for i := 0 to GmButtonsCnt - 1 do
    GmButton_Draw( @GmButtons[ i ] );

  //----- рисуем окно статистики существа --------
  if StatsWnd.Visible then StatsWnd_Draw;

  //------ рисуем перетаскиваемую иконку ---------
  if bcbDN <> -1 then
  begin
    bx := BuyCrBtn[ bcbDN ].X;
    by := BuyCrBtn[ bcbDN ].Y;
    BuyCrBtn[ bcbDN ].X := Mouse_X - 32;
    BuyCrBtn[ bcbDN ].Y := Mouse_Y - 32;
    BuyCrBtn[ bcbDN ].MouseOver := True;
    BuyCrBtn_Draw( @BuyCrBtn[ bcbDN ], False );
    BuyCrBtn[ bcbDN ].MouseOver := False;
    BuyCrBtn[ bcbDN ].X := bx;
    BuyCrBtn[ bcbDN ].Y := by;
  end;

  //------ рисуем курсор -------------------
  if CurState = CUR_CURSOR then ssprite2d_Draw( CursorTex, Mouse_X - 8, Mouse_Y - 5, 32, 32, 0 );
  if CurState = CUR_WALK then ssprite2d_Draw( CWalkTex, Mouse_X - 32, Mouse_Y - 32, 64, 64, 0 );
  if CurState = CUR_FLY then ssprite2d_Draw( CWalkTex, Mouse_X - 32, Mouse_Y - 32, 64, 64, 0 );  
  if CurState = CUR_SHOOT then ssprite2d_Draw( CArrowTex, Mouse_X - 32, Mouse_Y - 32, 64, 64, 0 );

  if CurState = CUR_ATACK then
  begin
    if CurAng <> -1 then
      if ( CurAng = 0 ) or ( CurAng = 45 ) or ( CurAng = 315 ) then
        ssprite2d_Draw( CSwordTex, Mouse_X - 64, Mouse_Y - 64, 128, 128, CurAng, 255, FX_BLEND )
      else
        ssprite2d_Draw( CSwordTex, Mouse_X - 64, Mouse_Y - 64, 128, 128, CurAng, 255, FX_BLEND or FX2D_FLIPY );
  end;
end;

//==============================================================================
procedure GmGUI_Update;
var
  i, mx, my, tx, ty : integer;
  bool, p1HasCr : boolean;
begin
  mx := Mouse_X;
  my := Mouse_Y;

  if StatsWnd.Visible then
  begin
    mx := mxdwn;
    my := mydwn;
  end;

  for i := 0 to GmButtonsCnt - 1 do
    if GmButtons[ i ].Clicked then
    begin
      mx := mxdwn;
      my := mydwn;
    end;

  if Mouse_Click( M_BLEFT ) and not mouse_Down( M_BRIGHT ) then
  begin
    mxdwn := mx;
    mydwn := my;
  end;
  if Mouse_Click( M_BRIGHT ) and not mouse_Down( M_BLEFT ) then
  begin
    mxdwn := mx;
    mydwn := my;
  end;

  //------- тыкнули правой кнопкой мыши на существе -------------------
  if Mouse_Click( M_BRIGHT ) and not mouse_Down( M_BLEFT ) then
  begin
    GetPickedHex( mx, my, tx, ty );
    for i := 0 to Arena.CreaturesCnt - 1 do
      if Arena.Creatures[ i ].State <> CS_DIE then
        if ( Arena.Creatures[ i ].TX = tx ) and ( Arena.Creatures[ i ].TY = ty ) then
        begin
          StatsWnd.Cr      := Arena.Creatures[ i ];
          StatsWnd.CrPat   := nil;
          StatsWnd.X       := mx;
          StatsWnd.Y       := my;
          StatsWnd.Visible := True;
          Break;
        end;
  end;

  //------ если правая кнопка не нажата то скрываем окно статистики ------------
  if ( StatsWnd.Visible ) and not mouse_Down( M_BRIGHT ) then
  begin
    StatsWnd.Visible  := False;
    StatsWnd.CrPat    := nil;
    StatsWnd.Cr       := nil;
  end;

  //------ обрабатывае кнопки --------
  for i := 0 to GmButtonsCnt - 1 do
    with GmButtons[ i ] do
      if Visible and Enabled then
      begin
        MouseOver := ( ( mx > X ) and ( my > Y ) and ( mx < X + Width ) and ( my < Y + Height ) );
        if bcbDN <> -1 then MouseOver := False;
        if Clicked and not mouse_Down( M_BLEFT ) then
        begin
          if ( Mouse_X > X ) and ( Mouse_Y > Y ) and ( Mouse_X < X + Width ) and ( Mouse_Y < Y + Height ) then GmButton_Click( @GmButtons[ i ] );
          Clicked := False;
        end;
        if MouseOver then
          if Mouse_Click( M_BLEFT ) and not mouse_Down( M_BRIGHT ) then Clicked := True;
      end;

  if GameState = 'Shop' then
  begin
    p1HasCr := False;
    for i := 0 to Arena.CreaturesCnt - 1 do
      if Arena.Creatures[ i ].PlayerN = 1 then p1HasCr := True;
    for i := 0 to GmButtonsCnt - 1 do
      if GmButtons[ i ].Name = 'Fight' then GmButtons[ i ].Enabled := p1HasCr;

    //------ находится ли курсор над иконкой существа --------
    for i := 0 to BuyCrBtnCnt - 1 do
      with BuyCrBtn[ i ] do
      begin
        MouseOver := ( ( mx > X ) and ( my > Y ) and ( mx < X + Width ) and ( my < Y + Height ) );
        if BuyCrBtn[ i ].CrPat.Cost > Arena.Money then MouseOver := False;
        if bcbDN <> -1 then MouseOver := False;
      end;

    //------ тыкнули левую кнопку мыши ---------------
    if Mouse_Click( M_BLEFT ) and not mouse_Down( M_BRIGHT ) then
    begin
      bcbN := -1;
      for i := 0 to BuyCrBtnCnt - 1 do
        if BuyCrBtn[ i ].MouseOver then bcbN := i;
    end;

    //------ тыкнули правой кнопкой мыши на иконке существа ---------------
    if Mouse_Click( M_BRIGHT ) and not mouse_Down( M_BLEFT ) then
    begin
      for i := 0 to BuyCrBtnCnt - 1 do
        with BuyCrBtn[ i ] do
          if ( mx > X ) and ( my > Y ) and ( mx < X + Width ) and ( my < Y + Height ) then
          begin
            StatsWnd.Cr      := nil;
            StatsWnd.CrPat   := BuyCrBtn[ i ].CrPat;
            StatsWnd.X       := mx;
            StatsWnd.Y       := my;
            StatsWnd.Visible := True;
          end;
    end;

    //------ начинаем таскать иконку существа ---------------
    if ( bcbN <> -1 ) and ( ( ABS( mxdwn - mx ) > 3 ) or ( ABS( mydwn - my ) > 3 ) ) then
    begin
      bcbDN := bcbN;
      bcbN  := -1;
    end;

    //------ кликнули на иконку существа или перетащили ее на клетку -----------
    if mouse_Down( M_BLEFT ) = False then
    begin
      if bcbN <> -1 then
      begin
        for i := 0 to BuyCrBtnCnt - 1 do
          if ( BuyCrBtn[ i ].MouseOver ) and ( i = bcbN ) then
          begin
            ty := GetFreeTileY;
            if ty <> -1 then
              with Arena do
              begin
                INC( CreaturesCnt );
                SetLength( Creatures, CreaturesCnt );
                Creatures[ CreaturesCnt - 1 ] := TCreature.Create( 0, ty, BuyCrBtn[ bcbN ].CrPat, 1 );
                Arena.Money := Arena.Money - BuyCrBtn[ bcbN ].CrPat.Cost;
              end;
            Break;
          end;
        bcbN := -1;
      end;
      if bcbDN <> -1 then
      begin
        GetPickedHex( mx, my, tx, ty );
        if ( tx = 0 ) and ( ty >= 0 ) and ( ty <= 8 ) then
        begin
          bool := True;
          for i := 0 to Arena.CreaturesCnt - 1 do
            if ( Arena.Creatures[ i ].TX = tx ) and ( Arena.Creatures[ i ].TY = ty ) then
            begin
              bool := False;
              Break;
            end;
          if bool = True then
            with Arena do
            begin
              INC( CreaturesCnt );
              SetLength( Creatures, CreaturesCnt );
              Creatures[ CreaturesCnt - 1 ] := TCreature.Create( tx, ty, BuyCrBtn[ bcbDN ].CrPat, 1 );
              Arena.Money := Arena.Money - BuyCrBtn[ bcbDN ].CrPat.Cost;
            end;
        end;
        bcbDN := -1;
      end;
    end;
  end;
end;

//==============================================================================
procedure GmShopGUI_Init;
var
  i, h : integer;
begin
  BuyCrBtnCnt := Arena.BuyCrCnt;
  SetLength( BuyCrBtn, BuyCrBtnCnt );
  h := BuyCrBtnCnt * 70;
  for i := 0 to BuyCrBtnCnt - 1 do
  begin
    BuyCrBtn[ i ].X       := 800 div 2 - h div 2 + i * 70;
    BuyCrBtn[ i ].Y       := 110;
    BuyCrBtn[ i ].Width   := 64;
    BuyCrBtn[ i ].Height  := 64;
    BuyCrBtn[ i ].CrPat   := Arena.BuyCr[ i ];
  end;
end;

end.
