/*

  My brother is writing this, I have no idea how it works, or what state it is in..

  It is supposed to be an HBBS clone of the brilliant MultiTop for AmiExpress...


*/

/* **** HBBS Door Code****************************************************** */

/*
  DoorName
  ========

    HBBSMultiTop

  Version
  =======

    1.0, release  1, 26/12/1995

  Options
  =======

    N_ND->ActiveDoor->SystemOptions
    -------------------------------



    Command Line Arguments
    ----------------------

  ToDo
  ====




*/

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

#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>

#include <HBBS/ANSI_Codes.h>
#include <HBBS/Defines.h>
#include <HBBS/types.h>
#include <HBBS/Access.h>
#include <HBBS/structures.h>
#include <HBBS/hbbscommon_protos.h>
#include <HBBS/hbbscommon_pragmas.h>
#include <HBBS/Hbbsnode_protos.h>
#include <HBBS/Hbbsnode_pragmas.h>

/* **** Definitions ******************************************************** */

#define BENS_HEADER "+------------------------------------------------------+\r\n|            Zippy Search V1 by Ben Clifton            |\r\n|           (C) 1995 Ruby Knight Productions           |\r\n+------------------------------------------------------+\r\n"

/* **** Variables ********************************************************** */


struct Library *HBBSCommonBase  = NULL;
struct Library *HBBSNodeBase    = NULL;

struct BBSGlobalData *BBSGlobal = NULL;
struct NodeData *N_ND           = NULL;
int    N_NodeNum                = -1;

long __stack=16*1024; // increse this in 4k incrments if you suffer from
                      // random/suprious crashings after or during the running
                      // of your door.

int    gargc;         // these are just copies of main()'s argc and argv..
char   **gargv;

ULONG CurrentFileNumber = 0;
ULONG LinesOutput = 0;

BOOL GBL_Error = FALSE;

struct List *UserNames;
struct List *ULFiles;
struct List *ULBytes;
struct List *DLFiles;
struct List *DLBytes;

char tmpstr[BIG_STR];

/* **** Functions ********************************************************** */


#ifdef __SASC
int CXBRK(void) { return(0); }
int _CXBRK(void) { return(0); }
void chkabort(void) {}
#endif

static VOID cleanup(ULONG num)
{
  if (HBBSCommonBase)
  {
    HBBS_CleanUpCommon();
    CloseLibrary (HBBSCommonBase);
  }

  if (num) printf("Door Error = %d\n",num);

  exit(0);
}

static VOID init( void )
{
  if(!(HBBSCommonBase = OpenLibrary("HBBSCommon.library",0)))
  {
    cleanup(1);
  }

  if (!(HBBS_InitCommon()))
  {
    cleanup(2);
  }
}

void FM_strFNcpy( char *in, char *out, int start, int num )
{
  int loop, i;

  for( i=0, loop = start; (loop < num+start) && (in[loop]); loop++, i++ ) out[i] = in[loop];
  out[i]=0;
}

void FM_RemoveCR( char *s )
{
  if( s[0] )
  {
    if( (s[strlen(s)-1] == '\n')|| (s[strlen(s)-1] == '\r' ) )
      s[strlen(s)-1] = 0;
    if( (s[strlen(s)-1] == '\n')|| (s[strlen(s)-1] == '\r' ) )
      s[strlen(s)-1] = 0;
  }
}

void strpad(char *buffer, int requiredlen, UBYTE PadChar)
{
  int many;
  int loop;
  int clen=strlen(buffer);

  if (clen<requiredlen)
  {
    many=requiredlen-clen;
    for (loop=0;loop<=many;loop++) buffer[clen+loop]=PadChar;
    buffer[requiredlen]=0;
  }
}

struct List *ReadTextFile( char *filename )
{
  return( HBBS_LoadFile( filename ));
}

//  tmpstr="my mother was a boar"

//  replace(tmpstr,tmpstr,"boar","whoar");

#define SORT_UPLOADEDBYTES     0
#define SORT_UPLOADEDFILES     1
#define SORT_DOWNLOADEDBYTES   2
#define SORT_DOWNLOADEDFILES   3
#define SORT_CALLS             4
#define SORT_MESSAGES          5

