/*******************************************************************/
/*                                                                 */
/* Version 1.0: Erster Release.                                    */
/* Version 1.1: Readfile etwas sicherer gemacht.                   */
/* Version 1.2: Nur lohnende Routen (>1000 MCr Gewinn)             */
/* Version 1.3: Investment und Laderaumueberpruefung               */
/* Version 1.4: 0-Rueckfluege gekuerzt                             */
/* Version 1.4(beta): Erste Testversion fuer Allgemeine Benutzung  */
/* Version 1.5(beta): Bugfix im Menu 3                             */
/* Version 1.6(beta): Nach 4 Routen ein FormFeed                   */
/* Version 1.7(beta): Mindestgewinn wird jetzt eingegeben          */
/* Version 1.8(beta): jeweils die letzte Handelsroute kann         */
/*                    geloescht werden.                            */
/* Version 1.9(beta): Neue Ausgabe der Routen/mit maxcargo         */
/* Version 2.0: kleiner Bugfix in rekalk() (credits...)            */
/* Version 2.1: Ausdruck geaendert                                 */
/* Version 2.2: Mindestgwinn pro Ware eingefuehrt                  */
/* Version 2.3: Convoyroutes                                       */
/*                                                                 */
/*******************************************************************/

#include <stdio.h>
#include <string.h>
#include "avl.h"
#include "handel.h"

#define VERSION "2.3"
/*#define ALLIANZ "Galaktische Foederation von Orion"*/
#define ALLIANZ "Hierachie der Killermaschinen"
#define DATAFILE "hdatafile"
#define NEWDATAFILE "hdatafile"
#define ROUTENFILE "routen"
#define HANDELFILE "handelsrouten"
#define WARENFILE "warenrouten"
#define CONVOYROUTEN "Convoy.dat"
#define CONVOYSAVE "Convoy.dat"
#define AUTOTRADE 0
#define TRADE 1
#define NOSUM 0
#define SUM 1
#define PRINTER 1
#define NOPRINTER 0

char version[]= "$VER:Handel " VERSION " (c) M. Horstmann " __DATE__ " (" __TIME__ ")\0";

struct route *rroot = NULL, *rroot2 = NULL, *troot = NULL;
int maxdist, dist, cargospace, credits, minwin, minpr, maxcargo;
struct planet *plhead = NULL;
FILE *CONVFILE;

freerlist ()
{
  struct route *hp1, *hp2;

  hp1 = rroot;
  while (hp1)
    {
      hp2 = hp1->next;
      free (hp1);
      hp1 = hp2;
    }
  rroot = NULL;
}

freerlist2()
{
  struct route *hp1, *hp2;

  hp1 = rroot2;
  while (hp1)
    {
      hp2 = hp1->next;
      free (hp1);
      hp1 = hp2;
    }
  rroot2 = NULL;
}

addtail (struct planet *x)
{
  if (plhead)
    {
      plhead->prev->next = x;
      x->prev = plhead->prev;
      plhead->prev = x;
      x->next = NULL;
    }
  else
    {
      plhead = x;
      x->next = NULL;
      x->prev = plhead;
    }
}

struct planet *findplanet (char name[20], int num)
{
  struct planet *hp;

  hp = plhead;
  
  while (hp)
    {
      if (strncmp (name, hp->name, strlen (name)) == 0)
	if (num == hp->num)
	  return hp;
      hp = hp->next;
    }				/* while */
  printf("Planet %s %d\n nicht in Datenbasis.\n", name, num);
  return NULL;
}

insertatr (struct route * x)
{
  struct route *hp;
  int quit = 0;

  hp = rroot;

  if (hp)
    {
      while (!quit)
	if ((x->gpr) > (hp->gpr))
	  {
	    x->next = hp;
	    x->prev = (hp->prev);
	    hp->prev = x;
	    quit = 1;
	    if (hp == rroot)
	      rroot = x;
	    else
	      x->prev->next = x;
	  }
	else if (hp->next)
	  hp = hp->next;
	else
	  {
	    x->next = (hp->next);
	    hp->next = x;
	    x->prev = hp;
	    rroot->prev = x;
	    quit = 1;
	  }

    }
  else
    {
      rroot = x;
      x->prev = NULL;
      x->next = NULL;
    }
}

