// REPORT.C - Creating Report-Files
// Written by Stefan Pfeiffer, DL1ELY, 950725
// Last modification: 951213
// (C) 1995 by Stefan Pfeiffer, DL1ELY@DB0PKE.#NRW.DEU.EU

#include "report.h"
#include "dvideo.h"
#include "global.h"
#include "database.h"
#include "string.h"
#include "auswert.h"
#include "structs.h"


void print_statistics(void);
void init_statistics(void);
void paint_sel(char, char);
void do_preview(void);

void allgemein(FILE *, char);
void qsos_ueber(FILE *, char, unsigned);
void zeitverlauf(FILE *, char);
void laender(FILE *, char);
void grossfelder_liste(FILE *, char);
void grossfelder_karte(FILE *, char);
void top_ten_grossfelder_qsos(FILE *, char);
void top_ten_grossfelder_punkte(FILE *, char);
void top_five_stunden_qsos(FILE *, char);
void top_five_stunden_punkte(FILE *, char);
void entfernungen(FILE *, char);


unsigned km_grenze;


extern unsigned char activebuttoncol;
extern unsigned char passivebuttoncol;
extern struct definition *act_def;
extern char fn_path[128];


#define STAT_CNT 11

struct report_des report[STAT_CNT];


void init_statistics()
{
   char i;

   for(i=0;i<STAT_CNT;i++)
   {
      report[i].code = i+1;
      report[i].pos = 0;
   };

   strcpy(report[0].name,"General overview");
   strcpy(report[1].name,"QSOs over %s km");
   strcpy(report[2].name,"Points/QSOs every hour");
   strcpy(report[3].name,"Logged countries");
   strcpy(report[4].name,"Logged squares (list)");
   strcpy(report[5].name,"Logged squares (map)");
   strcpy(report[6].name,"Top Ten of squares by QSOs");
   strcpy(report[7].name,"Top Ten of squares by points");
   strcpy(report[8].name,"Top Five of hours by QSOs");
   strcpy(report[9].name,"Top Five of hours by points");
   strcpy(report[10].name,"Points/QSOs by distance");
};



void print_statistics()
{
   char i;
   char hlp[6];

   dfill(2,4,39,lastline-5,' ',menucol);
   dfill(43,4,lastrow,lastline-5,' ',menucol);

   for(i=0;i<STAT_CNT;i++)
   {
      if(i!=1) dprint(3,report[i].code+3,menucol,report[i].name);
      else dprintf(3,report[i].code+3,menucol,report[i].name,"x");
      if(report[i].pos) dprint(2,report[i].code+3,menucol,"*");
   };

   for(i=0;i<STAT_CNT;i++)
   {
      if(report[i].pos)
      {
         if(i!=1) dprint(43,3+report[i].pos,menucol,report[i].name);
         else
         {
            sprintf(hlp,"%d",km_grenze);
            dprintf(43,3+report[i].pos,menucol,report[i].name,hlp);
         };
      };
   };
};

void paint_sel(char sel, char act)
{
   if(sel < 15) dcolor(1,sel,38,sel,act?menuinvcol:menucol);
   else
   switch(sel)
   {
      case 15:
         paint_but(20,lastline-2," Create ",act?activebuttoncol:passivebuttoncol,menucol);
         break;
      case 16:
         paint_but(36,lastline-2,"Preview",act?activebuttoncol:passivebuttoncol,menucol);
         break;
      case 17:
         paint_but(50,lastline-2," Abort ",act?activebuttoncol:passivebuttoncol,menucol);
         break;
   };
};

#pragma warn -par

void allgemein(FILE *f, char preview)
{
  struct qso *hlp;

  fprintf(f,"\noverview:\n\n");

  fprintf(f,"     contest results %s - %s\n\n",h.owncall,h.desc);
  fprintf(f,"  band                 : %s\n\n",act_def->band);
  fprintf(f,"  locator              : %s\n",h.ownloc);
  fprintf(f,"  total QSOs           : %d",h.qso_cnt);
  if(h.invalid) fprintf(f," (%d invalid)",h.invalid);
  fprintf(f,"\n  points               : %ld\n",h.points);
  fprintf(f,"  points/QSO           : %d\n\n",h.average);
  fprintf(f,"  logged WAE-countries : %d\n",h.countries);
  fprintf(f,"  logged squares       : %d\n\n",h.squares);

  for(hlp = firstqso;strcmp(hlp->call,h.ODX_call) && hlp; hlp = hlp->next);
 
  if(hlp) fprintf(f,"  ODX: %s in %s (%d km) at %02d:%02d UTC\n\n",hlp->call,hlp->locator,hlp->points,hlp->hour,hlp->min);
};

