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


#ifdef __STDC__
void 
nl (void)
#else
void 
nl ()
#endif
{
   int             i;

   fputc('\n', f);
   for (i = 0; i != indent; i++)
      fputc(' ', f);
   comma = 0;
}

/* MAYAN Was origionally
 * memicmp(char c1[256], char c2[256], int val)
 * but I figure that the bounds are going to be ignored anyway
 */

#ifdef __STDC__
int 
memicmp(char *c1, char *c2, int val)
#else
int 
memicmp(c1, c2, val)
char *c1;
char *c2;
int val;
#endif
{
   int             char1, char2, i;
   for (i = 0; i < val; i++) {
      char1 = tolower(c1[i]);
      char2 = tolower(c2[i]);
      if (char1 != char2)
         return 1;
   }
   return 0;
}


#ifdef __STDC__
char           *
getstr(char *s)
#else
char           *
getstr(s)
char *s;
#endif
{
   static char    *s1;
   static char     buf[256];
   int             i;

   if (s)
      s1 = s;
   while (isspace(*s1))
      s1++;
   i = 0;
   if (*s1 == '"') {
      s1++;
      while (*s1 && *s1 != '"') {
         buf[i] = *s1;
         if (*s1 == '_' || *s1 == ',')
            buf[i] = ' ';
         i++;
         s1++;
      }
      s1++;
   } else if (*s1 != ';')
      while (*s1 && !isspace(*s1)) {
         buf[i] = *s1;
         if (*s1 == '_' || *s1 == ',')
            buf[i] = ' ';
         i++;
         s1++;
      }
   while (i && isspace(buf[i - 1]))
      i--;
   buf[i] = 0;
   i = 0;
   while (isspace(buf[i]))
      i++;
   return buf + i;
}

/* MAYAN Was origionally
 * strcmpl(char c1[100], char c2[100])
 * but since the bounds are not used in this piece of code, I figured
 * that either
 *   -  we ignore the bounds, or
 *   -  we abort if the two are not the same.
 */
#ifdef __STDC__
int 
strcmpl(char c1[100], char c2[100])
#else
int 
strcmpl(c1, c2)
char c1[100];
char c2[100];
#endif
{
   int             char1, char2, i;
   for (i = 0; i < 100; i++) {
      char1 = tolower(c1[i]);
      char2 = tolower(c2[i]);
      if (char1 != char2)
         return 1;
      if ((char1 == '\0') || (char2 == '\0')) {
         return 0;
      }
   }
}


#ifdef __STDC__
void 
nstrcpy (char *to, char *from, int n)
#else
void 
nstrcpy (to, from, n)
char *to;
char *from;
int n;
#endif
{
   n--;
   do
      if ((*to++ = *from++) == 0)
         return;
   while (--n);
   *to = 0;
}

#ifdef __STDC__
char           *
findnext(void)
#else
char           *
findnext()
#endif
{
   if ((dp = readdir(dfd)) == NULL)
      return NULL;
   if (strcmp(dp->d_name, ".") == 0)
      if ((dp = readdir(dfd)) == NULL)
         return NULL;
   if (strcmp(dp->d_name, "..") == 0)
      if ((dp = readdir(dfd)) == NULL)
         return NULL;
   return dp->d_name;
}

#ifdef __STDC__
char           *
findfirst(char *dir)
#else
char           *
findfirst(dir)
char *dir;
#endif
{
   if(dfd != NULL)
		closedir(dfd);
   if ((dfd = opendir(dir)) == NULL)
      return NULL;
   return findnext();
}




#ifdef __STDC__
strlist        *
makestrlist (char *ns)
#else
strlist        *
makestrlist (ns)
char *ns;
#endif
{
   strlist        *s;

   s = alloc(sizeof(strlist));
   s->s[0] = strdup(ns);
   return s;
}


#ifdef __STDC__
void           *
numtop(void *base, char *s)
#else
void           *
numtop(base, s)
void *base;
char *s;
#endif
{
   list           *p;
   int             i, n;

   i = 0;
   n = atoi(s);
   for (p = base; p; p = p->next) {
      i++;
      if (i == n)
         return p;
   }
   return 0;
}

#ifdef __STDC__
void 
removelist(void *_base, void *_p)
#else
void 
removelist(_base, _p)
void *_base;
void *_p;
#endif
{
   list          **base;
   list           *p;
   list           *q;

   base = _base;
   p = _p;
   if (*base == p)
      *base = p->next;
   else {
      for (q = *base; q->next != p; q = q->next)
         assert(q);
      q->next = p->next;
   }
   free(p);
}

/* MAYAN this is _identical_ to atoi
#ifdef __STDC__
int
_atoi(char *s)
#else
int
_atoi(s)
char *s;
#endif
{
   if (!isdigit(s[0]))
      return 0;
   return atoi(s);
}

Use instead:
*/