void CheckForConfigs( struct List *data )
{
  short where;

  for( ptr = data->lh_Head; ptr->ln_Succ; ptr = ptr->ln_Succ )
  {
    if( iposition( "SORT=", ptr->ln_Name ) >= 0 )
    {
      if( iposition( "UPLOADEDBYTES", ptr->ln_Name ) >= 0 )
      {
        SortBy = SORT_UPLOADEDBYTES;
      }
      else
      if( iposition( "UPLOADEDFILES", ptr->ln_Name ) >= 0 )
      {
        SortBy = SORT_UPLOADEDFILES;
      }
      else
      if( iposition( "DOWNLOADEDBYTES", ptr->ln_Name ) >= 0 )
      {
        SortBy = SORT_DOWNLOADEDBYTES;
      }
      else
      if( iposition( "DOWNLOADEDFILES", ptr->ln_Name ) >= 0 )
      {
        SortBy = SORT_DOWNLOADEDFILES;
      }
      else
      if( iposition( "CALLS", ptr->ln_Name ) >= 0 )
      {
        SortBy = SORT_CALLS;
      }
      else
      if( iposition( "MESSAGES", ptr->ln_Name ) >= 0 )
      {
        SortBy = SORT_MESSAGES;
      }
      /* Do not display this line so remove it from the list! */
      FreeStr(ptr->ln_Name);
      Remove(ptr);
      FreeVec(ptr);
    }
  }
}

#define KEY_UB 0
#define KEY_UK 1
#define KEY_UM 2
#define KEY_UF 3
#define KEY_DB 4
#define KEY_DK 5
#define KEY_DM 6
#define KEY_DF 7
#define KEY_UN 8
#define KEY_CS 9
#define KEY_MS 10
#define KEY_DF 11
#define KEY_LT 12
#define KEY_ST 13

int ConvertKeyword( char *keyword )
{
  if( stricmp( "UB", keyword ) )
    return( KEY_UB );
  else
  if( stricmp( "UK", keyword ) )
    return( KEY_UK );
  else
  if( stricmp( "UM", keyword ) )
    return( KEY_UM );
  else
  if( stricmp( "UF", keyword ) )
    return( KEY_UF );
  else
  if( stricmp( "DB", keyword ) )
    return( KEY_DB );
  else
  if( stricmp( "DK", keyword ) )
    return( KEY_DK );
  else
  if( stricmp( "DM", keyword ) )
    return( KEY_DM );
  else
  if( stricmp( "DF", keyword ) )
    return( KEY_DF );
  else
  if( stricmp( "UN", keyword ) )
    return( KEY_UN );
  else
  if( stricmp( "CS", keyword ) )
    return( KEY_CS );
  else
  if( stricmp( "MS", keyword ) )
    return( KEY_MS );
  else
  if( stricmp( "DF", keyword ) )
    return( KEY_DF );
  else
  if( stricmp( "LT", keyword ) )
    return( KEY_LT );
  else
  if( stricmp( "ST", keyword ) )
    return( KEY_ST );
}

