// [SKEL-TCL v1.4] Top Callers Lister

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

#include <proto/all.h>
#include <stdio.h>
#include <time.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 TopCallers
 {
  char   Name[31],Location[31];
  USHORT CallsToday,Times_Called;
  long   Time_Last;
 };
struct TopCallers *TopC;
struct User User;
struct Today Today;
struct SKEL SKEL;

//*******************************
//*****  Global Variables  ******
//*******************************

char OUTPATH[200],shit1[200];
int  RANK,TodayCalls,TodayMessages,Percent;

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

void main(int argc,char *argv[])
{
 int stat,slot = 0,fd;
 char string[255];
 sprintf(shit1,"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"");
 if(argc != 4)
  {
   PutStr("\n[m[1m    _______ _________\n");
   PutStr("   / ___/ [4m/[m[1m/ / ___/ /    [[32mSKEL-TCL v3.29[m[1m] - [3mTop Callers 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-TCL [OutFile] [Rank] [BBS Path]\n");
   PutStr(" EXAMPLE: SKEL-TCL RAM:TEST 50 TEMPEST:\n\n");
   PutStr("[OutFile] Path & Name of created file\n");
   PutStr("   [Rank] Number of Users you want listed\n");
   PutStr("[BBSPath] Path of BBS Files & Accounts.Data\n\n");
   exit(0);
  }
 strcpy(OUTPATH,argv[1]);
 RANK  = atoi(argv[2]);
 if(!(TopC=(struct TopCallers *)AllocVec((ULONG)sizeof(struct TopCallers)*(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 Runtime.Data  ******
//********************************

 sprintf(string,"%sSetup/RunTime-1.data",argv[3]);
 fd=Open(string,MODE_OLDFILE);
 if(fd==0)
  {
   PutStr("\nRuntime.data not found!\n");
   FreeVec(TopC);
   exit(0);
  }
 Read(fd,(char *)&Today, sizeof(struct Today));
 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(TopC);
   exit(0);
  }
 NEXTFILE:
 stat=Read(fd,(char *)&User, sizeof(struct User));
 if(stat<=0)
  {
   Close(fd);
   if(RANK>slot)
     RANK=slot-1;
   Print();
   PutStr("\nSKEL-TCL Done!\n");
   FreeVec(TopC);
   exit(0);
  }
 slot++;
 if(User.Time_Last_Logoff >= Today.TODAY)
  {
   TodayCalls    += User.Period_Calls;
   TodayMessages += User.Period_Posts;
  }
 Sort();
 goto NEXTFILE;
}

//*****************************
//*****  Top Caller Sort  *****
//*****************************

VOID Sort(VOID)
{
 register int x = 0,y,HOLDER;
 do
  {
   if((User.Slot_Number==1)||(User.Status!=1)||(User.Total_Calls<1))
    {
     break;  /* TO SKIP SYSOP,NEW USERS,USERS WITH LESS THAN 1 CALL  */
    }
   if(User.Total_Calls >= TopC[x].Times_Called)   /* move other entries down one */
    {
     HOLDER = x;
     y=0;
     while(x+1<RANK)
      {
       y++;
       CopyMem(&TopC[RANK-(y+1)],&TopC[RANK-y],sizeof(struct TopCallers));
       x++;
      }
     x=HOLDER;
     strcpy(TopC[x].Name,User.Name);
     strcpy(TopC[x].Location,User.City);
     TopC[x].CallsToday   = User.Period_Calls;
     TopC[x].Time_Last    = User.Time_Last_Logoff;
     TopC[x].Times_Called = User.Total_Calls;
     return;
    }
   x++;
  }
 while(x<RANK);
}

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

VOID Print(VOID)
{
 int x=0;
 char Month[50],Day[50],Year[50],string[255],Percent2[50];
 FILE *out2;
 out2=fopen(OUTPATH,"w");
 if(out2==NULL)
  {
   PutStr("Error writing output file!\n");
   FreeVec(TopC);
   exit(0);
  }
 fprintf(out2,"\f~+[33m[[0mSKEL-TCL[33m] [36mTop Callers Lister By Michael Bockert\n");
 fprintf(out2,"[34m%s\"\"\"\"\"\"\"\n",shit1);
 fprintf(out2,"  [32m#  Alias/Handle         Calls Percent  Last On   CT  Location/Group\n");
 fprintf(out2,"[34m====-==================-=======-=======--=========-==--========================\n");
 strcpy(shit1,"------------------------");
 do
  {
   strcpy(string,ctime(&TopC[x].Time_Last));
   strmid(string,Month,5,3);
   strmid(string,Day,9,2);
   strmid(string,Year,23,2);
   Percent = ((TopC[x].Times_Called * 1000L)+1L) / ((SKEL.TotalCalls+10L) / 10L);
   if(Percent <10)
      sprintf(Percent2,"0.0%d",Percent);
   else if(Percent <100)
           sprintf(Percent2,"0.%d",Percent);
        else if(Percent <1000)
              {
               sprintf(string,"%d",Percent);
               sprintf(Percent2,"%c.%c%c",string[0],string[1],string[2]);
              }
             else if(Percent <10000)
                   {
                    sprintf(string,"%d",Percent);
                    sprintf(Percent2,"%c%c.%c%c",string[0],string[1],string[2],string[3]);
                   }
   if(TopC[x].Time_Last < Today.TODAY)
    {
     TopC[x].CallsToday = 0;
    }
    if(strlen(TopC[x].Name) > 2)
     {
      fprintf(out2,"[0m%3d. [36m%-18.18s [33m[ [32m%5s [0m%5s[32m%[33m]  [37m%s %2s,%s [35m%2d  [37m%-24.24s\n",
         x+1,TopC[x].Name,commas(TopC[x].Times_Called,buff),Percent2,Month,Day,Year,TopC[x].CallsToday,TopC[x].Location);
     }
   x++;
  }
 while(x<RANK);
 fprintf(out2,"[34m.%s.-.%s.-.-----------------------.\n",shit1,shit1);
 fprintf(out2,"[34m|    [32mCalls Today  [33m[[0m%4d[33m] [34m|[33m=[34m| [32mCalls Yesterday [33m[[0m%4d[33m] [34m|[33m=[34m| [32mTotal Calls [33m[[0m%7s[33m] [34m|\n",
                TodayCalls,SKEL.HCalls[1],commas(SKEL.TotalCalls,buff));
 fprintf(out2,"[34m| [32mMessages Today  [33m[[0m%4d[33m] [34m|[33m=[34m| [32m Msgs Yesterday [33m[[0m%4d[33m] [34m|[33m=[34m| [32mTotal Msgs  [33m[[0m%7s[33m] [34m|\n",
                TodayMessages,SKEL.HMessages[1],commas(SKEL.TotalMessages,buff));
 fprintf(out2,"[34m`%s' `%s' `-----------------------'[0m~r\n",shit1,shit1);
 fclose(out2);
}
