#include "textDisplay.h"
#include "global.h"
#include "trans.h"
#include "city.h"
#include "player.h"
#include "citydisplay.h"
#include "displays.h"
#include "graph.h"
#include "help.h"
#include "units.h"
#include "rules.h"

void UnitHelpHandler(BuildObject *u);
void ScienceHelpHandler(Science *s);
void CityHandler(City *city) {
  city->Show();
}

TextDisplay &operator << (TextDisplay &t,Science sci) {
  return t.HyperStr(Sciences[sci].name, ScienceHelpHandler, 
		    &Sciences[sci].type);
};

TextDisplay &operator << (TextDisplay &t,BuildObject b) {
  return t.HyperStr(Objects[b].name, UnitHelpHandler, &Objects[b].type);
};

TextDisplay &operator << (TextDisplay &t,City *city) {
  return t.HyperStr(city->name, CityHandler, city);
};

void UnitHelp(BuildObject unit)
{
  if (!Objects[unit].IsUnit())
    return;

  char text[20];
  TextDisplay *display = 
    screen->CreateTextDisplay((18+LongestScienceName)*FontWidth,
			      SquareHeight+7*LineHeight);

  display->HSpace(((18+LongestScienceName)*FontWidth-SquareWidth)/2);
  display->DrawPixmap(Units[unit].picture, playerId) << NEWLINE;
  display->SetTabs(0,19*FontWidth);
  (*display) << "Unit Name:" << TAB << Objects[unit].name << NEWLINE;
  (*display) << "Unit Type:" << TAB;
  if (SeaUnit(unit))
    (*display) << "Sea Unit" << NEWLINE;
  else if (AirUnit(unit))
    (*display) << "Air Unit" << NEWLINE;
  else
    (*display) << "Land Unit" << NEWLINE;

  (*display) << "Shields Required:" << TAB << Objects[unit].prodCost << NEWLINE;
  sprintf(text, "%d/%2d/%2d", UnitAttack(unit), UnitDefense(unit), UnitMoves(unit));
  (*display) << "Unit A/D/M:" << TAB << text << NEWLINE;
  if (CarryCapacity(unit)) {
    sprintf(text, "%d", CarryCapacity(unit));
    (*display) << "Carrying capacity:" << TAB << text << " Units" << NEWLINE;
  }
  (*display) << "Required Science:" << TAB << Objects[unit].NeededScience << NEWLINE;
  
  Science sci = ObsoletedBy(unit);
  if (sci != NOSCIENCE)
    (*display) << "Obsoleted by:" << TAB << sci << NEWLINE;
}

void
UnitHelpHandler(char *unitName, void *)
{
  BuildObject unit = NOOBJECT;

  BuildObject i;
  FOR_ALL_UNITS(i)
    if (!strcmp(Objects[i].name, unitName))
      unit = Units[i].type;

  if (unit != NOOBJECT)
    UnitHelp(unit);
}

void UnitHelpHandler(BuildObject *u) {
  UnitHelp(*u);
}

void UnitHelp()
{
  List<charp> units;
  for (int i = LASTUNIT; i >= FIRSTUNIT; i--)  
    units.Insert(Objects[i].name);
  screen->CreateChoiceFrame("Unit Help on...", units, UnitHelpHandler, NULL);
  units.Delete();
}