insertatr2 (struct route * x)
{
  struct route *hp;
  int quit = 0;

  hp = rroot2;

  if (hp)
    {
      while (!quit)
	if ((x->gpr) > (hp->gpr))
	  {
	    x->next = hp;
	    x->prev = (hp->prev);
	    hp->prev = x;
	    quit = 1;
	    if (hp == rroot2)
	      rroot2 = x;
	    else
	      x->prev->next = x;
	  }
	else if (hp->next)
	  hp = hp->next;
	else
	  {
	    x->next = (hp->next);
	    hp->next = x;
	    x->prev = hp;
	    rroot2->prev = x;
	    quit = 1;
	  }
    }
  else
    {
      rroot2 = x;
      x->prev = NULL;
      x->next = NULL;
    }
}

insertatt (struct route *x)
{
  struct route *hp;

  if (troot)
    {
      x->next = NULL;
      x->prev = (troot->prev);
      troot->prev->next = x;
      troot->prev = x;
    }
  else
    {
      troot = x;
      x->prev = x;
      x->next = NULL;
    }
}

rekalk(struct route *x)
{
  int i;
  
  for (i=0; i<10; i++)
  {
    x->start->prvol[i][0]+=x->handel[i][0];
    x->ziel->prvol[i][1]+=x->handel[i][0];
  }
  credits-=x->gpr;
  search();
}

rmlasttroute ()
{
  struct route *hp;

  if (troot)
    if (troot->next)
    {
      hp=troot->prev;
      troot->prev->prev->next=NULL;
      troot->prev=troot->prev->prev;
      rekalk(hp);
      free(hp);
    } 
    else
    {
      rekalk(troot);
      free(troot);
      troot=NULL;
    }     
}

int readfile ()
{
  FILE *file;
  int i;
  struct planet *pl;

  file = fopen (DATAFILE, "r");

  if (feof (file))
    {
      fprintf (stderr, "File %s existiert nicht, oder ist leer.\n",DATAFILE);
      return 0;
    }

  while (!feof (file))
    {
      pl = (struct planet *) calloc (1, sizeof (struct planet));;
      fscanf (file, "%s %d ( %d, %d, %d )\n", pl->name, &(pl->num),
	      &(pl->x), &(pl->y), &(pl->z));
      for (i = 0; i < 10; i++)
	{
	  fscanf (file, "%d %d %d %d\n", &(pl->prvol[i][0]),
		  &(pl->prvol[i][1]),
		  &(pl->prvol[i][2]),
		  &(pl->prvol[i][3]));
	}
      fscanf (file, "\n");
      addtail (pl);
    }
  fclose (file);
  return 1;
}

output ()
{
  int j;
  struct planet *i;
  FILE *file;

  file = fopen (NEWDATAFILE, "w");
  i = plhead;
  while (i)
    {
      fprintf (file, "%s %d (%3d,%3d,%2d)\n", i->name, i->num,
	       i->x, i->y, i->z);
      for (j = 0; j < 10; j++)
	{
	  fprintf (file, "%5d %5d %4d %4d\n",
		   i->prvol[j][0],
		   i->prvol[j][1],
		   i->prvol[j][2],
		   i->prvol[j][3]);
	}
      fprintf (file, "\n");
      i = i->next;
    }
  fclose (file);
  CONVFILE=fopen(CONVOYSAVE, "w");
  AVLinfixKey(conroutes, (void *)extprintcroutes, (void *)NULL); 
  fclose(CONVFILE);
}

int max (int x, int y)
{
  if (x > y)
    return x;
  else
    return y;
}

int min (int x, int y)
{
  if (x < y)
    return x;
  else
    return y;
}

int distok (struct planet *x, struct planet *y)
{
  dist = max (abs (x->z - (y->z)), max (abs (x->x - (y->x)), abs (x->y - (y->y))));
  if (dist <= maxdist)
    return 1;
  else
    return 0;
}

int cmp (struct item *a, struct item *b)
{
  return ((b->gpr) - (a->gpr));
}