void qsos_ueber(FILE *f, char preview, unsigned grenze)
{
   struct qso *q;
   unsigned cnt = 0;

   fprintf(f,"\nQSOs over %dkm:\n\n",grenze);
   fprintf(f,"   UTC   callsign      locator   QRB   remarks\n");
   fprintf(f,"  ===============================================================\n");

   q = firstqso;
   while(q)
   {
      if(q->points>grenze)
      {
         cnt++;
         fprintf(f,"  %02d:%02d  %-12s  %s  %4dkm\n",q->hour,q->min,q->call,q->locator,q->points);
      };
      q = q->next;
   };
   if(!cnt) fprintf(f,"  NONE!\n");
   else fprintf(f,"\n  %d QSO%s over %dkm in total\n",cnt,cnt==1?"":"s",grenze);

   fprintf(f,"\n");
};

void zeitverlauf(FILE *f, char preview)
{
   unsigned qsos[24];
   unsigned long points[24];
   struct qso *q;
   float prozent;
   unsigned char i;
   unsigned char gap;
   char cnt = 0;

   gap = 1;
   q = firstqso;
   memset(qsos,0,sizeof(qsos));
   memset(points,0,sizeof(points));
   while(q)
   {
      if(q->points)
      {
         qsos[q->hour]++;
         points[q->hour]+=q->points;
      };
      q = q->next;
   };

   fprintf(f,"\nlogged QSOs and points every hour:\n\n");

   for(i=14;i<24;i++)
   {
      if(qsos[i])
      {
         fprintf(f,"  %02d:00 - %02d:59:%3d QSO%c ",i,i,qsos[i],qsos[i]==1?' ':'s');
         prozent = (float)qsos[i]*100/h.qso_cnt;
         if(prozent>=10.0) fprintf(f,"(%2.1f%%)",prozent);
         else fprintf(f,"( %1.1f%%)",prozent);
         fprintf(f," with %6ld points ",points[i]);
         prozent = (float)points[i]*100/h.points;
         if(prozent>=10.0) fprintf(f,"(%2.1f%%)\n",prozent);
         else fprintf(f,"( %1.1f%%)\n",prozent);
         gap = 1;
         cnt++;
      }
      else
      if(gap)
      {
         fprintf(f,"\n");
         gap = 0;
      };
   };

   for(i=0;i<14;i++)
   {
      if(qsos[i])
      {
         fprintf(f,"  %02d:00 - %02d:59:%3d QSO%c ",i,i,qsos[i],qsos[i]==1?' ':'s');
         prozent = (float)qsos[i]*100/h.qso_cnt;
         if(prozent>=10.0) fprintf(f,"(%2.1f%%)",prozent);
         else fprintf(f,"( %1.1f%%)",prozent);
         fprintf(f," with %6ld points ",points[i]);
         prozent = (float)points[i]*100/h.points;
         if(prozent>=10.0) fprintf(f,"(%2.1f%%)\n",prozent);
         else fprintf(f,"( %1.1f%%)\n",prozent);
         gap = 1;
         cnt++;
      }
      else
      if(gap)
      {
         fprintf(f,"\n");
         gap = 0;
      };
   };
   if(gap) fprintf(f,"\n");
   fprintf(f,"  operating %d of 24 hours\n\n",cnt);
};

