/**********************************************************************
 *
 *   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_PARTY_HEADER
#define CLASS_PARTY_HEADER

#include "../basistypes.h"
#include "../exception.h"

#include "../player/player.h"
class Rule;
class GamePointsTable;
class GameSummary;

class Party {
  friend class Game;
  public:

  Party();
  ~Party();

  vector<Player*>& players();
  Player& player(unsigned const p);
  Player const& player(unsigned const p) const;
  void set_player(Player* player, unsigned const n);
  Player* switch_player(Player* player, unsigned const n);
  void switch_players(unsigned const n0, unsigned const n1);
  unsigned playerno() const;
  // number of human players
  unsigned humanno() const;

  void set_playername(unsigned const player_no, string const& new_name);
  void set_playertype(unsigned const player_no,
		      Player::Type const new_type);

  void set_random_seed_first();
  void set_seed(unsigned const seed_new);
  void set_random_seed();
  unsigned seed_next();

  void set_random_startplayer_first();

  unsigned roundno() const;
  unsigned remaining_rounds() const;
  unsigned gameno() const;


  bool starts_new_round(unsigned const gameno) const;
  unsigned round_of_game(unsigned const gameno) const;
  unsigned round_startgame(unsigned const roundno) const;

  GameSummary const& last_game_summary() const;
  GameSummary const& game_summary(unsigned const gameno) const;
  int pointsum() const;
  int pointsum_till_game(unsigned const gameno) const;
  int pointsum_till_round(unsigned const roundno) const;
  int pointsum_in_round(unsigned const roundno) const;
  int pointsum(Player const& player) const;
  int pointsum(unsigned const playerno) const;
  int pointsum_till_game(unsigned const gameno, unsigned const playerno) const;
  int pointsum_till_round(unsigned const roundno, unsigned const playerno) const;
  int pointsum_in_round(unsigned const roundno, unsigned const playerno) const;

  unsigned rang(unsigned const playerno) const;
  unsigned rang(Player const& player) const;
  unsigned lustsolo_games(unsigned const playerno) const;
  unsigned lustsolo_games(Player const& player) const;


  bool write(ostream& ostr) const;
  bool read(istream& istr) throw (ReadException);

  bool save(string const& filename) const;
  bool load(string const& filename) throw (ReadException);



  void open();
  void init();
  void play();
  void close();


  private:
  bool auto_save() const;
  public:
  void remove_auto_save() const;
  void save_changes() const;

  private:
  void increment_round();

  private:
  PRIV_VAR_P_RW(Rule, rule); // rules for the party

  PRIV_VAR_R(vector<Player*>, players); // players

  PRIV_VAR_RW(unsigned, seed_first); // starting random seed
  PRIV_VAR_RW(unsigned, startplayer_first); // starting startplayer
  PRIV_VAR_R(unsigned, real_seed_first); // real starting random seed
  PRIV_VAR_R(unsigned, real_startplayer_first); // real starting startplayer
  // the game in which the round starts
  PRIV_VAR_R(vector<unsigned>, round_startgame);

  PRIV_VAR_P_RW(Game, game); // current game

  PRIV_VAR_R(unsigned, seed); // random seed
  PRIV_VAR_R(unsigned, startplayer); // startplayer


  PRIV_VAR_R(vector<GameSummary*>, game_summaries); // game summaries

  // set_ai_players
  // partie typ (tutorial...)
  // pflichtstsoli
  // punkte topf
  // tunier status

  private: // not to be used
  Party(Party const&);
  Party& operator=(Party const&);
}; // class Party

ostream& operator<<(ostream& ostr, Party const& p);

extern Party party;

#endif // #ifdef CLASS_PARTY_HEADER
