/*
[SKEL-TDL v1.6] Top Downloaders Lister

/**********************/
/*****  Includes  *****/
/**********************/

#include <proto/all.h>
#include <stdio.h>
#include <exec/memory.h>

#include <string.h>
#include <skeleton/commas.h>
#include <Tempest/Headers.h>
#include <Tempest/Skel-Data.h>

VOID Sort(VOID);
VOID Print(VOID);

/************************/
/*****  Structures  *****/
/************************/

struct Downloads
 {
  char   Handle[31],Location[31];
  long   BytesUL,BytesDL;
  USHORT TimesCalled;
 };
struct Downloads *DOWN;
struct User User;
struct SKEL SKEL;

/*******************************/
/*****  Global Varialbes  ******/
/*******************************/

char  string[200],OUTPATH[200],shit1[200];
int   RANK;
float Percent;

/**************************/
/*****  Main Program  *****/
/**************************/

void main(int argc,char *argv[])
{
 int stat,slot = 0,fd;
 sprintf(shit1,"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"");
 if(argc != 4 )
  {
   PutStr("\n[m[1m    _______ _________\n");
   PutStr("   / ___/ [4m/[m[1m/ / ___/ /    [[32mSKEL-TDL v3.29[m[1m] - [3mTop Downloaders Lister[m\n");
   PutStr("[1m  [4m/[m[1m__  /   _/ ___/ [4m/[m[1m__\n");
   PutStr("[1m [4m/[m[1m____[4m/[m[1m_/\\_[4m)[m[1m____[4m/[m[1m____/   For Tempest BBS - [Programmer: Michael Bockert]\n");
   PutStr(shit1);
   PutStr("\n[m   USAGE: SKEL-TDL OutFile [#] BBS:\n");
   PutStr(" EXAMPLE: SKEL-TDL RAM:TEST 12 BBS:\n\n");
   PutStr("[OutFile] Path & Name of the created file\n");
   PutStr("      [#] Number of Users you want listed\n");
   PutStr("   [BBS:] Path of Accounts.Data File\n\n");
   exit(0);
  }
 strcpy(OUTPATH,argv[1]);
 RANK   = atoi(argv[2]);
 if(!(DOWN=(struct Downloads *)AllocVec((ULONG)sizeof(struct Downloads)*(RANK),MEMF_PUBLIC | MEMF_CLEAR)))
  {
   PutStr("\nCan't Allocate Memory\n");
   exit(0);
  }

/*********************************/
/*****  Load Skel-Data.Data  *****/
/*********************************/

 sprintf(string,"%sSetup/Skel-Data.Data",argv[3]);
 fd=Open(string,MODE_OLDFILE);
 if(fd==0)
  {
   PutStr("Skel-Data.Data not found!\n");
   setmem(&SKEL,sizeof(struct SKEL),NULL);
  }
 else
  {
   Read(fd,(char *)&SKEL, sizeof(struct SKEL));
   Close(fd);
  }

/********************************/
/*****  Load Accounts.Data  *****/
/********************************/

 sprintf(string,"%sAccounts.data",argv[3]);
 fd=Open(string,MODE_OLDFILE);
 if(fd==0)
  {
   PutStr("\nAccounts.data not found.\n");
   FreeVec(DOWN);
   exit(0);
  }
 NEXTFILE:
 stat=Read(fd,(char *)&User, sizeof(struct User));
 slot++;
 if(stat <=0 )
  {
   Close(fd);
   if(RANK>slot)
     RANK=slot-1;
   Print();
   PutStr("\nSKEL-TDL Done!\n");
   FreeVec(DOWN);
   exit(0);
  }
 Sort();
 goto NEXTFILE;
}

/***************************/
/*****  Download Sort  *****/
/***************************/

VOID Sort(VOID)
{
 register int x =0,y,HOLDER;
 do
  {
   if((User.Slot_Number==1)||(User.Status!=1)||(User.Total_DLBytes<1000000L))
       break;
   if(User.Total_DLBytes >= DOWN[x].BytesDL)  /* move other entries down one */
    {
     HOLDER = x;
     y=0;
     while(x+1<RANK)
      {
       y++;
       CopyMem(&DOWN[RANK-(y+1)],&DOWN[RANK-y],sizeof(struct Downloads));
       x++;
      }
     x=HOLDER;
     strcpy(DOWN[x].Handle,User.Name);
     strcpy(DOWN[x].Location,User.City);
     DOWN[x].BytesUL     = User.Total_ULBytes;
     DOWN[x].BytesDL     = User.Total_DLBytes;
     DOWN[x].TimesCalled = User.Total_Calls;
     return;
    }
   x++;
  }
 while(x < RANK);
}

/********************/
/*****  Output  *****/
/********************/

VOID Print(VOID)
{
 register int x=0;
 char Ratio2[40];
 float Ratio;
 FILE *out2;
 out2=fopen(OUTPATH,"w");
 if(out2==NULL)
  {
   PutStr("Error writing output file!\n");
   FreeVec(DOWN);
   exit(0);
  }
 fprintf(out2,"\f~+[35m[[33mSKEL-TDL[35m] [36mTop Downloaders Lister By Michael Bockert\n");
 fprintf(out2,"[34m%s\"\"\"\"\"\"\"\n",shit1);
 fprintf(out2,"  [0m#  Alias/Handle             DL Bytes Percent Ratio Calls Location/Group\n");
 fprintf(out2,"[34m====-==================-==============-=======-=====-=====-====================\n");
 strcpy(shit1,"-----------------------------");
 do
  {
   Ratio = (float) DOWN[x].BytesDL / DOWN[x].BytesUL;
   if((Ratio>3.00) && (DOWN[x].BytesDL > 1000000L))
      strcpy(Ratio2,"[34mLEECH");
   else
    {
     if((Ratio < 0.16) && (Ratio >= 0.00) && (DOWN[x].BytesUL >= 5000000L))
         strcpy(Ratio2,"[33mELITE");
     else
         sprintf(Ratio2,"%4.2f",Ratio);
    }
   Percent = (float) (DOWN[x].BytesDL / 1024L) / (SKEL.TotalDLKB / 100L);
   if(strlen(DOWN[x].Handle) > 2)
    {
     fprintf(out2,"[0m%3d. [36m%-18.18s [35m[[32m%13s [31m%5.2f[32m%[35m] [36m%5s [0m%4d  [31m%-20.20s\n",
         x+1,DOWN[x].Handle,commas(DOWN[x].BytesDL,buff),Percent,Ratio2,DOWN[x].TimesCalled,DOWN[x].Location);
    }
   x++;
  }
 while(x<RANK);
 fprintf(out2,"[34m.%s.-.-------------.-.%s.\n",shit1,shit1);
 fprintf(out2,"[34m| [36mULed Files   [35m[[0m%9s[35m]    [34m|[33m=[34m| [36mUsers [35m[[0m%3d[35m] [34m|[33m=[34m| [36mDLed Files   [35m[",
                               commas(SKEL.TotalUL,buff),SKEL.TotalUsers);
 fprintf(out2,"[0m%9s[35m]    [34m|\n",commas(SKEL.TotalDL,buff));
 fprintf(out2,"[34m| [36mULed Bytes [35m[[0m%11s[35m] [32mKB [34m| `-------------' | [36mDLed Bytes [35m[",
                            commas(SKEL.TotalULKB,buff));
 fprintf(out2,"[0m%11s[35m] [32mKB [34m|\n",commas(SKEL.TotalDLKB,buff));
 fprintf(out2,"[34m`%s'                 `%s'[0m~r\n",shit1,shit1);
 fclose(out2);
}