search ()
{
  struct planet *i, *j;
  int k, akraum;
  struct route *at;
  char route[25];
  struct item gprh[10] = {0, 0};

  freerlist ();
  i = plhead;
  while (i)
    {
      j = plhead;
      while (j)
	{
	  at = (struct route *) calloc (1, sizeof (struct route));
	  at->start = i;
	  at->ziel = j;
	  if (distok (i, j))
	  {
	    for (k = 0; k < 10; k++)
	      if (((i->prvol[k][0]) > 0) && ((j->prvol[k][1]) > 0) &&
		 (((j->prvol[k][3]) - (i->prvol[k][2])) > minpr))
		{
                  gprh[k].gpr = ((j->prvol[k][3]) - (i->prvol[k][2]));
		  gprh[k].item = k;
		}
              else
              {
                  gprh[k].gpr = 0;
		  gprh[k].item = k;
              }
            qsort (gprh, 10, sizeof (struct item), cmp);
            akraum=maxcargo;
	    for (k = 0; gprh[k].gpr; k++)
	    {
	      at->handel[gprh[k].item][0] = min (credits / i->prvol[gprh[k].item][2], min (akraum, min (i->prvol[gprh[k].item][0], j->prvol[gprh[k].item][1])));
	      at->handel[gprh[k].item][1] = (j->prvol[gprh[k].item][3]) - (i->prvol[gprh[k].item][2]);
	      at->handel[gprh[k].item][2] = (at->handel[gprh[k].item][0]) * (at->handel[gprh[k].item][1]);
	      at->gpr += at->handel[gprh[k].item][2];
	      at->invest += (at->handel[gprh[k].item][0]) * (i->prvol[gprh[k].item][2]);
	      at->cargo += at->handel[gprh[k].item][0];
	      akraum -= at->handel[gprh[k].item][0];

/*		at->handel[k][0] = min (i->prvol[k][0], j->prvol[k][1]);
		at->handel[k][1] = (j->prvol[k][3] - (i->prvol[k][2]));
		at->handel[k][2] = (at->handel[k][0]) * (at->handel[k][1]);
		at->gpr += at->handel[k][2];
		at->invest += (at->handel[k][0]) * (i->prvol[k][2]);
		at->cargo += at->handel[k][0];
*/
             }
	    at->dist = dist;
	  }
	  if ((at->gpr) > minwin)
	    insertatr (at);
	  else
	    free (at);
	  j = j->next;
	}
      i = i->next;
    }
}

search2()
{
  struct planet *i, *j;
  int k;
  struct route *at;
  char route[25];

  freerlist2 ();
  i = plhead;
  while (i)
    {
      for (k = 0; k < 10; k++)
      {
        j = plhead;
        at = (struct route *) calloc (1, sizeof (struct route));
	at->start = i;
        while (j)
	{
	  if (distok (i, j))
	    if ((((j->prvol[k][3] - (i->prvol[k][2])) > at->handel[k][1]) && (min (i->prvol[k][0], j->prvol[k][1]) > 0))|| 
   	         ((((j->prvol[k][3] - (i->prvol[k][2])) >= at->handel[k][1]) 
                 && ((j->prvol[k][3] - (i->prvol[k][2])) > minpr)) 
                 && (min (i->prvol[k][0], j->prvol[k][1]) > at->handel[k][0]))) 
		{
		  at->handel[k][0] = min (i->prvol[k][0], j->prvol[k][1]);
		  at->handel[k][1] = (j->prvol[k][3] - (i->prvol[k][2]));
		  at->handel[k][2] = (at->handel[k][0]) * (at->handel[k][1]);
		  at->gpr = at->handel[k][2];
		  at->invest = (at->handel[k][0]) * (i->prvol[k][2]);
		  at->cargo = at->handel[k][0];
		  at->ziel = j;
            	  at->dist = dist;
		}
	  j = j->next;
	}
        if (at->gpr) 
          insertatr2 (at);
        else
          free(at);
      }
      i = i->next;
    }
}

