/**********************************************************************
 *
 *   FreeDoko a Doppelkopf-Game
 *    
 *   Copyright (C) 2001-2006  by Diether Knof and Borg Enders
 *
 *   This program is free software; you can redistribute it and/or 
 *   modify it under the terms of the GNU General Public License as 
 *   published by the Free Software Foundation; either version 2 of 
 *   the License, or (at your option) any later version.
 *
 *   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.  See the
 *   GNU General Public License for more details. 
 *   You can find this license in the file 'gpl.txt'.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
 *   MA  02111-1307  USA
 *
 *  Contact:
 *    Diether Knof dknof@gmx.de
 *    Borg Enders  borg@borgsoft.de
 *
 **********************************************************************/

#ifndef CLASS_OS_BUG_REPORT_REPLAY_HEADER
#define CLASS_OS_BUG_REPORT_REPLAY_HEADER

#include "os.h"
#include "../game/gameplay.h"
#include "../card/hand.h"
#include "../card/trick.h"
#include "../party/party.h"
#include "../party/rule.h"
#include "../game/game.h"
#include "../game/game_summary.h"

#include "../basistypes.h"
#include "../utils/version.h"

class GameplayAction;

namespace OS_NS {

  /**
   **
   ** A class to simplify the replay of the bug report.
   ** All info's from the bug report are used and differences to the
   ** gameplay are shown.
   **
   ** Parts of the bug report:
   ** - version		is printed
   ** - system		is printed
   ** - date		is printed
   ** - message		is printed
   ** - seed		is set
   ** - startplayer	is set
   ** - ruleset		is set, differences to the standard ruleset and
   **				the default are printed
   ** - players		are set, differences to the standard aiconfig
   **				 are printed
   ** - hands		are checked
   **			* marriage: bridge is checked
   ** - gametype		is checked
   **			* marriage: bridge is checked
   **			* poverty: shifted cards are checked
   **
   **
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   ** @todo	poverty
   ** @todo	marriage
   ** @todo	automatic announcements for the player
   **
   **/
  class BugReportReplay : public OS {
    public:
      // Konstruktor with the filename of the bugreport
      BugReportReplay(string const& filename);
      ~BugReportReplay();

      // write the data of this bug report into 'ostr'
      void write(ostream& ostr) const;

      // this bug report is inconsistent
      void inconsistent();


      // returns the keyword from the line read
      string keyword() const;
      // returns the value from the line read
      string value() const;

      // 'line' is expected -- test the current line
      bool line_expect(string const& line);
      // 'keyword' is expected -- test the current line
      bool keyword_expect(string const& keyword);
      // 'value' is expected -- test the current line
      bool value_expect(string const& value);

      // returns the keyword from the human line read
      string keyword_human() const;
      // returns the value from the human line read
      string value_human() const;

      // reads the first lines of the file
      void read_first_lines();
      // test, whether this is the end of the bug report
      bool test_for_end();
      // the bug report is finished
      void finished();

      // the parts of a party
      void party_open(Party const& party);
      void party_get_settings();
      void party_close();

      // the parts of a game
      void game_open(Game const& game);
      void game_start();

      void trick_open(Trick const& trick);
      void trick_full();

      // get a card
      void card_get(Player const& player);
      // the card is played
      void card_played(HandCard const& card);
      // test, whether there is an announcement and make it, if the player
      // is human
      bool test_for_announcement();
      // an announcement is made
      void announcement_made(Announcement const& announcement,
				     Player const& player);
      // the player has swines
      void swines_announced(Player const& player);
      // the player has hyperswines
      void hyperswines_announced(Player const& player);

      // 'player' shifts 'cardno' cards
      void poverty_shift(Player const& player, unsigned const cardno);
      // ask 'player' whether to accept the poverty
      void poverty_ask(Player const& player,
			       unsigned const cardno);
      // all players have denied to take the cards
      void poverty_take_denied_by_all();
      // the player 'player' has accepted the poverty trumps
      // and has returned 'cardno' cards with 'trumpno' trumps
      void poverty_take_accepted(Player const& player,
					 unsigned const cardno,
					 unsigned const trumpno);
      // the player selects a partner
      void genscher_partner();
      // a player has announced a genscher
      void genscher(Player const& genscher, Player const& partner);


      // returns the next card played by the player
      HandCard next_card(Player const& player) const;

    private:
      // reads the whole file
      void read_file();

    public:
      // the filename of the bugreport
      string const filename;
      // the input stream for the bug report (for the gameplay)
      istream* istr;
      // the last read line (for the gameplay)
      string line;
      // the input stream for the bug report (for the human)
      istream* istr_human;
      // the last read line (for the human)
      string line_human;


      // the version
      DK::Utils::Version* version;
      // the date of the compilation
      string compiled;
      // the system
      string system;
      // the time the bug report was created
      string time;
      // the language
      string language;
      // the trick of the bug report
      unsigned trickno;
      // the mesage
      string message;
      // the seed
      unsigned seed;
      // the number of the startplayer
      unsigned startplayer_no;
      // the gametype
      ::GameType game_type;
      // the marriage selector
      ::MarriageSelector marriage_selector;
      // the number of the soloplayer
      unsigned soloplayer_no;

      // the rule
      ::Rule rule;
      // the players
      vector< ::Player*> players;
      // poverty cards
      ::HandCards* poverty_cards_shifted;
      ::HandCards* poverty_cards_returned;
      // hands
      vector< ::Hand> hands;
      // the number of the player with swines
      unsigned swines_player_no;
      // the number of the player with hyperswines
      unsigned hyperswines_player_no;
      // gameplay
      vector< ::GameplayAction*> actions;
      
      // full tricks
      vector< ::Trick> full_tricks;
      // game summary
      ::GameSummary* game_summary;

      // current hands
      vector< ::Hand> current_hands;
      // current trick
      ::Trick* current_trick;
      // human actions
      vector< ::GameplayAction*> human_actions;

    private: // not implemented
      BugReportReplay();
      BugReportReplay(BugReportReplay const&);
      BugReportReplay& operator=(BugReportReplay const&);
  }; // class BugReportReplay

} // namespace OS_NS

#endif // #ifndef CLASS_OS_BUG_REPORT_REPLAY_HEADER
