#include <exec/types.h>

#include <stdlib.h>
#include <strings.h>
#include <dos.h>

#include <link/lang.h>
#include <link/io.h>

#include <proto/dlg.h>
#include <proto/exec.h>
#include <proto/dos.h>

#include <dlg/msg.h>
#include <dlg/file.h>

#include <pragmas/dlg.h>

#include "Freq.h"

BPTR                 sout;
struct   Library    *DLGBase =  NULL;
struct   LangStruct *ls;
char               **SA;

int   cmp(struct FREQ_INDEX *, struct FREQ_INDEX *);
void  ShutDown(int, char *);

#include <private/Version.h>
#define  ObjRev "1"
const UBYTE version[]="\0$VER: MakeIndex " BUILDVER "." ObjRev " ©" COPYRIGHT " by Digerati Dreams "__AMIGADATE__;

void main(int argc, char **argv)
{
   BOOL                 Quiet =  FALSE;
   BPTR                 fh    =  NULL;

   struct   Msg_Area   *farea =  NULL;
   struct   FREQ_INDEX *fi    =  NULL;

   unsigned long        asize =  0;
   unsigned long        i     =  0;


   sout = Output();

   DLGBase = OpenLibrary("dlg.library",4L);

   if(!DLGBase)   ShutDown(10,"Could not open dlg.library!");

   SA = getlang(NULL);

   if(!SA)        ShutDown(10,"Could not read language file!");

   if(argc > 1)
   {
      if(!Stricmp(argv[1],"-q"))
         Quiet = TRUE;
   }

   fi = calloc(1,sizeof(struct FREQ_INDEX));

//    if(!fi)  ShutDown(22,"Memory allocation error 3!");
   if(!fi)  ShutDown(22,SA[3768]);

   FileSize(AreaFile,&asize);

//    if(asize == 0) ShutDown(11,"Could not open File:Area.BBS");
   if(asize == 0) ShutDown(11,SA[3769]);

   farea = calloc(1,asize);

//    if(!farea)     ShutDown(20,"Memory allocation error 1");
   if(!farea)     ShutDown(20,SA[3770]);

   fh = Open(AreaFile,MODE_OLDFILE);

   if(!fh)
   {
      free(farea);
//       ShutDown(11,"Could not read File:Area.BBS");
      ShutDown(11,SA[3771]);
   }

   if(!Quiet)
//       AFPrintf(NULL,sout,"Reading %ld file areas ... ",asize/(sizeof(struct Msg_Area)));
      AFPrintf(NULL,sout,SA[3772],asize/(sizeof(struct Msg_Area)));

   Read(fh,farea,asize);
   Close(fh);

   if(!Quiet)
//       AFPrintf(NULL,sout,"Done!\n");
      AFPrintf(NULL,sout,SA[3773]);

   if(Exists(IndexFile))   DeleteFile(IndexFile);

   for(i = 0; i < (asize/sizeof(struct Msg_Area)); i++)
   {
      BPTR                 ofh   =  NULL;
      char                 t[512];
      int                  j;
      struct   QuickFile  *qf    =  NULL;
      unsigned long        qsize =  0;


      chkabort();

      if(!Quiet)
//          AFPrintf(NULL,sout,"File area [%ld]: %s ... ",farea[i].Number,farea[i].Name);
         AFPrintf(NULL,sout,SA[3774],farea[i].Number,farea[i].Name);

      if((farea[i].Flag & FREQ_AREA) == 0)
      {
         if(!Quiet)
//             AFPrintf(NULL,sout,"Not freqable, skipped\n");
            AFPrintf(NULL,sout,SA[3775]);
         continue;
      }

      ASPrintf(NULL,t,"FILE:%ld/file.dat",farea[i].Number);

      FileSize(t,&qsize);

      if(!qsize)
      {
         if(!Quiet)
//             AFPrintf(NULL,sout,"No files, skipped\n");
            AFPrintf(NULL,sout,SA[3776]);
         continue;
      }

      qf = calloc(1,qsize);

      if(!qf)
      {
         free(farea);
//          ShutDown(21,"Memory allocation error 2!");
         ShutDown(21,SA[3777]);
      }

      fh = Open(t,MODE_OLDFILE);

      if(!fh)
      {
         free(qf);
         free(farea);
//          ShutDown(12,"Could not open a file.dat!");
         ShutDown(12,SA[3778]);
      }

      Read(fh,qf,qsize);
      Close(fh);

      ofh = Open(IndexFile,MODE_READWRITE);

      if(!ofh)
      {
         free(farea);
         free(qf);
         free(fi);
         Close(fh);
//          ShutDown(13,"Could not open output file");
         ShutDown(13,SA[3779]);
      }

      Seek(ofh,0,OFFSET_END);

      if(!Quiet)
//          AFPrintf(NULL,sout,"%ld entries ... ",qsize/sizeof(struct QuickFile));
         AFPrintf(NULL,sout,SA[3780],qsize/sizeof(struct QuickFile));

      for(j = 0; j < (qsize/sizeof(struct QuickFile)); j++)
      {
         chkabort();
         ASPrintf(NULL,fi->Name,"%s",qf[j].filename);
         fi->Area = farea[i].Number;
         Write(ofh,fi,sizeof(struct FREQ_INDEX));
      }

      Close(ofh);

      free(qf);

      if(!Quiet)
//          AFPrintf(NULL,sout,"Done!\n");
         AFPrintf(NULL,sout,SA[3773]);
   }

   free(fi);
   free(farea);

   if(!Quiet)
//       AFPrintf(NULL,sout,"Reading .... ");
      AFPrintf(NULL,sout,SA[3781]);

   FileSize(IndexFile,&asize);

   fi = calloc(1,asize);

//    if(!fi)  ShutDown(24,"Memory allocation error 5!");
   if(!fi)  ShutDown(24,SA[3782]);

   fh = NULL;

   fh = Open(IndexFile,MODE_OLDFILE);

   if(!fh)
   {
      free(fi);
//       ShutDown(15,"Could not open Index to sort!");
      ShutDown(15,SA[3783]);
   }

   Read(fh,fi,asize);
   Close(fh);

   if(!Quiet)
//       AFPrintf(NULL,sout,"sorting .... ");
      AFPrintf(NULL,sout,SA[3784]);

   qsort(fi,asize/sizeof(struct FREQ_INDEX),sizeof(struct FREQ_INDEX),cmp);

   if(!Quiet)
//       AFPrintf(NULL,sout,"writing .... ");
      AFPrintf(NULL,sout,SA[3785]);

   fh = NULL;

   fh = Open(IndexFile,MODE_NEWFILE);

   if(!fh)
   {
      free(fi);
//       ShutDown(16,"Could not open Index to write!");
      ShutDown(16,SA[3786]);
   }

   Write(fh,fi,asize);
   Close(fh);

   if(!Quiet)
//       AFPrintf(NULL,sout,"Done!\n");
      AFPrintf(NULL,sout,SA[3773]);

   ShutDown(0,NULL);
}

int cmp(struct FREQ_INDEX *a, struct FREQ_INDEX *b)
{
   return(Stricmp(a->Name,b->Name));
}

void ShutDown(int Error, char *ErrStr)
{
   if(DLGBase) CloseLibrary(DLGBase);

   if(Error)
   {
//       FPuts(sout,"MakeIndex: ");
      FPuts(sout,SA[3787]);
      FPuts(sout,ErrStr);
      FPuts(sout,"\n\n");
   }

   exit(Error);
}