joinroutes()
{
  struct planet *i, *j;
  int k;
  struct route *at, *at2, *hp;
  char route[25];

  i = plhead;
  while (i)
    {
      j = plhead;
      while (j)
	{
          at = (struct route *) calloc (1, sizeof (struct route));
          at->start = i;
	  at->ziel = j;
	  at2=rroot2;
          while (at2)
          {
            if ((at2->start==i)&&(at2->ziel==j))
            {
    	      for (k = 0; k < 10; k++)
    	        if (at2->handel[k][0])
		{
		  at->handel[k][0] = at2->handel[k][0];
		  at->handel[k][1] = at2->handel[k][1];
		  at->handel[k][2] = at2->handel[k][2];
		  at->gpr += at->handel[k][2];
		  at->invest += (at->handel[k][0]) * (i->prvol[k][2]);
		  at->cargo += at->handel[k][0];
		  at->dist=at2->dist;
		}
	      hp=at2;
	      at2=at2->next;
	      if (at2)
  	        at2->prev=hp->prev;
  	      else
  	        rroot2->prev=hp->prev;
	      if (hp==rroot2) 
                rroot2=at2;
	      else
 	        hp->prev->next=at2;
	      free(hp);
	    }
	    else
	      at2=at2->next;
	  }
	    
          if (at->gpr)
	    insertatr2 (at);
	  else
	    free (at);
	  j = j->next;    
	}
      i = i->next;
    }
}

printroutes (struct route *root, FILE * file, int mode, int printermode)
     /* mode 0 Keine Aufsummierung */
     /* mode 1 Aufsummierung */
{
  struct route *at;
  int k, l = 1;
  int sumanz = 0, sum = 0, gessumanz = 0;

  at = root;
  while (at)
    {
      fprintf (file, "    %s %d (%3d,%3d,%2d) -> %s %d (%3d,%3d,%2d) (Distanz %d)\n", 
               at->start->name,
	       at->start->num,
	       at->start->x,
	       at->start->y,
	       at->start->z,
	       at->ziel->name,
	       at->ziel->num,
	       at->ziel->x,
	       at->ziel->y,
	       at->ziel->z,
	       at->dist);
      if (at->gpr)
	{
	  fprintf (file, "\n");
	  for (k = 0; k < 10; k++)
	    if (at->handel[k][0])
	      fprintf (file, "      %-21s %6d %6d %3d\n", gueter[k],
		       at->handel[k][0], at->handel[k][2], at->handel[k][1]);
	  sumanz = at->cargo;
	  sum += at->gpr;
	  gessumanz += sumanz;
	  fprintf (file, "      ------------------------------------------------------\n");
	  fprintf (file, "      %-21s %6d %6d Invest: %d\n", "", sumanz, at->gpr, at->invest);
	}
      else
	fprintf (file, "\n      Leerflug - Keine Ladung!\n");
      fprintf(file, "\n");
      l++;
      at = at->next;
    }
  if (mode)
    fprintf (file, "\n      Handelsvolumen: Laderaeume %d, MCr %d, Staatskasse: %d\n\n\n", gessumanz, sum, credits);
}