void laender(FILE *f, char preview)
{
  unsigned border, max;
  struct countryinfo *hlp;
  float prozent;

  fprintf(f,"\nlogged WAE-countries:\n\n");

  border = 65000;
  do
  {
    hlp = firstcountry;
    max = 0;
    while(hlp)
    {
      if(hlp->worked > max && hlp->worked < border) max = hlp->worked;
      hlp = hlp->next;
    };
    border = max;

    hlp = firstcountry;
    while(hlp && max)
    {
       if(hlp->worked == max)
       {
          fprintf(f,"  %-20s - %3d QSO%c ",hlp->name_eng,max,max==1?' ':'s');
          prozent = (float)max*100/h.qso_cnt;
          if(prozent>=10.0) fprintf(f,"(%2.1f%%)",prozent);
          else fprintf(f,"( %1.1f%%)",prozent);
          fprintf(f," with %6ld points ",hlp->points);
          prozent = (float)hlp->points*100/h.points;
          if(prozent>=10.0) fprintf(f,"(%2.1f%%)\n",prozent);
          else fprintf(f,"( %1.1f%%)\n",prozent);
       };
       hlp = hlp->next;
    };
  } while(max);

  fprintf(f,"\n  %d WAE-countries in total\n\n",h.countries);
};

void grossfelder_liste(FILE *f, char preview)
{
   char act_sq[3];
   char cnt;
   unsigned char x, y;
   struct squareinfo *sq;


   fprintf(f,"\nlist of logged squares:\n");

   for(y=0;y<4;y++)
   {
      for(x=0;x<5;x++)
      {
         sprintf(act_sq,"%c%c\0",'H'+x,'P'-y);
         cnt = 0;
         sq = firstsquare;
         while(sq)
         {
            if(!strncmp(act_sq,sq->name,2))
            {
               if(!cnt) fprintf(f,"\n  %s: ",act_sq);
               fprintf(f,"%s ",sq->name+2);
               cnt++;
               if(!(cnt%24)) fprintf(f,"\n      ");
            };
            sq = sq->next;
         };
      };
   };

   fprintf(f,"\n\n  %d squares in total\n\n",h.squares);
};

void grossfelder_karte(FILE *f, char preview)
{
   struct squareinfo *sq;
   int x, y;
   int xmax, xmin;
   int ymax, ymin;
   int x_pos, y_pos;
   int own_x, own_y;
   char ende;

   xmin = 100;
   xmax = -100;
   ymin = 100;
   ymax = -100;

   loc2rel(h.ownloc,&own_x,&own_y);

   sq = firstsquare;
   while(sq)
   {
      loc2rel(sq->name,&x,&y);

      if(x<xmin) xmin = x;
      if(x>xmax) xmax = x;
      if(y<ymin) ymin = y;
      if(y>ymax) ymax = y;

      sq = sq->next;
   };
   if(xmax-xmin>15) xmax=xmin+15;

   fprintf(f,"\nmap of logged squares:\n\n");

   for(y_pos=ymin;y_pos<=ymax;y_pos++)
   {
      for(x_pos=xmin;x_pos<=xmax;x_pos++)
      {
         ende = 0;
         for(sq=firstsquare;sq && (!ende);)
         {
            loc2rel(sq->name,&x,&y);
            ende = ((x == x_pos) && (y == y_pos));
            if(!ende) sq = sq->next;
         };
         if((x_pos == own_x) && (y_pos == own_y)) fprintf(f,"<");
         else
            if((x_pos == own_x+1) && (y_pos == own_y)) fprintf(f,">");
            else
               if(x_pos%10) fprintf(f," ");
               else fprintf(f,"³");
         if(sq) fprintf(f,"%s",sq->name);
         else fprintf(f,"    ");
      };

      if(!(x_pos%10)) fprintf(f,"³");
      fprintf(f,"\n");
      if(!(y_pos%10))
      {
         for(x=xmin;x<=xmax;x++)
         {
            if(x%10) fprintf(f,"Ä");
            else fprintf(f,"Å");
            fprintf(f,"ÄÄÄÄ");
         };
         if(!(x%10)) fprintf(f,"Å");
         fprintf(f,"\n");
      };
   };

         
   fprintf(f,"\n  %d squares in total\n\n",h.squares);
};

