#include "copyright.h"
#include "galaxy.h"

#ifdef __STDC__
int
canseegroup (player * P, group * g)
#else
int
canseegroup (P, g)
player * P;
group * g;
#endif
{
   group          *g2;

   if (g->dist)
      return 0;
   if (g->where->owner == P)
      return 1;
   for (g2 = P->groups; g2; g2 = g2->next)
      if (!g2->dist && g2->where == g->where)
         return 1;
   return 0;
}

#ifdef __STDC__
int
canseeplanet (player * P, planet * p)
#else
int
canseeplanet (P, p)
player * P;
planet * p;
#endif
{
   group          *g;

   if (p->owner == P)
      return 1;
   for (g = P->groups; g; g = g->next)
      if (g->dist == 0 && g->where == p)
         return 1;
   return 0;
}

#ifdef __STDC__
int
isunidentified (player * P, planet * p)
#else
int
isunidentified (P, p)
player * P;
planet * p;
#endif
{
   return p->owner && !canseeplanet(P, p) && p->x >= x1 && p->x <= x2 &&
      p->y >= tmpy1 && p->y <= y2;
}

#ifdef __STDC__
int
isuninhabited (player * P, planet * p)
#else
int
isuninhabited (P, p)
player * P;
planet * p;
#endif
{
   return !p->owner &&
      ((p->x >= x1 && p->x <= x2 && p->y >= tmpy1 && p->y <= y2) ||
       canseeplanet(P, p));
}

#ifdef __STDC__
void 
_reportfilename (player * P, char *s)
#else
void 
_reportfilename (P, s)
player * P;
char *s;
#endif
{
   int             i, j;

   i = strlen(P->name);
   while (i && isalnum(P->name[i - 1]))
      i--;
   if (P->addr[0]) {
      sprintf(s, "reports/%s/", gamename);
      s += (9 + strlen(gamename));
   } else {
      sprintf(s, "nreports/%s/", gamename);
      s += (10 + strlen(gamename));
   }
   for (j = 0; P->name[i + j] && j != 8; j++)
      *s++ = P->name[i + j];
   *s++ = '.';
   *s++ = 'r';
   *s++ = gamename[0];
   *s++ = gamename[1];
   *s = 0;
}

#ifdef __STDC__
void 
reportfilename (player * P)
#else
void 
reportfilename (P)
player * P;
#endif
{
   player         *P2;
   static char     buf2[256];

   _reportfilename(P, buf);
   for (P2 = players; P2 != P; P2 = P2->next) {
      _reportfilename(P2, buf2);
      if (!strcmp(buf, buf2)) {
         sprintf(buf, P->addr[0] ? "reports/%s/_%d.r%c" : "nreports/%s/_%d.r%c",
            gamename, ++reportfileno, gamename[0]);
         if (gamename[1]) {
            buf2[0] = gamename[1];
            buf2[1] = 0;
            strcat(buf, buf2);
         }
	 printf("buf = %s\n", buf);
         break;
      }
   }
}

