
{$ASSERTIONS ON}

uses
  SysUtils, Classes, StrUtils, IoUtils, PgnRead, ChessGame;

const
  CSample = 'files/sample.pgn';
  CStartPosition = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';
  
var
  LList: TList;
  LGameIdx, LTagIdx, LMoveIdx: integer;
  LGroupIdx: TGroupIndex;
  LGroups: PGroups;
  LFilename: string;
  LTime: TDateTime;
  LGame: TChessGame;
  LMove: string;
  LStartPosition: string;
  
begin
  if ParamCount >= 1 then
    LFilename := ParamStr(1)
  else
    LFilename := CSample;
  Assert(FileExists(LFilename));
  
  LTime := Time;
  LList := ParsePgnText(TFile.ReadAllText(LFilename));
  WriteLn('Time elapsed ', FormatDateTime('nn:ss,zzz', Time - LTime));
  WriteLn('LList.Count ', LList.Count);
  
  for LGameIdx := 0 to Pred(LList.Count) do
  begin
    WriteLn('LGameIdx=', LGameIdx);
    
    with TGameData(LList[LGameIdx]) do
    begin
      LStartPosition := FTags.Values['FEN'];
      if Length(LStartPosition) = 0 then
        LStartPosition := CStartPosition;
      
      LGame := TChessGame.Create(LStartPosition);
      
      for LTagIdx := 0 to Pred(FTags.Count) do
        WriteLn(
          'TAG ',
          FTags.Names[LTagIdx], '=',
          FTags.ValueFromIndex[LTagIdx]
        );
      
      for LMoveIdx := 0 to Pred(FMoves.Count) do
      begin
        LGroups := FMoves[LMoveIdx];
        (*
        for LGroupIdx := Low(TGroupIndex) to High(TGroupIndex) do
          Write(LGroups^[LGroupIdx], ',');
        WriteLn;
        WriteLn(LGame.CurrPosToStr());
        *)
        
        LMove := EmptyStr;
        for LGroupIdx := Low(TGroupIndex) to High(TGroupIndex) do
          LMove := Concat(LMove, LGroups^[LGroupIdx]);
        
        WriteLn('LMove=', LMove);
        WriteLn(LGame.CurrPosToStr());
        
        with LGame do
          if IsLegal(LMove) then
            DoMove(LMove)
          else
          begin
            WriteLn('ERR illegal move "', LMove, '" LGameIdx ', LGameIdx, ' LMoveIdx ', LMoveIdx);
            //WriteLn(LegalMoves);
            //WriteLn(CurrPosToStr());
            Flush(Output);
            Break;
          end;
      end;
      
      LGame.Free;
      
      WriteLn(FTermination);
    end;
  end;
  
  for LGameIdx := Pred(LList.Count) downto 0 do
    TGameData(LList[LGameIdx]).Free;
  LList.Free;
end.