void top_ten_grossfelder_qsos(FILE *f, char preview)
{
   unsigned border, max;
   struct squareinfo *sq;
   unsigned char cnt;
   float prozent;


   border = 65000;
   cnt = 0;
   fprintf(f,"\nTop Ten squares by QSOs:\n\n");

   do
   {
      max = 0;

      sq = firstsquare;
      while(sq)
      {
         if(sq->worked > max && sq->worked < border) max = sq->worked;
         sq = sq->next;
      };

      if(max)
      {
         sq = firstsquare;
         while(sq && cnt<10)
         {
            if(sq->worked == max)
            {
               fprintf(f,"  %s:%3d QSO%c ",sq->name,sq->worked,sq->worked>1?'s':' ');
               prozent = (float)max*100/h.qso_cnt;
               if(prozent>=10.0) fprintf(f,"(%2.1f%%)\n",prozent);
               else fprintf(f,"( %1.1f%%)\n",prozent);

               cnt++;
            };
            sq = sq->next;
         };
         border = max;
      };
   } while (max && cnt<10);

   fprintf(f,"\n  %d squares in total\n\n",h.squares);
};

void top_ten_grossfelder_punkte(FILE *f, char preview)
{
   struct squareinfo *sq;
   unsigned border, max;
   unsigned char cnt;
   float prozent;

   border = 65000;
   cnt = 0;
   fprintf(f,"\nTop Ten squares by points:\n\n");

   do
   {
      max = 0;

      sq = firstsquare;
      while(sq)
      {
         if(sq->points > max && sq->points < border) max = sq->points;
         sq = sq->next;
      };
 
      if(max)
      {
         sq = firstsquare;
         while(sq && cnt<10)
         {
            if(sq->points == max)
            {
               fprintf(f,"  %s:%6ld points ",sq->name,sq->points);
               prozent = (float)max*100/h.points;
               if(prozent>=10.0) fprintf(f,"(%2.1f%%)\n",prozent);
               else fprintf(f,"( %1.1f%%)\n",prozent);

               cnt++;
            };
            sq = sq->next;
         };
         border = max;
      };
   } while (max && cnt<10);

   fprintf(f,"\n  %d squares in total\n\n",h.squares);
};

void top_five_stunden_qsos(FILE *f, char preview)
{
   struct qso *q;
   unsigned qsos[24];
   unsigned border, max, cnt;
   unsigned char i;
   float prozent;

   cnt = 0;
   q = firstqso;
   memset(qsos,0,sizeof(qsos));
   while(q)
   {
      if(q->points) qsos[q->hour]++;
      q = q->next;
   };

   border = 65000;

   fprintf(f,"\nBest five hours by QSOs:\n\n");

   do
   {
      max = 0;
      for(i=0;i<24;i++) if((qsos[i]>max) && (qsos[i]<border)) max = qsos[i];

      if(max)
      {
         for(i=0;i<24;i++) if(qsos[i]==max)
         {
            fprintf(f,"  %02d:00 - %02d:59 :%3d QSOs ",i,i,max);
            prozent = (float)max*100/h.qso_cnt;
            if(prozent>=10.0) fprintf(f,"(%2.1f%%)\n",prozent);
            else fprintf(f,"( %1.1f%%)\n",prozent);
            cnt++;
         };
         border = max;
      };
   } while(max&&cnt<5);

   fprintf(f,"\n");
};

void top_five_stunden_punkte(FILE *f, char preview)
{
   struct qso *q;
   unsigned long points[24];
   unsigned long border, max;
   unsigned cnt;
   unsigned char i;
   float prozent;

   cnt = 0;
   q = firstqso;
   memset(points,0,sizeof(points));
   while(q)
   {
      if(q->points) points[q->hour]+=q->points;
      q = q->next;
   };

   border = 100000;

   fprintf(f,"\nBest five hours by points:\n\n");

   do
   {
      max = 0;
      for(i=0;i<24;i++) if((points[i]>max) && (points[i]<border)) max = points[i];

      if(max)
      {
         for(i=0;i<24;i++) if(points[i]==max)
         {
            fprintf(f,"  %02d:00 - %02d:59 :%6ld points ",i,i,max);
            prozent = (float)max*100/h.points;
            if(prozent>=10.0) fprintf(f,"(%2.1f%%)\n",prozent);
            else fprintf(f,"( %1.1f%%)\n",prozent);
            cnt++;
         };
         border = max;
      };
   } while(max&&cnt<5);

   fprintf(f,"\n");
};

