/*
  This file is part of CardWords.
  (C) 1999 Tobias Peters

  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 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
*/

// cardwords_playerlist.hh

// The class CardWords_PlayerList can be used by CardWords_Clients.
// It takes messages from the CardWords_server regarding the Players.
// parses that info and gives access to it.

#ifndef CARDWORDS_PLAYERLIST_HH
#define CARDWORDS_PLAYERLIST_HH

#include "charpointer.hh"
#include <vector>
#include "cardwords_exceptions.hh"
#include <iostream.h>

class CardWords_PlayerList {
public:

  CardWords_PlayerList (constCharPointer logged_players_message);

  constCharPointer
  get_name(size_t pos) const;
  
  // The positions of the players change when the game starts!
  size_t
  get_pos(constCharPointer name) const;

  bool
  is_robot(size_t pos) const;
  bool
  is_robot(constCharPointer name) const {return is_robot(get_pos(name));}

  size_t
  get_no_of_cards_of(size_t pos) const;
  size_t
  get_no_of_cards_of(constCharPointer name) const
    {return get_no_of_cards_of(get_pos(name));}

  int
  get_points_of(size_t pos) const;
  int
  get_points_of(constCharPointer name) const
    {return get_points_of(get_pos(name));}
  int
  get_last_points_of(size_t pos) const;
  int
  get_last_points_of(constCharPointer name) const
    {return get_points_of(get_pos(name));}
  
  bool
  is_game_running(void) const;

  void
  game_starts(constCharPointer starting_message);

  void
  update_info(constCharPointer logged_players_message);

  void
  set_last_points_of(size_t pos, int last_points);
  void
  set_last_points_of(constCharPointer name, int last_points)
    {set_last_points_of(get_pos(name), last_points);}

  size_t
  size(void) const; // the number of players

  size_t
  get_no_of_robots(void) const;

  size_t
  get_no_of_remote_participants(void) const
    {return size() - get_no_of_robots();}

  size_t
  get_active_player_pos(void) const;

  constCharPointer
  get_active_player_name(void) const
    {return get_name(get_active_player_pos());}

  void
  set_active_player(constCharPointer go_of_message);
  
private:
  struct Player {
  public:
    constCharPointer name;
    bool             robot;
    size_t           no_of_cards;
    int              points;
    int              last_points;
    Player(constCharPointer n, bool r, size_t t, int p, int l = 0)
      : robot(r), no_of_cards(t), points(p), last_points(l)
      {
        name = strdup(n);
        if(name == 0)
        {throw CardWords_XLowResources(gettext("CardWords_PlayerList::Player"\
                                             "::Player(..): Out of memory"));
        }
      }
    Player(const Player & p)
      : robot(p.robot), no_of_cards(p.no_of_cards), points(p.points),
        last_points(p.last_points)
      {
        name = strdup(p.name);
        if(name == 0)
          {throw CardWords_XLowResources(gettext("CardWords_PlayerList::"\
                                                 "Player::Player(): "\
                                                 "Out of memory"));
          }
      }
    Player & operator = (const Player & p)
      {
        robot = p.robot; no_of_cards = p.no_of_cards; points = p.points;
        last_points = p.last_points;
        if (name != 0) free(name);
        name = strdup(p.name);
        if(name == 0)
          {throw CardWords_XLowResources(gettext("CardWords_PlayerList::"\
                                                 "Player::operator=: "\
                                                 "Out of memory"));
        }
        return *this;
      }
    ~Player() {if (name != 0) free(name);}
  };
  vector<Player> players;
  size_t no_of_robots;
  size_t active_player_pos;
  bool game_running;
};

ostream &
operator << (ostream &, const CardWords_PlayerList &);

inline ostream &
operator << (ostream & ostr, const CardWords_PlayerList *kplp)
{
  return ostr << *kplp;
}
#endif