void ScienceHelp(Science sci)
{
  TextDisplay *display = 
    screen->CreateTextDisplay((14+LongestBuildingName)*FontWidth, 11*LineHeight);

  display->SetTabs(0,14*FontWidth);
  (*display) << "Science:" << TAB << Sciences[sci].name << NEWLINE << NEWLINE;
  (*display) << "Requires:" << TAB
	     << Sciences[Sciences[sci].NeededScience[0]].type << NEWLINE;
  if (Sciences[sci].NeededScience[1] != SURVIVAL)
    (*display) << "     and" << TAB
	       << Sciences[Sciences[sci].NeededScience[1]].type;
  
  (*display) << NEWLINE << "Required For:";

  Science i;
  FOR_ALL_SCIENCES(i)
    if ((Sciences[i].NeededScience[0] == sci) ||
	(Sciences[i].NeededScience[1] == sci))
      (*display) << TAB << i << NEWLINE;

  BuildObject j;
  FOR_ALL_BUILDOBJS(j)
    if (Objects[j].NeededScience == sci) {
      (*display) << TAB << j << NEWLINE; 
    }

  FOR_ALL_BUILDOBJS(j)
    if (sci == ObsoletedBy(j)) {
      (*display) << "Obsoletes:" << TAB << j << NEWLINE;
    }
}

void ScienceHelpHandler(char *scienceName, void *)
{
  Science sci = NOSCIENCE;
  Science i;

  FOR_ALL_SCIENCES(i)
    if (!strcmp(Sciences[i].name, scienceName)) {
      sci = Sciences[i].type;
      break;
    }
  if (sci != NOSCIENCE)
    ScienceHelp(sci);
}

void ScienceHelpHandler(Science *sci) {
  ScienceHelp(*sci);
}

void 
ScienceHelp()
{
  List<charp> sciences;
  for (int i = FUTURETECH-1; i >= FIRSTSCIENCE; i--)  
    sciences.Insert(Sciences[i].name);
  screen->CreateChoiceFrame("Science Help on...", sciences, ScienceHelpHandler,
			    NULL);
  sciences.Delete();
}

void CityReport(Player *player)
{
  City *city;
  int i;
  int maxPeople = 0, longestName = 0;

  for (Lister<ulong> cities = player->citys; cities; cities.Next())
    {
      city = trans->TransCity(cities.Elem());
      if (city->size > maxPeople)
	maxPeople = city->size;
      if (strlen(city->name) > longestName)
	longestName = strlen(city->name);
    }
  longestName++;
  TextDisplay *display =
    screen->CreateTextDisplay(maxPeople*PeopleWidth +
			      (longestName +LongestBuildingName + 9)*FontWidth,
			      player->citys.Count()*PeopleHeight);
  
  display->SetTabs(0, longestName*FontWidth,
		   longestName*FontWidth+maxPeople*PeopleWidth,
		   (longestName+LongestBuildingName)*FontWidth+maxPeople*PeopleWidth);
  for (Lister<ulong> cities = player->citys; cities; cities.Next())
    {
      city = trans->TransCity(cities.Elem());
      (*display) << city << TAB;
      for (i = 0; i < city->happy; i++)
	display->DrawPixmap(&happy_pic);
      for (i = 0; i < city->working; i++)
	display->DrawPixmap(&worker_pic);
      for (i = 0; i < city->goondas; i++)
	display->DrawPixmap(&goonda_pic);
      for (i = 0; i < city->elvi; i++)
	display->DrawPixmap(&elvis_pic);
      for (i = 0; i < city->scientists; i++)
	display->DrawPixmap(&scientist_pic);
      for (i = 0; i < city->taxmen; i++)
	display->DrawPixmap(&taxman_pic);
      (*display) << TAB <<  Objects[city->building].name << TAB << "(" 
		 << city->accProd << "/" << city->needProd() << ")" << NEWLINE;
    }
}

void ScienceReport(Player *player)
{
  TextDisplay *display = screen->CreateTextDisplay((LongestScienceName+1)*3*FontWidth,((player->discovered.Size()/3)+3)*LineHeight);

  (*display) << "Currently Researching: "<< player->researching
	     << "  (" << player->scienceAcc << "/" << player->needScience
	     << ")" << NEWLINE << NEWLINE;
  display->SetTabs(0, (LongestScienceName+1)*FontWidth,
		   (LongestScienceName+1)*FontWidth*2);
  Science i;
  FOR_ALL_SCIENCES(i) {
    Science sc = i; 
    if (player->HasDiscovered(sc)) {
      (*display) << sc << TAB;
    }
  }
}