trade (struct rt *route, int mode, int goods[10], int frachtraum)
     /* mode=0 Autotrade */
     /* mode=1 Trade goods */
{
  int k, akraum;
  struct item gprh[10] = {0, 0}, gprz[10] = {0, 0};
  struct planet *start, *ziel;
  struct route *at;

  start = route->start;
  ziel = route->ziel;

  switch (mode)
    {
    case 0:
      at = (struct route *) calloc (1, sizeof (struct route));
      at->start = start;
      at->ziel = ziel;
      akraum = frachtraum;
      if (distok (start, ziel))
	{
	  for (k = 0; k < 10; k++)
	    if (((start->prvol[k][0]) > 0) && ((ziel->prvol[k][1]) > 0) &&
		(((ziel->prvol[k][3]) - (start->prvol[k][2])) > 0))
	      {
		gprh[k].gpr = (ziel->prvol[k][3] - (start->prvol[k][2]));
		gprh[k].item = k;
	      };
	  qsort (gprh, 10, sizeof (struct item), cmp);
	  for (k = 0; gprh[k].gpr; k++)
	    {
	      at->handel[gprh[k].item][0] = min (credits / start->prvol[gprh[k].item][2], min (akraum, min (start->prvol[gprh[k].item][0], ziel->prvol[gprh[k].item][1])));
	      at->handel[gprh[k].item][1] = (ziel->prvol[gprh[k].item][3]) - (start->prvol[gprh[k].item][2]);
	      at->handel[gprh[k].item][2] = (at->handel[gprh[k].item][0]) * (at->handel[gprh[k].item][1]);
	      at->gpr += at->handel[gprh[k].item][2];
	      at->cargo += at->handel[gprh[k].item][0];
	      start->prvol[gprh[k].item][0] = start->prvol[gprh[k].item][0] - at->handel[gprh[k].item][0];
	      ziel->prvol[gprh[k].item][1] = ziel->prvol[gprh[k].item][1] - at->handel[gprh[k].item][0];
	      akraum -= at->handel[gprh[k].item][0];
	      credits -= (at->handel[gprh[k].item][0]) * (start->prvol[gprh[k].item][2]);
	      at->invest += (at->handel[gprh[k].item][0]) * (start->prvol[gprh[k].item][2]);
	    }
	}
      at->dist = dist;
      credits += (at->invest + at->gpr);
      insertatt (at);
      at = (struct route *) calloc (1, sizeof (struct route));
      at->start = ziel;
      at->ziel = start;
      akraum = frachtraum;
      if (distok (start, ziel))
	{
	  for (k = 0; k < 10; k++)
	    if (((ziel->prvol[k][0]) > 0) && ((start->prvol[k][1]) > 0) &&
		((start->prvol[k][3] - (ziel->prvol[k][2])) > 0))
	      {
		gprz[k].gpr = (start->prvol[k][3] - (ziel->prvol[k][2]));
		gprz[k].item = k;
	      };
	  qsort (gprz, 10, sizeof (struct item), cmp);
	  for (k = 0; gprz[k].gpr; k++)
	    {
	      at->handel[gprz[k].item][0] = min (credits / ziel->prvol[gprz[k].item][2], min (akraum, min (ziel->prvol[gprz[k].item][0], start->prvol[gprz[k].item][1])));
	      at->handel[gprz[k].item][1] = (start->prvol[gprz[k].item][3] - (ziel->prvol[gprz[k].item][2]));
	      at->handel[gprz[k].item][2] = (at->handel[gprz[k].item][0]) * (at->handel[gprz[k].item][1]);
	      at->cargo += at->handel[gprz[k].item][0];
	      at->gpr += at->handel[gprz[k].item][2];
	      ziel->prvol[gprz[k].item][0] = ziel->prvol[gprz[k].item][0] - at->handel[gprz[k].item][0];
	      start->prvol[gprz[k].item][1] = start->prvol[gprz[k].item][1] - at->handel[gprz[k].item][0];
	      akraum -= at->handel[gprz[k].item][0];
	      credits -= (at->handel[gprz[k].item][0]) * (ziel->prvol[gprz[k].item][2]);
	      at->invest += (at->handel[gprz[k].item][0]) * (ziel->prvol[gprz[k].item][2]);
	    }
	}
      at->dist = dist;
      credits += (at->invest + at->gpr);
      insertatt (at);
      break;
    case 1:
      at = (struct route *) calloc (1, sizeof (struct route));
      at->start = start;
      at->ziel = ziel;
      akraum = frachtraum;
      if (distok (start, ziel))
	{
	  for (k = 0; k < 10; k++)
	    if (((start->prvol[k][0]) > 0) && ((ziel->prvol[k][1]) > 0) &&
		((ziel->prvol[k][3] - (start->prvol[k][2])) > 0) && goods[k])
	      {
		gprh[k].gpr = (ziel->prvol[k][3] - (start->prvol[k][2]));
		gprh[k].item = k;
	      };
	  qsort (gprh, 10, sizeof (struct item), cmp);
	  for (k = 0; gprh[k].gpr; k++)
	    {
	      at->handel[gprh[k].item][0] = min (credits / start->prvol[gprh[k].item][2], min (akraum, min (start->prvol[gprh[k].item][0], ziel->prvol[gprh[k].item][1])));
	      at->handel[gprh[k].item][1] = (ziel->prvol[gprh[k].item][3] - (start->prvol[gprh[k].item][2]));
	      at->handel[gprh[k].item][2] = (at->handel[gprh[k].item][0]) * (at->handel[gprh[k].item][1]);
	      at->gpr += at->handel[gprh[k].item][2];
	      at->cargo += at->handel[gprh[k].item][0];
	      start->prvol[gprh[k].item][0] = start->prvol[gprh[k].item][0] - at->handel[gprh[k].item][0];
	      ziel->prvol[gprh[k].item][1] = ziel->prvol[gprh[k].item][1] - at->handel[gprh[k].item][0];
	      akraum -= at->handel[gprh[k].item][0];
	      credits -= (at->handel[gprh[k].item][0]) * (start->prvol[gprh[k].item][2]);
	      at->invest += (at->handel[gprh[k].item][0]) * (start->prvol[gprh[k].item][2]);
	    }
	}
      at->dist = dist;
      insertatt (at);
      credits += (at->invest + at->gpr);
      break;
    default:
      break;
    }
  search ();
}