void entfernungen(FILE *f, char preview)
{
   unsigned qsos[21];
   unsigned long points[21];
   struct qso  *q;
   unsigned char pos;

   memset(qsos,0,sizeof(qsos));
   memset(points,0,sizeof(points));

   q = firstqso;
   while(q)
   {
      if(q->points > 0)
      {
         pos = (unsigned char)(q->points/50);
         if(pos > 20) pos = 20;
         qsos[pos]++;
         points[pos]+=q->points;
      };
      q = q->next;
   };
  
   fprintf(f,"\nQSOs by covered distance per QSO:\n\n");

   fprintf(f,"  ");
   for(pos=0;pos<10;pos++)
      fprintf(f,"%3d - ",pos*50);
   fprintf(f,"500km\n");

   fprintf(f,"     ");
   for(pos=0;pos<9;pos++)
      if(qsos[pos]<10) fprintf(f," %d    ",qsos[pos]);
      else fprintf(f,"%3d   ",qsos[pos]);
   if(qsos[9]<10) fprintf(f," %d        QSOs\n\n",qsos[9]);
   else fprintf(f,"%3d       QSOs\n\n",qsos[9]);

   fprintf(f,"  ");
   for(pos=10;pos<20;pos++)
      fprintf(f,"%3d - ",pos*50);
   fprintf(f,"1000km\n");

   fprintf(f,"     ");
   for(pos=10;pos<20;pos++)
      if(qsos[pos]<10) fprintf(f," %d    ",qsos[pos]);
      else fprintf(f,"%3d   ",qsos[pos]);
   fprintf(f,"%3d QSOs\n\n",qsos[20]);

  
   fprintf(f,"\nPoints by covered distance per QSO:\n\n");

   fprintf(f,"  ");
   for(pos=0;pos<10;pos++)
      fprintf(f,"%3d - ",pos*50);
   fprintf(f,"500km\n");

   fprintf(f,"    ");
   for(pos=0;pos<9;pos++)
   {
      if(points[pos]<1000)
      {
         if(points[pos]<100) fprintf(f,"%3ld   ",points[pos]);
         else fprintf(f," %3ld  ",points[pos]);
      }
      else
      {
         points[pos]+=50;
         fprintf(f," %1ldk%1ld  ",points[pos]/1000,(points[pos]%1000)/100);
      };
   };
   
   if(points[9]<1000)
   {
      if(points[pos]<100) fprintf(f,"%3ld         points\n\n",points[9]);
      else fprintf(f," %3ld        points\n\n",points[9]);
   }
   else
   {   
      points[9]+=50;
      fprintf(f," %1ldk%1ld      points\n\n",points[9]/1000,(points[9]%1000)/100);
   }; 
   
   fprintf(f,"  ");
   for(pos=10;pos<20;pos++)
      fprintf(f,"%3d - ",pos*50);
   fprintf(f,"1000km\n");

   fprintf(f,"   ");
   for(pos=10;pos<20;pos++)
   {
      if(points[pos]<1000)
      {
         if(points[pos]<100) fprintf(f," %3ld  ",points[pos]);
         else  fprintf(f,"  %3ld ",points[pos]);
      }
      else
      {
         points[pos]+=50;
         fprintf(f,"  %1ldk%1ld ",points[pos]/1000,(points[pos]%1000)/100);
      };
   };

   if(points[20]<100) fprintf(f," %2ld  points\n\n",points[20]);
   else
   { 
      points[20]+=50;
      fprintf(f," %1ldk%1ld points\n\n",points[20]/1000,((points[20]%1000)+50)/100);
   };

};

#pragma warn +par