/* MAYAN: already available in library
rand(void)
{
   randno = randno * 1103515245 + 12345;
   return (randno / 0x10000) & 0x7fff;
}
*/


#ifdef __STDC__
void 
ftrunc3 (void)
#else
void 
ftrunc3 ()
#endif
{
   int             i;

   i = strlen(buf);
   while (i && buf[i - 1] == '0')
      buf[--i] = 0;
   if (i && buf[i - 1] == '.')
      buf[i - 1] = 0;
}

#ifdef __STDC__
FILE           *
Fopen(char *filename, char *mode)
#else
FILE           *
Fopen(filename, mode)
char *filename;
char *mode;
#endif
{
   FILE           *f;

   f = fopen(filename, mode);
   if (f == 0) {
      printf("Can't open file %s in mode %s\n", filename, mode);
      exit(1);
   }
   return f;
}

#ifdef __STDC__
void           *
alloc(int n)
#else
void           *
alloc(n)
int n;
#endif
{
   void           *p;

   p = malloc(n);
   if (p == 0) {
      printf("Out of memory\n");
      exit(1);
   }
   return p;
}

/* MAYAN: available in <string.h>
char           *
strdup(const char *s)
{
   return strcpy(alloc(strlen(s) + 1), s);
}
*/

#ifdef __STDC__
void 
addlist(void *_base, void *_p)
#else
void 
addlist(_base, _p)
void *_base;
void *_p;
#endif
{
   list          **base;
   list           *p, *q;

   base = _base;
   p = _p;
   p->next = 0;
   if (*base) {
      for (q = *base; q->next; q = q->next);
      q->next = p;
   } else
      *base = p;
}

#ifdef __STDC__
void 
freelist(void *base)
#else
void 
freelist(base)
void *base;
#endif
{
   list           *p, *p2;

   p = base;
   while (p) {
      p2 = p->next;
      free(p);
      p = p2;
   }
}

#ifdef __STDC__
void 
freestrlist(strlist * s)
#else
void 
freestrlist(s)
strlist * s;
#endif
{
   strlist        *s2;

   while (s) {
      s2 = s->next;
      free(s->s[0]);
      free(s);
      s = s2;
   }
}

#ifdef __STDC__
void           *
nametop(void *head, char *s)
#else
void           *
nametop(head, s)
void *head;
char *s;
#endif
{
   list           *p;

   if (!s[0])
      return 0;
   for (p = head; p; p = p->next)
      if (!strcmpl((char *) (p + 1), s))
         return p;
   return 0;
}

#ifdef __STDC__
int
ptonum(void *base, void *target)
#else
int
ptonum(base, target)
void *base;
void *target;
#endif
{
   list           *p;
   int             i;

   for (p = base, i = 1; p; p = p->next, i++)
      if (p == target)
         return i;
   return 0;
}

#ifdef __STDC__
void 
getbuf(void)
#else
void 
getbuf()
#endif
{
   int             i;
   char            c;

   i = 0;
   for (;;) {
      c = fgetc(f);
      if (c == (char)EOF) {
         buf[0] = (char)EOF;
         return;
      }
      if (c == '\n') {
         buf[i] = 0;
         return;
      }
      if (i == sizeof(buf) - 1) {
         buf[i] = 0;
         while (c != (char)EOF && c != '\n')
            c = fgetc(f);
         if (c == (char)EOF)
            buf[0] = (char)EOF;
         return;
      }
      buf[i++] = c;
   }
}

#ifdef __STDC__
double 
frand(double x)
#else
double 
frand(x)
double x;
#endif
{
   return fmod((rand() % 100) * .01 + rand() % 10000, x);
}

#ifdef __STDC__
double 
frand2(void)
#else
double 
frand2()
#endif
{
   return (rand() % 20000 - 10000) * .0001;
}

#ifdef __STDC__
planet         *
addplanet(void)
#else
planet         *
addplanet()
#endif
{
   planet         *p;
   int             i;

   for (p = planets, i = 1; p; p = p->next, i++);
   p = alloc(sizeof(planet));
   memset(p, 0, sizeof(planet));
   addlist(&planets, p);
   p->producing = PR_CAP;
   sprintf(p->name, "%d", i);
   return p;
}

#ifdef __STDC__
int
atwar(player * P, player * P2)
#else
int
atwar(P, P2)
player * P;
player * P2;
#endif
{
   alliance       *a;

   if (P == P2)
      return 0;
   for (a = P->allies; a; a = a->next)
      if (a->who == P2)
         return 0;
   return 1;
}

#ifdef __STDC__
double 
weaponmass(shiptype * t)
#else
double 
weaponmass(t)
shiptype * t;
#endif
{
   return (t->attacks ? t->weapons : 0) +
   ((t->attacks > 1) ? ((t->attacks - 1) * 0.5 * t->weapons) : 0);
}