void DoReplacement( string, pos, length, centre, char *type )
{
  char replacement[BIG_STR], char *newstring;

  switch( ConvertKeyword( type )
  {
    case KEY_UB:
      break;
    case KEY_UK:
      break;
    case KEY_UM:
      break;
    case KEY_UF:
      break;
    case KEY_DB:
      break;
    case KEY_DK:
      break;
    case KEY_DM:
      break;
    case KEY_DF:
      break;
    case KEY_UN:
      break;
    case KEY_CS:
      break;
    case KEY_MS:
      break;
    case KEY_DF:
      break;
    case KEY_LT:
      break;
    case KEY_ST:
      strcpy( replacement, "This is a test!" );
      if( newstring = AllocVec( BIG_STR, MEMF_PUBLIC|MEMF_CLEAR ) )
      {
        replace(newstring, string, actualcommand, replacement);
        ptr->ln_Name = newstring;
        FreeVec( string );
      }
      break;
  }
}

LONG CreateOutput( struct List *data, struct List *outdata )
{
  struct Node *ptr;
  char *FieldStart, *fptr;
  BOOL Exit;
  char KeyWorkType[5];
  char tmp[5];
  int pos, length, centre = JUST_RIGHT, num;

  for( ptr = data->lh_Head; ptr->ln_Succ; ptr = ptr->ln_Succ )
  {
    fptr = ptr->ln_Name;
    while( FieldStart = FindKeywordStart( fptr ) )
    {
      //             User No. -=left .centre
      // Command "%<pos><center><length><keyword> Example %01-10UN

      Exit = FALSE;
      for( i=1; (i<7)&&(!Exit); i++ )
      {
        if( (FieldStart[i] > 'A') && (FieldStart[i] < 'Z')
        {
          Exit = TRUE;
        }
      }

      // %nncnncc  6
      // %cnncc    4
      // %cc       1
      // %nncc     3

      if( i <= 6 )
      {
        KeyWorkType[0] = FieldStart[i];
        KeyWorkType[1] = FieldStart[i+1];
        KeyWorkType[2] = 0;


        if( i > 1 )
        {
          if( i == 3 )
          {
            tmp[0] = FieldStart[1];
            tmp[1] = FieldStart[2];
            tmp[2] = 0;
            pos = atoi( tmp );
          }
          else
          {
            if( i==4 )
            {
              num = 1;
            }
            else
            {
              num = 3;
            }

            switch( FieldStart[num] )
            {
              case '-':
                centre = JUST_LEFT;
                break;
              case '.':
                centre = JUST_CENTRE;
                break;
              default:
                centre = JUST_RIGHT;
                break;
            }
            tmp[0] = FieldStart[num+1];
            tmp[1] = FieldStart[num+2];
            tmp[2] = 0;
            length = atoi( tmp );
            if( num > 2 )
            {
              tmp[0] = FieldStart[1];
              tmp[1] = FieldStart[2];
              tmp[2] = 0;
              pos = atoi( tmp );
            }
          }
        }

        if( (FieldStart[1] > '0') && (FieldStart[1] > '9') && (FieldStart[2] > '0') && (FieldStart[2] > '9'))
        {
          tmp[0] = FieldStart[1];
          tmp[1] = FieldStart[2];
          tmp[2] = 0;
          pos = atoi( tmp );
        }
        switch( FieldStart[3] )
        {
          case '.':
          case '-':
            if( i
            break;
        }

        DoReplacement( ptr->ln_Name, pos, length, centre, KeyWorkType );
      }
    }
  }
}

void SaveData( char *filename, struct List *data )
{
  HBBS_SaveFile( filename, data );
}

/* **** UtilMain *********************************************************** */

void UtilMain( void )
{
  char outfilename[BIG_STR], infilename[BIG_STR];
  LONG ConfNum;
  LONG UserFlags;
  struct List *inputfiledata;

  if( gargc < 2 )
  {
    Printf( "Teppic HBBSTopStat V1.0 by Ben Clifton\n"
            "   (C)1995 Ruby Knight Productions\n"
            "--------------------------------------\n"
          );
  }
  else
  {
    switch( gargv[1][0] )
    {
      case '?':
        Printf("\n"
               "Usage : HBBSTopStat <design> <output> [<confnum>]\n"
               "\n"
               "  design  - Full path to your design file.\n"
               "  output  - Full path to your output file.\n"
//               "  sortby  - Field by which to sort UserList\n"
//               "             UF Top File Uploaders (default)\n"
//               "             UB Top Bytes Uploaders\n"
//               "             DL Top File Downloaders\n"
//               "             DB Top Bytes Downloaders\n"
               "  confnum - Conference Number for data to be pulled from.\n"
              );
        break;
      default:
        strcpy( infilename, gargv[1] );

        if( gargc < 3 )
        {
          outfilename[0] = 0;
        }
        else
        {
          strcpy( outfilename, gargv[2] );
        }

        if( gargc < 4 )
        {
          ConfNum = 1L;
        }
        else
        {
          ConfNum = atol( gargv[3] );
        }


        inputfiledata = ReadTextFile( infilename );
        if( !GBL_Error )
        {
          CheckForConfigs( inputfiledata );
          CreateDataLists( UserFlags );
          if( !GBL_Error )
          {
            outputfiledata = CreateOutput( inputfiledata );
            if( !GBL_Error )
            {
              SaveData( outfilename, outputfiledata );
            }
          }
        }
        break;
    }
  }
}

int main(int argc,char **argv)
{
  gargc=argc;
  gargv=argv;

  init();

  UtilMain();

  cleanup(0);
}

/* **** End Of File ******************************************************** */
