#include <stdio.h>
#include <varargs.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include <setjmp.h>
#include <sys/file.h>
#include <math.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <pwd.h>
#include <ctype.h>
#include "defs.h"
#include "struct.h"
#include "data.h"

int mode=0;

void output();

char *ships[] = {"SC", "DD", "CA", "BB", "AS", "SB"};

char *statnames[] = {"F", "O", "A", "E", "D"};

char *name_fix();
char *str();


int             out = 1;        /* stdout for non-socket connections */

main(argc, argv)
     int argc;
     char **argv;
{
    int i;
    char monitor[17];
    int teams[9];
    float totalRatings;
    float hours;
    
    if (argc>1) {
	mode= *(argv[1]);
	out = 0;
    }

    if (!openmem(-1)) {
	output("\nNo one playing.\n");
	exit(0);
    }
	
    for (i=0; i<9; i++) teams[i]=0;

    output("<>=======================================================================<>\n");

    switch(mode) {
      case 'l':
	break;
      case 'd':
	output("  Pl: Name             Type  Kills Damage Shields Armies   Fuel\n");
	break;
      case 'r':
	output("  Pl: Name             Status Type Bombing Planets Offense Defense\n");
	break;

      case 'm':
	output("  Pl: Rank       Name             Login      Display                  Type\n");
	break;

      default:
	output("  Pl: Rank       Name              Login      Display          Ratings   DI\n");
	break;
    }
    output("<>=======================================================================<>\n");
    for (i=0; i<MAXPLAYER; i++) {
	if (players[i].p_status == PFREE || players[i].p_stats.st_tticks==0)
	    continue;
	teams[players[i].p_team]++;
	totalRatings = bombingRating(players+i)+
	    planetRating(players+i)+
		offenseRating(players+i);
	hours = (float) players[i].p_stats.st_tticks/(10*60*60);
	switch(mode) {
	  case 'd':
	    output("  %2s: %-16s   %2s %6.2f %6d %7d %6d %6d\n",
		   players[i].p_mapchars, players[i].p_name,
		   ships[players[i].p_ship.s_type],
		   players[i].p_kills,
		   players[i].p_damage,
		   players[i].p_shield,
		   players[i].p_armies,
		   players[i].p_fuel);
	    break;
	  case 'r':
	    output("  %2s: %-16s %s/%4d  %2s %7.2f %7.2f %7.2f %7.2f\n", 
		   players[i].p_mapchars,
		   players[i].p_name, 
		   statnames[players[i].p_status],
		   players[i].p_ghostbuster,
		   ships[players[i].p_ship.s_type],
		   bombingRating(players+i),
		   planetRating(players+i),
		   offenseRating(players+i),
		   defenseRating(players+i));
	    break;
	  case 'm':
	    output("  %2s: %-10s %-16s %-10s %-24s  %2s\n",
		   players[i].p_mapchars, 
		   ranks[players[i].p_stats.st_rank].name,
		   name_fix(players[i].p_name),
		   str(10,players[i].p_login),
		   str(-24, players[i].p_monitor),
		   ships[players[i].p_ship.s_type]);
	    break;
	  default:
	    strncpy(monitor, players[i].p_monitor, NAME_LEN);
	    monitor[NAME_LEN-1]=0;
	    output(" %c%2s: %-10s %-16s  %-10s %-16s %5.2f %8.2f\n",
		   (players[i].p_stats.st_flags & ST_CYBORG) ? '*' : ' ',
		   players[i].p_mapchars,
		   ranks[players[i].p_stats.st_rank].name,
		   players[i].p_name,
		   players[i].p_login,
		   monitor,
		   totalRatings,
		   totalRatings * hours);
	    break;
	}
    }
    output("<>=======================================================================<>\n");
    output("  Feds: %d   Roms: %d   Kli: %d   Ori: %d\n", 
	   teams[FED], teams[ROM], teams[KLI], teams[ORI]);

    if(queues[QU_PICKUP].count > 0)
	output("  Wait queue: %d\n", queues[QU_PICKUP].count);
    else
	output("  No wait queue.\n");

    output("<>=======================================================================<>\n");
    return 1;		/* satisfy lint */
}


char *name_fix(name)
   char *name;
{
   char *new = strdup(name);                    /* xx, never freed */
   register
   char *r = new;

   while(*name){
      *r++ = (*name <= 32)?'_':*name;
      name++;
   }
   *r = 0;
   return new;
}


char *
str(n, s)

   int  n;
   register
   char *s;
{
   char                 *new;
   register             i = 0, j;
   register char        *r;

   if(n > 0){
      j = strlen(s);
      if(j <= n)
         return s;
      else {
         new = (char *) malloc(n);              /* xx, never freed */
         r = new;
         while(*s && i < n){
            *r++ = *s++;
            i++;
         }
         *r = 0;
         return new;
      }
   }
   else if(n < 0){
      n = -n;
      j = strlen(s);
      if(j <= n)
         return s;
      else{
         new = (char *) malloc(n);              /* xx, never freed */
         r = new;
         s += (j-n);
         while(*s){
            *r++ = *s++;
         }
         *r = 0;
         new[0] = '+';  /* indicate that something missing */
         return new;
      }
   }
   else
      return NULL;
}


void
output(va_alist)
   va_dcl
{
   va_list      ap;
   char         *format;

   va_start(ap);
   format = va_arg(ap, char *);

   if(out == 1){
      vfprintf(stdout, format, ap);
   }
   else {
      char      buf[512];
      vsprintf(buf, format, ap);
      write(out, buf, strlen(buf));
   }
   va_end(args);
}

