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

#include "list.h"
#include "global.h"
#include "player.h"
#include "coord.h"

// MarkM added FREE_CONTENTED for civil-disorder code.
// it specifies how many contented folk you get free per city
// before having to *make* them content/happy somehow.
const int FREE_CONTENTED = 2;
const int CITY_VISIBILITY = 1;
const int MAX_POPULATION = 30; // used for display purposes only (63 theoretical limit)

class MsgQ;
class MapDisplay;
class CityDisplay;

typedef List<charp> StrList;

class City
{
public:
  City(char *Name, ulong Id, MapCoord where, uchar OwnerId);
  City(); // read from save file
  ~City();

  // do end of turn update for this city
  // fails if the city dies
  int Update();

  // Draw city on a map
  void Draw(WDisplay *window);

  ulong id;
  char *name;
  MapCoord coord;
  uchar ownerId;

  List<ulong> units;
  // the next two functions are called by Unit constructor/destructors
  // should only be needed for changing units' home cities otherwise
  void AddUnit(int id, BuildObject type);
  void RemoveUnit(int id, BuildObject type);
  void KillAllUnits(); // when a city dies all supported units are lost

  int size;
  int working, elvi, goondas, happy, taxmen, scientists;
  int LoveTheRuler;
  int disordered() {return (goondas > happy);}

  BuildObject building;
  int accProd;
  int needProd() {return Objects[building].prodCost;}
  int BuyCost() {return int((needProd() - accProd)*2.5);}

  List<charp> messages; // messages to show for this city

  void AddBuilding(BuildObject b);
  void DeleteBuilding(BuildObject b);
  int HasBuilding(BuildObject b);

  void Save();

  void Capture(int capturerId, MsgQ *q, MapDisplay *display = MainMap);

  // returns a list of things we can build
  StrList CanBuild();
  void WorkOn(BuildObject what) {building = what;} // what we should work on

  CityDisplay* Show();
  void InfoScreen(CityDisplay *window); // draws the whole info screen
  void InfoScreen();

  // functions to draw various components, call them if you update
  // any of the city variables
  void SetDisplay(CityDisplay *w);
  void DrawBasic();
  void DrawCityMap();
  void ShowPeople();
  void ShowEcon();
  void ShowFood();
  void ShowOwnUnits();
  void ShowStationedUnits();
  void ShowWorkInProg();
  void ShowBuildings();
  void ShowSmokeStacks();

  void DrawBasic(CityDisplay *window);
  void DrawCityMap(CityDisplay *window);
  void ShowPeople(CityDisplay *window);
  void ShowEcon(CityDisplay *window);
  void ShowFood(CityDisplay *window);
  void ShowOwnUnits(CityDisplay *window);
  void ShowStationedUnits(CityDisplay *window);
  void ShowWorkInProg(CityDisplay *window);
  void ShowBuildings(CityDisplay *window);
  void ShowSmokeStacks(CityDisplay *window);

  void ComputeEcon();

  void ChooseBuild();
  void HandleBuildChoice(char *choice);
  void ChooseBuy();
  void HandleBuyChoice(char *choice);

  void PutExtraWorker();
  void PutPollution();
  void DrawIfVisible(MapDisplay* window = MainMap);

  char *MakeWorkMap(int &len);
  void TransWorkMap(MsgQ *q);

  void TakeHit(); // city attacked
  int NuclearAttack(); // returns 0 if attack fails (SDI). Takes damage

  int HasCoast();

  friend void GetCapturedCity(MsgQ *q, Player *p);

private:

  int foodStored;
  int foodSupport() {return settlers*players[ownerId]->FoodUsedPerSettler();}
  int foodStoreCap() {return 10*(size+1);}
  int settlers;

  int prod, food, trade;
  int science, money, luxuries;
  int surpProd();
  int corruption;
  int pollution;

  // things we have built in the city
  BuildingList buildings;
  WonderList wonders;

  void Produce();

  void SendCityInfo(MsgQ *q);

  CityDisplay *display;
  friend class CityDisplay;
};

#endif