int askroute (struct rt *route)
{
  char name[20];
  int num;

  fprintf (stderr, "Startplanet: ");
  scanf ("%s %d", name, &num);
  route->start = findplanet (name, num);

  fprintf (stderr, "Zielplanet: ");
  scanf ("%s %d", name, &num);
  route->ziel = findplanet (name, num);

/*
  fprintf (stderr, "Verfuegbare Frachtraeume: ");
  scanf ("%d", &cargospace);
*/
  
  cargospace=maxcargo;

  if ((route->start == route->ziel) || (route->start == NULL) || (route->ziel == NULL))
    {
      fprintf (stderr, "Illegale Route!\n");
      return 0;
    }
  else
    return 1;
}

void *extprintcroutes(struct convoy *x, void *args)
{
  int i;

  fprintf(CONVFILE, "%s: %s %d %s %d\n Out:\n", x->num,
	 x->start->name, x->start->num,
	 x->ziel->name, x->ziel->num);
  
  for (i=0; i<14; i++)
    if (x->outhandel[i]>0) fprintf(CONVFILE,"  %s %d\n", gueter[i], x->outhandel[i]);
  
  fprintf(CONVFILE, " In:\n");
  
  for (i=0; i<14; i++)
    if (x->inhandel[i]>0) fprintf(CONVFILE, "  %s %d\n", gueter[i], x->inhandel[i]);
}

void *printcroutes(struct convoy *x, void *args)
{
  int i;

  printf("Route %s: %s %d <-> %s %d\n", x->num,
	 x->start->name, x->start->num,
	 x->ziel->name, x->ziel->num);
}

struct convoy *getconroute(char *id)
{
  struct convoy tst=defaultroute;
  
  tst.num=id;
  return AVLask(&tst, cmprout, conroutes);
}