#ifdef __STDC__
void 
report (player * P)
#else
void 
report (P)
player * P;
#endif
{
   int             i, j;
   static char     buf2[256];
   double          pop, ind;
   player         *P2;
   planet         *p;
   shiptype       *t;
   battle         *b;
   participant    *r;
   bombing        *B;
   fleetname      *fl;
   group          *g;
   alliance       *a;
   strlist        *s;
   char *cap_gamename;

   reportfilename(P);

   f = Fopen(buf, "w");

   printf("Writing report file %s...\n", buf);

   cap_gamename = strdup(gamename);
   cap_gamename[0] = toupper(cap_gamename[0]);

   strcpy(buf, P->name);
   ckunderscores(buf);

   fprintf(f, "\t\tGalaxy Game %s Turn %d Report for %s\n", 
	cap_gamename, turn, buf);
   underscores = 0;
   twocol = P->twocol;

   if (P->pswdstate == 1) {
      fprintf(f, "\n\nPassword for player %s set to %s\n", P->name, P->pswd);
      fprintf(f, "First line of orders should now be:\n");
      fprintf(f, "#GALAXY %s %s %s\n", gamename, P->name, P->pswd);
   }
   if (P->pswdstate == 2) {
      fprintf(f, "\n\nPassword for player %s removed\n", P->name);
      fprintf(f, "First line of orders should now be:\n");
      fprintf(f, "#GALAXY %s %s\n", gamename, P->name);
   }

   if (turn == 0) {
      fbegin("Player Addresses", "xx");
      for (P2 = players; P2; P2 = P2->next) {
         fs(P2->name);
         fs(P2->addr);
      }
      fend();
   }

   if (messages)
      fprintf(f,"\n\nGLOBAL Messages\n");
      for (s = messages; s; s = s->next) {
         rps(s->s[0]);
         rnl();
      }

   if (P->messages)
      fprintf(f,"\n\nPERSONAL Messages for %s\n",P->name);
      for (s = P->messages; s; s = s->next) {
         rps(s->s[0]);
         rnl();
      }

/* Print ORDERS RECEIVED just before mistakes, but after messages. */
/* -RJS- */

   if(s = P->orders) {
      fprintf(f,"\n\nORDERS RECEIVED\n\n");
      for (; s; s = s->next) {
      /* nobody likes all those useless blank lines */
	 if(s->s[0][0] == '@') {
	    if(!s->s[0][1]) fprintf(f,"> @ [Global Message]\n");
	    else fprintf(f,"> @ [Message to:%s]\n",s->s[0] + 1);
	    for(s = s->next; s->s[0][0] != '@'; s = s->next);
	    continue;
	 }
	 fprintf(f,"> %s\n",s->s[0]);
      }
   }

   fbegin("Mistakes", "xx");
   for (s = P->mistakes; s; s = s->next) {
      if (s->s[0][0] == '#')
         fs(s->s[0] + 1);
      else
         fs(s->s[0]);
      s = s->next;
      fs(s->s[0]);
   }
   fend();

   underscores = P->underscores;

   fbegin("Status of Players", "xffffffix");
   flabels = "NDWSCPI#R";
   for (P2 = players; P2; P2 = P2->next) {
      fs(P2->name);
      ff(P2->drive);
      ff(P2->weapons);
      ff(P2->shields);
      ff(P2->cargo);
      pop = 0;
      ind = 0;
      i = 0;
      for (p = planets; p; p = p->next)
         if (p->owner == P2) {
            pop += p->pop;
            ind += p->ind;
            i++;
         }
      ff(pop);
      ff(ind);
      fi(i);
      fs(P == P2 ? "" : (atwar(P, P2) ? "War" : "Peace"));
   }
   fend();

   fbegin("Your Ship Types", "xfifff");
   flabels = "NDAWSC";
   for (t = P->shiptypes; t; t = t->next)
      printshiptype(t);
   fend();

   for (P2 = players; P2; P2 = P2->next)
      if (P2 != P) {
         for (t = P2->shiptypes; t; t = t->next)
            t->flag = 0;
         for (b = battles; b; b = b->next) {
            for (r = b->participants; r; r = r->next)
               if (r->who == P)
                  break;
            if (r) {
               for (r = b->participants; r; r = r->next)
                  if (r->who == P2)
                     break;
               if (r)
                  for (g = r->groups; g; g = g->next)
                     g->type->flag = 1;
            }
         }
         for (g = P2->groups; g; g = g->next)
            if (canseegroup(P, g))
               g->type->flag = 1;
         for (p = planets; p; p = p->next)
            if (p->owner == P2 && p->producing == PR_SHIP && canseeplanet(P, p))
               p->producingshiptype->flag = 1;
         for (B = bombings; B; B = B->next) {
            for (a = B->viewers; a; a = a->next)
               if (a->who == P)
                  break;
            if (a && B->producing == PR_SHIP)
               B->producingshiptype->flag = 1;
         }
         strcpy(buf, P2->name);
         ckunderscores(buf);
         strcat(buf, " Ship Types");
         fbegin(buf, "xfifff");
         flabels = "NDAWSC";
         for (t = P2->shiptypes; t; t = t->next)
            if (t->flag)
               printshiptype(t);
         fend();
      }
   for (b = battles; b; b = b->next) {
      for (r = b->participants; r; r = r->next)
         if (r->who == P)
            break;
      if (r) {
         rnl();
         sprintf(buf, "\t\tBattle at %s\n", b->where->name);
         ckunderscores(buf + 12);
         fprintf(f, "%s", buf);
         for (r = b->participants; r; r = r->next) {
            P2 = r->who;
            strcpy(buf, "Your");
            if (P2 != P) {
               strcpy(buf, P2->name);
               ckunderscores(buf);
            }
            strcat(buf, " Groups");
            fbegin(buf, "ixffffxfi");
            flabels = "#TDWSCTQL";
            for (g = r->groups; g; g = g->next)
               printgroup(P2, g, 0, 0);
            fend();
         }
      }
   }

   fbegin("Bombings", "xxxffxfff");
   flabels = "WONPIP$MC";
   for (B = bombings; B; B = B->next) {
      for (a = B->viewers; a; a = a->next)
         if (a->who == P)
            break;
      if (a) {
         fs(B->who->name);
         fs(B->owner->name);
         fs(B->name);
         ff(B->pop);
         ff(B->ind);
         if (B->producing == PR_SHIP)
            fs(B->producingshiptype->name);
         else
            fs(productname[B->producing]);
         ff(B->cap);
         ff(B->mat);
         ff(B->col);
      }
   }
   fend();

   x1 = P->mx;
   x2 = P->mx + P->msize;
   tmpy1 = P->my;
   y2 = P->my + P->msize;

   rnl();
   rpf(x1);
   rpc(',');
   rpf(tmpy1);
   space(MAPWIDTH - scrsize(x1, tmpy1) - scrsize(x2, tmpy1));
   rpf(x2);
   rpc(',');
   rpf(tmpy1);
   rnl();
   for (i = 0; i != MAPWIDTH; i++)
      rpc('-');
   rnl();

   memset(map, ' ', sizeof map);

   for (P2 = players; P2; P2 = P2->next)
      if (P2 != P)
         for (g = P2->groups; g; g = g->next)
            putmap(groupx(g), groupy(g), '-');

   for (g = P->groups; g; g = g->next)
      putmap(groupx(g), groupy(g), '.');

   for (p = planets; p; p = p->next)
      if (!p->owner)
         putmap(p->x, p->y, 'o');

   for (p = planets; p; p = p->next)
      if (p->owner && p->owner != P)
         putmap(p->x, p->y, '+');

   for (p = planets; p; p = p->next)
      if (p->owner == P)
         putmap(p->x, p->y, '*');

   for (i = 0; i != MAPHEIGHT; i++) {
      for (j = 0; j != MAPWIDTH; j++)
         rpc(map[j][i]);
      rnl();
   }

   for (i = 0; i != MAPWIDTH; i++)
      rpc('-');
   rnl();
   rpf(x1);
   rpc(',');
   rpf(y2);
   space(MAPWIDTH - scrsize(x1, y2) - scrsize(x2, y2));
   rpf(x2);
   rpc(',');
   rpf(y2);
   rnl();

   fbegin("Incoming Groups", "xxfff");
   flabels = "ODRSM";
   for (P2 = players; P2; P2 = P2->next)
      if (P2 != P)
         for (g = P2->groups; g; g = g->next)
            if (g->dist && g->where->owner == P) {
               fs(g->from->name);
               fs(g->where->name);
               ff(g->dist);
	       if (g->thefleet)
		  ff (g->thefleet->fleetspeed);
               else
                  ff(g->type->drive * g->drive * DRIVEMAGIC / shipmass(g));
               ff(shipmass(g) * g->ships);
            }
   fend();

   fbegin("Your Planets", "xffffffxfff");
   flabels = "NXYSPIRP$MC";
   for (p = planets; p; p = p->next)
      if (p->owner == P)
         printplanet(p);
   fend();

   if (P->prodtable) {
      fbegin ("Ships In Production","xxff");
      flabels = "NPNU";
      for (p=planets; p; p=p->next)
	 if (p->owner == P)
	    printproduction (p);
      fend ();
   }

   fbegin("Your Routes", "xxxxx");
   flabels = "N$MCE";
   for (p = planets; p; p = p->next)
      if (p->owner == P &&
          (p->routes[0] || p->routes[1] || p->routes[2] || p->routes[3])) {
         fs(p->name);
         for (i = 0; i != MAXCARGO; i++)
            if (p->routes[i])
               fs(p->routes[i]->name);
            else
               fs("-");
      }
   if (P->autounload) {
       fs("AUTO");
       fs("UNLOAD");
       fs("IS");
       fs("CURRENTLY");
       fs("SET");
   }
   fend();

   for (P2 = players; P2; P2 = P2->next)
      if (P2 != P) {
         strcpy(buf, P2->name);
         ckunderscores(buf);
         strcat(buf, " Planets");
         fbegin(buf, "xffffffxfff");
         flabels = "NXYSPIRP$MC";
         for (p = planets; p; p = p->next)
            if (p->owner == P2 && canseeplanet(P, p))
               printplanet(p);
         fend();
      }
   fbegin("Unidentified Planets", "xff");
   flabels = "NXY";
   for (p = planets; p; p = p->next)
      if (isunidentified(P, p)) {
         fs(p->name);
         ff(p->x);
         ff(p->y);
      }
   fend();

   fbegin("Uninhabited Planets", "xffff");
   flabels = "NXYSR";
   for (p = planets; p; p = p->next)
      if (isuninhabited(P, p)) {
         fs(p->name);
         ff(p->x);
         ff(p->y);
         if (canseeplanet(P, p)) {
            ff(p->size);
            ff(p->resources);
         } else {
            fs("");
            fs("");
         }
      }
   fend();

   if (P->fleettables) {
      fbegin("Your Groups", "iixffffxfxf"); 
      flabels = "G#TDWSCTQDR";
   }
   else {
      fbegin("Your Groups", "iixffffxfxxf");
      flabels = "G#TDWSCTQDFR";
   }
   for (g = P->groups, i = 1; g; g = g->next, i++)
      if ((!g->thefleet)||(!P->fleettables))
         printgroup(P, g, 2, i);
   fend();

   if (P->fleettables) {
      for (fl = P->fleetnames; fl; fl=fl->next) {
         strcpy (buf, fl->name);
         ckunderscores(buf);
         sprintf(buf2, "Fleet %s (speed %.2f)", buf, fl->fleetspeed);
         fbegin(buf2, "iixffffxfxf");
         flabels = "G#TDWSCTQDR";
         for (g = P->groups, i = 1; g; g = g->next, i++)
            if (g->thefleet == fl)
               printgroup(P, g, 2, i);
         fend ();
      }
   }
   else {
      fbegin("Fleet Speed", "xf");
      flabels = "FS";
      for (fl = P->fleetnames; fl; fl=fl->next) {
	 fs(fl->name);
	 ff(fl->fleetspeed);
      }
      fend();
   }

   for (P2 = players; P2; P2 = P2->next)
      if (P2 != P) {
         strcpy(buf, P2->name);
         ckunderscores(buf);
         strcat(buf, " Groups");
         fbegin(buf, "ixffffxfx");
         flabels = "#TDWSCTQD";
         for (g = P2->groups; g; g = g->next)
            if (canseegroup(P, g))
               printgroup(P2, g, 1, 0);
         fend();
      }
   fclose(f);
}
