/*
        .---------------.-------------------------.----------.
        | SKEL-TCM v1.3 | Top Callers/Msg Posters | 08-05-92 |
        `---------------^-------------------------^----------'

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

#include <proto/all.h>
#include <stdio.h>
#include <time.h>

#include <string.h>
#include <skeleton/commas.h>
#include <tempest/headers.h>
#include <tempest/Skel-Data.h>

VOID CSort(VOID);
VOID PSort(VOID);
VOID Print(VOID);

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

struct TopCallers
 {
  char   Name[31],Location[31];
  USHORT CallsToday,Times_Called;
  long   Time_Last;
 };
struct TopMsgPosters
 {
  char   Name[31],Location[31];
  USHORT MsgToday,MsgTotal;
  long   Time_Last;
 };
struct TopCallers TopC[5];
struct TopMsgPosters TopM[5];
struct User User;
struct Today Today;
struct SKEL SKEL;

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

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

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

void main(int argc,char *argv[])
{
 int stat,fd;
 char string[255];
 sprintf(shit1,"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"");
 if(argc != 3)
  {
   PutStr("\n[m[1m    _______ _________\n");
   PutStr("   / ___/ [4m/[m[1m/ / ___/ /    [[32mSKEL-TCM v3.29[m[1m] - [3mTop Callers/Msg Posters[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-TCM [OutFile] [BBS Path]\n");
   PutStr(" EXAMPLE: SKEL-TCM RAM:TEST TEMPEST:\n\n");
   PutStr("[OutFile] Path & Name of created file\n");
   PutStr("[BBSPath] Path of BBS Files & Accounts.Data\n\n");
   exit(0);
  }
 strcpy(OUTPATH,argv[1]);

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

 sprintf(string,"%sSetup/Skel-Data.Data",argv[2]);
 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 Files  ******/
/**************************************/

 sprintf(string,"%sSetup/RunTime-1.data",argv[2]);
 fd=Open(string,MODE_OLDFILE);
 if(fd==0)
  {
   PutStr("\nRuntime.Data not found!\n");
   exit(0);
  }
 Read(fd,(char *)&Today, sizeof(struct Today));
 Close(fd);

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

 sprintf(string,"%sAccounts.data",argv[2]);
 fd=Open(string,MODE_OLDFILE);
 if(fd==0)
  {
   PutStr("\nAccounts.data not found!\n");
   exit(0);
  }
 NEXTFILE:
 stat=Read(fd,(char *)&User, sizeof(struct User));
 if(stat <=0 )
  {
   Close(fd);
   Print();
   PutStr("\nSKEL-TCM Done!\n");
   exit(0);
  }
 if(User.Time_Last_Logoff >= Today.TODAY)
  {
   TodayCalls    += User.Period_Calls;
   TodayMessages += User.Period_Posts;
  }
 CSort();
 PSort();
 goto NEXTFILE;
}

/**********************************/
/*****  Top Msg Poster Array  *****/
/**********************************/

VOID PSort(VOID)
{
 register int x=0,y,HOLDER;
 do
  {
   if((User.Slot_Number==1)||(User.Status!=1)||(User.Total_Posts < 1))
    {
     break;  /* TO SKIP SYSOP,NEW USERS,USERS WITH LESS THAN 1 MSG  */
    }
   if(User.Total_Posts >= TopM[x].MsgTotal)   /* move other entries down one */
    {
     HOLDER = x;
     y=0;
     while(x+1<RANK)
      {
       y++;
       CopyMem(&TopM[RANK-(y+1)],&TopM[RANK-y],sizeof(struct TopMsgPosters));
       x++;
      }
     x=HOLDER;
     strcpy(TopM[x].Name,User.Name);
     strcpy(TopM[x].Location,User.City);
     TopM[x].MsgTotal     = User.Total_Posts;
     TopM[x].MsgToday     = User.Period_Posts;
     TopM[x].Time_Last    = User.Time_Last_Logoff;
     return;
    }
   x++;
  }
 while(x<RANK);
}

/*******************************/
/*****  Last Caller Array  *****/
/*******************************/

VOID CSort(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)
{
 register int x=0;
 char Month[50],Day[50],Year[50],Percent2[50],string[255],shit2[255];
 FILE *out2;
 out2=fopen(OUTPATH,"w");
 if(out2==NULL)
  {
   PutStr("Error writing output file!\n");
   exit(0);
  }
 strcpy(shit2,"[34m==-==================-=======-=======--=========-==--==========================\n");
 fprintf(out2,"\f~+                          [36mTop Callers/Msg Posters\n");
 fprintf(out2,"[34m%s\"\"\"\"\"\"\"\n",shit1);
 fprintf(out2,"[32m#  Top Callers          Calls Percent  Last On   CT  Location/Group\n");
 fprintf(out2,"%s",shit2);
 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);
   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%d. [36m%-18.18s [34m( [35m%5s [0m%5s[32m%[34m)  [37m%s %2s,%s [35m%2d  [37m%-26.26s\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);
 x = 0;
 fprintf(out2,"\n[32m#  Top Msg Posters       Msgs Percent  Last On   MT  Location/Group\n");
 fprintf(out2,"%s",shit2);
 do
  {
   strcpy(string,ctime(&TopM[x].Time_Last));
   strmid(string,Month,5,3);
   strmid(string,Day,9,2);
   strmid(string,Year,23,2);
   Percent = ((TopM[x].MsgTotal * 1000L)+1L) / (SKEL.TotalMessages / 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(TopM[x].Time_Last < Today.TODAY)
      TopM[x].MsgToday = 0;
   if(strlen(TopM[x].Name) > 2)
      fprintf(out2,"[0m%d. [36m%-18.18s [34m( [35m%5s [0m%5s[32m%[34m)  [37m%s %2s %s [35m%2d  [37m%-26.26s\n",
          x+1,TopM[x].Name,commas(TopM[x].MsgTotal,buff),Percent2,Month,Day,Year,TopM[x].MsgToday,TopM[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);
}