convoyroutes()
{
  int quit=0, k, akraum, num;
  char wahl;
  char rout[20];
  struct convoy *conv=NULL;
  struct planet *start, *ziel;
  struct route *at;
  struct convoy new;

  printf("Bekannte Routen:\n\n");
  AVLinfixKey(conroutes, (void *)printcroutes, (void *)NULL);
  while (!quit) {
    fprintf(stderr, "\n1 - Detailiert\n");
    fprintf(stderr, "2 - Ausfuehren\n");
    fprintf(stderr, "3 - Errichten\n");
    fprintf(stderr, "4 - Liste\n");
    fprintf(stderr, "\n\n 0 - ZURUECK\n");
    wahl = 0;
    fprintf(stderr,"Ihre Wahl: ");
    while ((wahl < '0') || (wahl > '4')) {
      scanf ("%c", &wahl);
    }
    switch(wahl)
      {
      case '0': quit=1; break;
      case '1':
	do {
	  fprintf(stderr, "Route : ");
	  scanf("%s", rout);
	} while (!(conv=getconroute(rout)));
	CONVFILE=stderr;
	extprintcroutes(conv, NULL);
	break;
      case '2':
	do {
	  fprintf(stderr, "Route : ");
	  scanf("%s", rout);
	} while (!(conv=getconroute(rout)));
	fprintf(stderr, "Cargospace: ");
	scanf("%d", &cargospace);
	
	start=conv->start;
	ziel=conv->ziel;
	
	at = (struct route *) calloc (1, sizeof (struct route));
	at->start = start;
	at->ziel = ziel;
	akraum = cargospace;
	if (distok (start, ziel))
	  {
	    for (k = 0; k < 10; k++)
	      if (((start->prvol[k][0]) > 0) && ((ziel->prvol[k][1]) > 0) &&
		  ((ziel->prvol[k][3] - (start->prvol[k][2])) > 0) 
		  && ((conv->outhandel[k])>0))
		{
		  at->handel[k][0] = min (credits / start->prvol[k][2], 
					  min(conv->outhandel[k], 
					      min(akraum, 
						  min(start->prvol[k][0], 
						      ziel->prvol[k][1]))));
		  if (at->handel[k][0]!=conv->outhandel[k]) {
		    printf("%s %d\n", gueter[k], at->handel[k][0]);
		    fprintf(stderr, "WARNUNG: Convoyroute nicht in Ordnung!\n");
		  }
		  at->handel[k][1] = (ziel->prvol[k][3] - (start->prvol[k][2]));
		  at->handel[k][2] = (at->handel[k][0]) * (at->handel[k][1]);
		  at->gpr += at->handel[k][2];
		  at->cargo += at->handel[k][0];
		  start->prvol[k][0] = start->prvol[k][0] - at->handel[k][0];
		  ziel->prvol[k][1] = ziel->prvol[k][1] - at->handel[k][0];
		  akraum -= at->handel[k][0];
		  credits -= (at->handel[k][0]) * (start->prvol[k][2]);
		  at->invest += (at->handel[k][0]) * (start->prvol[k][2]);
		}
	    at->dist = dist;
	    insertatt (at);
	    credits += (at->invest + at->gpr);
	    
	    start=conv->ziel;
	    ziel=conv->start;
	    at = (struct route *) calloc (1, sizeof (struct route));
	    at->start = start;
	    at->ziel = ziel;
	    akraum=cargospace;
	    for (k = 0; k < 10; k++)
	      if (((start->prvol[k][0]) > 0) && ((ziel->prvol[k][1]) > 0) &&
		  ((ziel->prvol[k][3] - (start->prvol[k][2])) > 0) 
		  && conv->inhandel[k])
		{
		  at->handel[k][0] = min (credits / start->prvol[k][2], 
					  min(conv->inhandel[k], 
					      min (akraum, 
						   min (start->prvol[k][0], 
							ziel->prvol[k][1]))));
		  if (at->handel[k][0]!=conv->inhandel[k]) {
		    printf("%s %d\n", gueter[k], at->handel[k][0]);
		    fprintf(stderr, "WARNUNG: Convoyroute nicht in Ordnung!\n");
		  }
		  at->handel[k][1] = (ziel->prvol[k][3] - (start->prvol[k][2]));
		  at->handel[k][2] = (at->handel[k][0]) * (at->handel[k][1]);
		  at->gpr += at->handel[k][2];
		  at->cargo += at->handel[k][0];
		  start->prvol[k][0] = start->prvol[k][0] - at->handel[k][0];
		  ziel->prvol[k][1] = ziel->prvol[k][1] - at->handel[k][0];
		  akraum -= at->handel[k][0];
		  credits -= (at->handel[k][0]) * (start->prvol[k][2]);
		  at->invest += (at->handel[k][0]) * (start->prvol[k][2]);
		}
	    at->dist = dist;
	    insertatt (at);
	    credits += (at->invest + at->gpr);
	  }
	break;
      case '3':
	new=defaultroute;
	fprintf (stderr, "ID: ");
	scanf ("%s", rout);
	new.num=strdup(rout);
	
	fprintf (stderr, "Startplanet: ");
	scanf ("%s %d", rout, &num);
	new.start = findplanet (rout, num);
	
	fprintf (stderr, "Zielplanet: ");
	scanf ("%s %d", rout, &num);
	new.ziel = findplanet (rout, num);
	
	if ((new.start == new.ziel) || (new.start == NULL) || (new.ziel == NULL)) {
	  fprintf (stderr, "Illegale Route!\n");
	  break;
	}
	fprintf(stderr,"Outbound:\n");
	for (k=0; k<14; k++) {
	  fprintf(stderr, "%s :", gueter[k]);
	  scanf("%d",&(new.outhandel[k]));
	}
	fprintf(stderr,"Inbound:\n");
	for (k=0; k<14; k++) {
	  fprintf(stderr, "%s :", gueter[k]);
	  scanf("%d",&(new.inhandel[k]));
	}
	newroute(new);
	break;
      case '4':
	AVLinfixKey(conroutes, (void *)printcroutes, (void *)NULL);
	break;
      }
  }
}