void do_preview()
{
   FILE *f;
   unsigned i, pos;
   char *text[512];
   unsigned lines;
   char s[256];
   void *save;
   char ch;
   char fname[256];

   generate_path(fn_path,"$$$$$$$$.59","",fname);
   if((f = fopen(fname,"wt")) == NULL)
   {
      ok_box("Error","Temporary file cannot be created!");
      return;
   };


   pos = 0;
   do
   {
      pos++;
      i = 0;
      while((i<STAT_CNT) && (report[i].pos!=pos)) i++;

      if(i<STAT_CNT)
      {
         switch(report[i].code)
         {
            case 1:
               allgemein(f,1);
               break;
            case 2:
               qsos_ueber(f,1,km_grenze);
               break;
            case 3:
               zeitverlauf(f,1);
               break;
            case 4:
               laender(f,1);
               break;
            case 5:
               grossfelder_liste(f,1);
               break;
            case 6:
               grossfelder_karte(f,1);
               break;
            case 7:
               top_ten_grossfelder_qsos(f,1);
               break;
            case 8:
               top_ten_grossfelder_punkte(f,1);
               break;
            case 9:
               top_five_stunden_qsos(f,1);
               break;
            case 10:
               top_five_stunden_punkte(f,1);
               break;
            case 11:
               entfernungen(f,1);
               break;
         };
      };
   } while(i<STAT_CNT);

   fprintf(f,"\n  This report was compiled by FiveNine %s\n  (C) 1995 by %s\n\n",VERSION,AUTHOR);
   fclose(f);

   memset(text,0,2048);
   lines = 0;
   f = fopen(fname,"rt");
   while(!feof(f))
   {
      fgets(s,256,f);
      if(s[strlen(s)-1] == '\n') s[strlen(s)-1] = 0;
      text[lines] = sec_alloc(strlen(s)+1);
      strcpy(text[lines],s);
      lines++;
   };
   fclose(f);

   save = dsave(0,0,79,lastline);

   pos = 0;
   dfill(0,1,79,lastline,' ',textcol);
   dfill(0,0,79,0,' ',titlecol);
   i = pos+lastline+1;
   dprintf(2,0,titlecol,"%3d/%3d %s",i<lines?i:lines,lines,"lines");
   dprint(51,0,titlecol,"Cursor-keys, <ESC> = quit");
   
   for(i=0;i<lastline;i++)
      if(text[i+pos]) dprint(0,i+1,textcol,text[i+pos]);

   do
   {
      ch = getch();
      if(!ch)
      {
         ch = getch();
         switch(ch)
         {
            case 72:   // cursor-up
               if(pos)
               {
                  dmove(0,1,79,lastline-1,0,2);
                  pos--;
                  i = pos+lastline+1;
                  dprintf(2,0,titlecol,"%3d",i<lines?i:lines);
                  dfill(0,1,79,1,' ',textcol);
                  dprint(0,1,textcol,text[pos]);
               };
               break;
            case 80:   // cursor-down
               if((pos<lines-lastline-1) && (lines>lastline))
               {
                  dmove(0,2,79,lastline,0,1);
                  pos++;
                  i = pos+lastline+1;
                  dprintf(2,0,titlecol,"%3d",i<lines?i:lines);
                  dfill(0,lastline,79,lastline,' ',textcol);
                  dprint(0,lastline,textcol,text[pos+lastline-1]);
               };
               break;
         };
      };
   } while(ch!=27);

   for(i=0;i<lines;i++) sec_free(text[i]);

   drestore(save);
   sec_free(save);
   unlink(fname);
};