#ifdef __STDC__
double 
typemass(shiptype * t)
#else
double 
typemass(t)
shiptype * t;
#endif
{
   return t->drive +
   weaponmass(t) +
   t->shields +
   t->cargo;
}

#ifdef __STDC__
double 
shipmass(group * g)
#else
double 
shipmass(g)
group * g;
#endif
{
   double          l;

   l = g->load;
   if (g->cargo)
      l /= g->cargo;
   return typemass(g->type) + l;
}

#ifdef __STDC__
void 
putmap(double x, double y, int c)
#else
void 
putmap(x, y, c)
double x;
double y;
int c;
#endif
{
   int             ix, iy;

   ix = (x - x1) / (x2 - x1) * MAPWIDTH;
   iy = (y - tmpy1) / (y2 - tmpy1) * MAPHEIGHT;
   if (ix < 0 || ix >= MAPWIDTH || iy < 0 || iy >= MAPHEIGHT)
      return;
   map[ix][iy] = c;
}

#ifdef __STDC__
double 
dist(planet * p1, planet * p2)
#else
double 
dist(p1, p2)
planet * p1;
planet * p2;
#endif
{
   double          dx, dy;

   dx = p1->x - p2->x;
   dy = p1->y - p2->y;
   return sqrt(dx * dx + dy * dy);
}

#ifdef __STDC__
void 
send(group * g, planet * p)
#else
void 
send(g, p)
group * g;
planet * p;
#endif
{
   g->from = g->where;
   g->where = p;
   g->dist = dist(p, g->from);
}

#ifdef __STDC__
void 
setproduction(planet * p, int t)
#else
void 
setproduction(p, t)
planet * p;
int t;
#endif
{
   float perccomp;
   float mass;
   float theshipmass;
   float prog;

   if (p->producing == PR_SHIP) {
      theshipmass = typemass(p->producingshiptype);
      mass = theshipmass*INDPERSHIP;
      prog = p->inprogress;
      if (theshipmass > p->mat)
         mass += (theshipmass - p->mat)/p->resources;
      perccomp = prog/mass;
      p->mat += typemass(p->producingshiptype)*perccomp;
   }

   p->inprogress = 0;
   p->producing = t;
   p->producingshiptype = 0;
}

#ifdef __STDC__
double 
groupx(group * g)
#else
double 
groupx(g)
group * g;
#endif
{
   double          dx, ratio, dis;

   dis = dist(g->from, g->where);
   if (!dis)
      return g->where->x;
   dx = g->where->x - g->from->x;
   ratio = g->dist / dis;
   return g->where->x - ratio * dx;
}

#ifdef __STDC__
double 
groupy(group * g)
#else
double 
groupy(g)
group * g;
#endif
{
   double          dy, ratio, dis;

   dis = dist(g->from, g->where);
   if (!dis)
      return g->where->y;
   dy = g->where->y - g->from->y;
   ratio = g->dist / dis;
   return g->where->y - ratio * dy;
}

#ifdef __STDC__
void 
freebattles(void)
#else
void 
freebattles()
#endif
{
   battle         *b, *b2;
   bombing        *B, *B2;
   participant    *r, *r2;

   b = battles;
   while (b) {
      r = b->participants;
      while (r) {
         freelist(r->groups);
         r2 = r->next;
         free(r);
         r = r2;
      }
      b2 = b->next;
      free(b);
      b = b2;
   }

   B = bombings;
   while (B) {
      freelist(B->viewers);
      B2 = B->next;
      free(B);
      B = B2;
   }

   battles = 0;
   bombings = 0;
}

#ifdef __STDC__
void 
freemessages(void)
#else
void 
freemessages()
#endif
{
   player         *P;

   for (P = players; P; P = P->next) {
      freestrlist(P->messages);
      freestrlist(P->mistakes);
      P->messages = 0;
      P->mistakes = 0;
   }

   freestrlist(messages);
   messages = 0;
}

#ifdef __STDC__
void 
freegame(void)
#else
void 
freegame()
#endif
{
   player         *P, *P2;

   freemessages();

   freelist(planets);

   P = players;
   while (P) {
      freelist(P->shiptypes);
      freelist(P->allies);
      freelist(P->groups);
      freestrlist(P->orders);
      P2 = P->next;
      free(P);
      P = P2;
   }

   freebattles();

   planets = 0;
   players = 0;
   gamename[0] = 0;
}

#ifdef __STDC__
group          *
addgroup(group *g, group *current, int first)
#else
group          *
addgroup(g, current, first)
group *g; 
group *current; 
int first;
#endif
{
   group *newgroup, *g2;
   if (first) {
      first = 0;
      newgroup = alloc(sizeof(group));
      *newgroup = *g;
      newgroup->next = 0;
   }
   else {
      g2 = alloc(sizeof(group));
      *g2 = *g;
      addlist(newgroup, g2);
   }
   return newgroup;
}
