// -*- c++ -*-
#ifndef _PLAYER_H
#define _PLAYER_H

#include "list.h"
#include "rules.h"
#include "mytypes.h"
#include "coord.h"

class MsgQ;
class Unit;
class City;
class CPixmap;

class Player
{
public:
  Player(char *Name, int Id);
  ~Player();

  char *name;
  char *title();

  char color1Str[40], color2Str[40]; // for fast color switching
  int id;
  List<ulong> citys;
  List<ulong> units;

  CPixmap *cityPic; // city pic
  City *capital;

  int govt; // government type
  ulong embassies;
  int CanAttack(int Id);

  int tax;
  // MarkM added luxuries rate:
  int luxuries;
  int money;

  int scienceAcc;
  int needScience;

  Science researching;
  ScienceList discovered;

  int TempleEffect()
  {if (!HasDiscovered(MYSTICISM)) return 1; return (HasWonder(ORACLE) && !Objects[ORACLE].isObsolete) ? 4 : 2;}

  int CathedralEffect() 
  {return (HasWonder(MICHELANGELO) && !Objects[MICHELANGELO].isObsolete) ? 6 : 4;}

  int SeaMoveBonus()
  {return (HasWonder(MAGELLAN) || (HasWonder(LIGHTHOUSE) && !Objects[LIGHTHOUSE].isObsolete)) ? 1 : 0;}

  int TradeBonus()
  {return (HasWonder(COLOSSUS) && !Objects[COLOSSUS].isObsolete) ? 1 : 0;};

  List<charp> messages; // any messages we want to show in city turn
  void ShowMessages();

  // create the first unit and start up the player, will also send
  // out the info for this unit to all other players
  void Setup();

  // send all the moves we made in this turn
  void SendMoves(MsgQ *);

  // get all moves a remote player made
  void ShowMoves(MsgQ *, MsgQ *outQ, int MoverId);

  void InitMoveTurn();
  void MoveTurnMesg(MsgQ *);

  void InitCityTurn();
  void CityTurnMesg(MsgQ *);

  void UpdateCities();

  int HasWonder(BuildObject name) {return wonders.Contains(name);}
  void InsertWonder(BuildObject name) {wonders.Insert(name);}
  void DeleteWonder(BuildObject name) {wonders.Delete(name);}

  int HasDiscovered(Science name) {return discovered.Contains(name);}
  void Discover(Science name);

  int HasEmbassy(int playerId) {return embassies & (1 << playerId);}
  void MakeEmbassy(int playerId){embassies |= (1 << playerId);}

  int FoodUsedPerSettler() {return govt < MONARCH ? 1 : 2;}
  int UnhappyPerUnitAway();
  void Save();  // saves everything to save file
  void Restore(); // restore from save file

  //private:
  typedef enum { SCIENCE, TAX_RATE, LUXURY_RATE, REVOLUTION, GOVERNMENT_TYPE, 
		 CARAVAN_MOVE, DIPLOMAT_MOVE, TREATY_OFFER, WAR_DECL
               } SelectingType;
  SelectingType selecting;

  WonderList wonders;
  TreatyStatus *treaties;

  int initiatedSave; // if save initiated

  MsgQ *unDispQ; // undisplayed moves
  int doneMoving; // true if he's told us he's done moving
  int acks_left; // number of acks remaining
  int accepts_left; // number of accepts outstanding

  Unit *currUnit; // currently selected unit
  int diplomacyId; // who we're currently talking to

  City *FindCityWithMsg();
  void ChooseGovernment();
  void ChooseScience();
  void ChooseRevolution();
  void ChooseTaxRate();
  void ChooseLuxRate();
  void ChooseBuy();
  void ChooseBuild();
  void AskForAccept();
  void AcceptMoves();
  void SelectEvent(char *data);
  void WakeUnit(Unit *ptr);
  void AttackMove(City *destCity, MapCoord newCoord);
  void NonAttackMove(City *destCity, MapCoord newCoord);
  void NextUnit();
  void MoveCurrUnit(int key);
  void UnitOrders(int key);
  void CheckCurrUnit();
  void WakeUnits(MapCoord c);
  void InitiateSave();
};

typedef Player *PlayerP;

#endif