void do_report()
{
   void *save;
   char s[80];
   char ch;
   char sel;
   char ende = 0;
   char i;
   char sel_cnt = 0;
   char res;
   void *save2;
   struct qso *q;
   unsigned cnt;
   FILE *f;
   char pos;
   char hlp[40];

   save = dsave(0,0,lastrow,lastline);

   dfill(0,0,79,0,' ',titlecol);
   sprintf(s,"%s %s - %s",PRGNAME,VERSION,"report creation");
   dprint(40-(strlen(s)>>1),0,titlecol,s);
   dfill(0,1,lastrow,lastline,' ',menucol);
   dfill(40,1,40,lastline-5,179,menucol);

   strcpy(s,"Possible statistics");
   dprint(20-(strlen(s)>>1),2,menucol,s);
   strcpy(s,"contest report");
   dprint(60-(strlen(s)>>1),2,menucol,s);

   init_statistics();
   print_statistics();

   paint_but(20,lastline-2," Create ",passivebuttoncol,menucol);
   paint_but(36,lastline-2,"Preview",passivebuttoncol,menucol);
   paint_but(50,lastline-2," Abort ",passivebuttoncol,menucol);

   sel = 4;

   do
   {
      paint_sel(sel,1);

      ch = getch();
      if(!ch)
      {
         ch = getch();
         switch(ch)
         {
            case 72:   // Cursor up
            case 15:   // SHIFT-TAB
               paint_sel(sel,0);
               sel--;
               if(sel<4) sel = 17;
               break;
            case 80:   // Cursor down
               paint_sel(sel,0);
               sel++;
               if(sel>17) sel = 4;
               break;
            case 75:   // Cursor left
               if(sel>14)
               {
                  paint_sel(sel,0);
                  sel--;
               };
               break;
            case 77:   // Cursor right
               if(sel>14)
               {
                  paint_sel(sel,0);
                  sel++;
                  if(sel>17) sel = 4;
               };
               break;

         };
      }
      else
      {
         if(ch == 9)
         {
            paint_sel(sel,0);
            sel++;
            if(sel>17) sel = 4;
         };
         if(ch == 27)
         {
            ende = 1;
            sel = 0;
         };
         if((ch == 13) || (ch == 32))
         {
            if(sel<15)
            {
               if(report[sel-4].pos)
               {
                  for(i=0;i<STAT_CNT;i++)
                  {
                     if(report[i].pos>report[sel-4].pos) report[i].pos--;
                  };
                  report[sel-4].pos = 0;
                  if(sel == 5) km_grenze = 0;
                  sel_cnt--;
                  print_statistics();
               }
               else
               {
                  res = 1;
                  if(sel == 5)
                  {
                     strcpy(s,"700");
                     save2 = make_win(60,5,75,8,textcol);
                     dprint(62,6,textcol,"km-border:");
                     res = input_string(62,7,11,11,DIGITS_ONLY,invcol,s);
                     drestore(save2);
                     sec_free(save2);
                     my_gotoxy(lastrow+1,lastline+1);
                     km_grenze = 0;
                     if(res) km_grenze = atoi(s);
                     
                     if(km_grenze)
                     {
                        q = firstqso;
                        cnt = 0;
                        while(q)
                        {
                           if(q->points>km_grenze) cnt++;
                           q=q->next;
                        };

                        sprintf(s,"There are %d QSO%s over %dkm.",cnt,cnt==1?"":"s",km_grenze);
                        res = ok_abort_box("Notification",s);
                     };
                  };

                  if(res)
                  {
                     sel_cnt++;
                     report[sel-4].pos = sel_cnt;
                     print_statistics();
                  };
               };
            }
            else
            switch(sel)
            {
               case 15:
                  ende = 1;
                  sel = 1;
                  break;
               case 16:
                  do_preview();
                  break;
               case 17:
                  ende = 1;
                  sel = 0;
                  break;
            };
         };
      };
   } while(!ende);

   if(sel)
   {
      save2 = make_win(30,5,70,8,textcol);
      dprint(32,6,textcol,"filename:");
      hlp[0] = 0;
      res = input_string(32,7,36,36,UPCASE|INSERT,invcol,hlp);
      drestore(save2);
      sec_free(save2);
      my_gotoxy(lastrow+1,lastline+1);

      if(!res)
      {
         drestore(save);
         sec_free(save);
         return;
      };

      generate_path(fn_path,hlp,".RPT",s);

      if((f = fopen(s,"wt")) == NULL)
      {
         ok_box("Error","File cannot be created!");
         drestore(save);
         sec_free(save);
         return;
      };


      pos = 0;
      do
      {
         pos++;
         i = 0;
         while((i<STAT_CNT) && (report[i].pos!=pos)) i++;

         if(i<STAT_CNT)
         {
            switch(report[i].code)
            {
               case 1:
                  allgemein(f,1);
                  break;
               case 2:
                  qsos_ueber(f,1,km_grenze);
                  break;
               case 3:
                  zeitverlauf(f,1);
                  break;
               case 4:
                  laender(f,1);
                  break;
               case 5:
                  grossfelder_liste(f,1);
                  break;
               case 6:
                  grossfelder_karte(f,1);
                  break;
               case 7:
                  top_ten_grossfelder_qsos(f,1);
                  break;
               case 8:
                  top_ten_grossfelder_punkte(f,1);
                  break;
               case 9:
                  top_five_stunden_qsos(f,1);
                  break;
               case 10:
                  top_five_stunden_punkte(f,1);
                  break;
               case 11:
                  entfernungen(f,1);
                  break;
            };
         };
      } while(i<STAT_CNT);

      fprintf(f,"\n  This report was compiled by FiveNine %s\n  (C) 1995 by %s\n\n",VERSION,AUTHOR);
      fclose(f);
   };

   drestore(save);
   sec_free(save);
};