dotrade ()
{
  int i, quit = 0, test;
  char menuwahl;
  int wahl;
  int goods[10];
  struct rt traderoute;
  FILE *file;

  while (!quit)
    {
      fprintf (stderr, "\n 1 - Drucke moegliche Routen\n 2 - Drucke bestehende Handelsrouten\n");
      fprintf (stderr, " 3 - Handel bestimmte Gueter\n 4 - Automatischer Handel\n");
      fprintf (stderr, " 5 - Drucke Handelsrouten auf File\n");
      fprintf (stderr, " 6 - Drucke alle moeglichen Routen auf File\n");
      fprintf (stderr, " 7 - Letzte Handelsroute wieder loeschen\n");
      fprintf (stderr, " 8 - Beste Handelsroute je Ware\n");
      fprintf (stderr, " 9 - Aendere Transportkapazitaet (%d)\n", maxcargo);
      fprintf (stderr, " A - Convoyrouten\n");
      fprintf (stderr, " B - Angegebene Mengen handeln\n");
      
      fprintf (stderr, "\n0 - ENDE\n\nIhre Wahl: ");
      menuwahl = 0;
      while ((menuwahl < '0') || (menuwahl > 'B')) {
	scanf ("%c", &menuwahl);
      }
      switch (menuwahl)
	{
	case '0':
	  quit = 1;
	  break;
	case '1':
          search();
	  printroutes (rroot, stdout, NOSUM, NOPRINTER);
	  break;
	case '2':
	  printroutes (troot, stdout, SUM, NOPRINTER);
	  break;
	case '3':
          search();
	  for (i = 0; i < 10; i++)
	    goods[i] = 0;
	  test = 0;
	  while (!test)
	    {
	      fprintf (stderr, "Moegliche Gueter:\n");
	      for (i = 0; i < 10; i++)
		{
		  if (goods[i]==0)
		    fprintf (stderr, "%2d) - %s\n", i + 1, gueter[i]);
		}
	      fprintf (stderr, "\n55 - Alles\n");
	      fprintf (stderr, "\n 0 - Fertig\n\nIhre Wahl: ");
	      wahl = 99;
	      while ((wahl < 0) || ((wahl > 10) && (wahl != 55)))
		scanf ("%d", &wahl);
	      if (wahl > 0)
		{
		  if (wahl == 55)
		    for (i = 0; i < 10; i++)
		      goods[i] = 1;
		  else
		    goods[wahl - 1] = 1;
		  test = 1;
		  for (i = 0; i < 10; i++)
		    test *= goods[i];
		}
	      else
		test = 1;
	    }
	  if (askroute (&traderoute))
	    trade (&traderoute, TRADE, goods, cargospace);
	  break;
	case '4':
          search ();
	  if (askroute (&traderoute))
	    trade (&traderoute, AUTOTRADE, NULL, cargospace);
	  break;
	case '5':
	  file = fopen (HANDELFILE, "w");
	  printroutes (troot, file, SUM, PRINTER);
	  fclose (file);
	  break;
	case '6':
          search ();
	  file = fopen (ROUTENFILE, "w");
	  printroutes (rroot, file, NOSUM, PRINTER);
	  fclose (file);
	  break;
	case '7':
	  rmlasttroute(troot);
	  break;
	case '8':
	  search2();
	  joinroutes();
	  file = fopen (WARENFILE, "w");
	  printroutes (rroot2, file, NOSUM, PRINTER);
	  fclose (file);
	  break;
	case '9':
          fprintf (stderr, "\nMaximale Transportkapazitaet: ");
          scanf ("%d", &maxcargo);
          break;
	case 'A':
	  convoyroutes();
	  break;
	default:
	  break;
	}			/* switch */
    }				/* while */
}

main ()
{
  on_exit(output);
  fprintf (stderr, "Handel v%s von Marcus Horstmann\n(%s)\n\n", VERSION, ALLIANZ);
  if (!readfile ())
    exit (10);
  LoadConvoy(CONVOYROUTEN);
  
  fprintf (stderr, "Maximale Entfernung in einem Zug: ");
  scanf ("%d", &maxdist);
  fprintf (stderr, "\nStaatskasse: ");
  scanf ("%d", &credits);
  fprintf (stderr, "\nMindestgewinn pro Route: ");
  scanf ("%d", &minwin);
  fprintf (stderr, "\nMindestgewinn pro Ware: ");
  scanf ("%d", &minpr);
  fprintf (stderr, "\nMaximale Transportkapazitaet: ");
  scanf ("%d", &maxcargo);
  dotrade ();
  output ();
  fprintf (stderr, "\nEs lebe die %s !!!\n\n", ALLIANZ);
}

