// Copyright 1994, 1995 by Jon Dart.  All Rights Reserved.

#ifndef _LOG_H
#define _LOG_H

#include "board.h"
#include "rmove.h"
#include "search.h"
#include <fstream.h>
#ifndef __AFXCOLL_H__
#include <afxcoll.h>
#endif

enum { Initial_Log_Size = 100 };  // initial log size
                                  // (expandable if necessary)

class Log;

class Log_Entry
{
     // Maintains info on a move made so far in the game.            

     public:

     Log_Entry(const ReversibleMove &move,
               const char *move_image);
     // create a log entry. 
     // "move_image" is the string representation of the move.
             
     Log_Entry();
     // create a null log entry.  Used only to initialize storage.
             
     ~Log_Entry();
     
     const ReversibleMove &move() const
     {
         return my_move;
     }
     
     const char *image() const
     {
         return (const char *)my_image;
     }
     
     const char *result() const
     {
         return (const char *)my_result;
     }
     
     void setResult( const char *result)
     {
         my_result = result;
     }
     
     int operator == ( const Log_Entry &l ) const;
     int operator != ( const Log_Entry &l ) const;

     private:
             
     ReversibleMove my_move;
     CString my_image;
     CString my_result;
};

class Log
{
     // maintains a log of moves made in the game so far.  Unlike the
     // Move_Array (see movearr.h), moves are not added and removed
     // during the search process.  The log maintains a size, which
     // is the total number of moves ever added, and a current position,
     // which is normally == to its size, but may be less if the
     // user has "taken back" moves.

     public:         
        
     Log();
     // create a log.
             
     virtual ~Log();         

     void add_move( Board &board,
                    const ReversibleMove &emove,
                    const char *move_image,
                    const Search::Statistics *stats,
                    const BOOL toFile);
     // Add a move to the log.  If "toFile" is true, also record it
     // in the log file.  This is called before the move has been
     // made.
             
     void remove_move();
     // remove the most recently added move to the log.
             
     // Return the number of the last move made.  "Backing up"
     // through the moves changes current w/o changing num_moves.        
     unsigned current() const
     {
             return my_current;
     }
     
     const Log_Entry &operator[](int n) const
     {
             return *((Log_Entry*)contents[n]);
     }

     // Return the total number of moves made.
     unsigned num_moves() const
     {
         return contents.GetSize();
     }
     
     // Advance the "current" move by one.
     BOOL back_up();
     
     // Decrement the "current" move pointer.
     BOOL go_forward();
     
     // Reset the "current" position to the start of the game, w/o
     // altering the file or clearing the log.    
     void reset();
     
     const ReversibleMove &last_move() const;
     // return the last move in the log.  The log must be non-empty.

     const ReversibleMove &move( const unsigned n ) const;
     // return the nth move in the log.  0 <= n <= num_moves - 1.
        
     void clear();
     // remove everything from the log
             
     void write_header();

     void write(const char *);

     void write_eol();
     
     void setResult(const char *result);
     
     const char *getResult() const;
             
private:
     CPtrArray contents;
     void flush();
     int my_current;
     ofstream log_file;     
     char buf[128];
};

#endif

