{
    This file is part of Langton's Ant
    Copyright (c) 2002 by Ian Hickson

    A graphical implementation of Langton's Ant

    See the file COPYING, included in this distribution,
    for details about the copyright.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 **********************************************************************}
{$MODE OBJFPC}
program Graphical; // See also Text

{$ifdef Win32}
 {$apptype GUI}
{$endif}

uses
  {$ifdef Win32}
   WinCrt,
   Windows,
  {$endif}
  DOS,
  Graph,
  SysUtils,
  LangtonAnt,
  Scenarios;

type
  TGraphicalAnt = class (TAnt)
  protected
    procedure SetPixel(aState: Boolean); override;
    function GetPixel: Boolean; override;
    function InRange: Boolean; override;
  end;

  TGraphicalAntFarm = class (TAntFarm)
    function Stop: Boolean; override;
    function Width: Integer; override;
    function Height: Integer; override;
  end;

var
   MaxWidth, MaxHeight, MaxColor, White, Black: Integer;

    procedure TGraphicalAnt.SetPixel(aState: Boolean);
    begin
       if aState then
          PutPixel(FX, FY, White)
       else
          PutPixel(FX, FY, Black);
    end;

    function TGraphicalAnt.GetPixel: Boolean;
    begin
       Result := Graph.GetPixel(FX, FY) = White;
    end;

    function TGraphicalAnt.InRange: Boolean;
    begin
       // keep the ant within a circle one third
       // of the height of the viewport
       Result := ((FAntFarm.Width div 2) - FX) ** 2 +
                 ((FAntFarm.Height div 2) - FY) ** 2 <
                     (FAntFarm.Height div 6) ** 2;
    end;

    function TGraphicalAntFarm.Stop: Boolean;
    begin
       Result := Keypressed;
    end;

    function TGraphicalAntFarm.Width: Integer;
    begin
       Result := MaxWidth;
    end;

    function TGraphicalAntFarm.Height: Integer;
    begin
       Result := MaxHeight;
    end;

var
  gDriver, gmLow, gmHigh: SmallInt;
  Farm: TAntFarm;
  Time: Integer;
begin
  gDriver := Detect;
  GetModeRange(gDriver, gmLow, gmHigh);
  {$ifdef Win32}
   ShowWindow(GetActiveWindow, 0);
  {$endif}
  InitGraph(gDriver, gmHigh, '');
  if GraphResult <> grOk then
  begin
     Writeln('Graph driver ', gDriver, ' graph mode ', gmHigh, ' not supported');
     Halt(1);
  end;
  MaxWidth := GetMaxX;
  MaxHeight := GetMaxY;
  MaxColor := GetMaxColor - 1;
  Black := 7 * MaxColor div 32; // hack
  White := 12 * MaxColor div 32; // hack
  Farm := TGraphicalAntFarm.Create(TGraphicalAnt);
  repeat
    ClearViewport;
    Time := Scenarios.RunLangtonsAnt(Farm);
    OutTextXY(10, 10, 't = ' + IntToStr(Time));
    while keypressed do readkey;
  until readkey <> ' ';
  Farm.Destroy;
  CloseGraph;
end.

