#include <exec/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>

#include <dlg/dlg.h>

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

#include <pragmas/dlg.h>

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

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

void  main(void);
void  HandleBuf(void);
void  MakeEntries(void);
int   cmp(void const *, void const *);
void _CXBRK(void);
void  CleanUp(char *);

struct ScreenEntry {char *str[2];};

BPTR                sout;
BPTR                ifh      = NULL;
BPTR                ofh      = NULL;

unsigned short      counter  = 0;
unsigned short      whichstr = 0;
char               *mem     = NULL;
struct ScreenEntry *entries = NULL;
char                buf[256];

char              **SA;
struct Library     *DLGBase = NULL;

/// main()
void main(void)
{
   ULONG          size;
   unsigned short cnt;

   sout = Output();
   if (!(DLGBase = OpenLibrary(DLGNAME, DLGVERSION)))  exit(5);
   if (!(SA = getlang(NULL)))                          exit(5);

   ifh = Open("Screen.Msg",MODE_OLDFILE);

   if(!ifh) CleanUp(SA[37]);

   AFPrintf(NULL, sout, SA[38]);

   if(Exists("Screen.dat"))
      DeleteFile("Screen.dat");

   ofh = Open("Screen.dat",MODE_READWRITE);

   if(!ofh)
   {
      Close(ifh); ifh = NULL;
      CleanUp(SA[39]);
   }

   while(FGets(ifh,buf,256))
      HandleBuf();

   if(ifh)  Close(ifh); ifh = NULL;

   if(ofh)  Close(ofh);
   ofh = NULL;

   AFPrintf(NULL, sout, SA[40], counter);

   if(-1 == FileSize("Screen.dat", &size)) CleanUp(SA[42]);
   if(size == 0) CleanUp(SA[42]);

   mem     = malloc(size);
   entries = malloc(counter * sizeof(struct ScreenEntry));

   if (!mem || !entries)  CleanUp(SA[42]);

   ofh = Open("Screen.dat",MODE_READWRITE);
   if(!ofh) CleanUp(SA[41]);

   if (Read(ofh,mem,size) != size)  CleanUp(SA[43]);
   MakeEntries();

   qsort(entries,counter,sizeof(struct ScreenEntry),cmp);
   AFPrintf(NULL, sout, SA[44]);

   Seek(ofh,  0,       OFFSET_BEGINNING);
   Write(ofh, &counter, 2);

   for(cnt=0;cnt<counter;cnt++)
   {
      Write(ofh,entries[cnt].str[0],strlen(entries[cnt].str[0])+1);
      Write(ofh,entries[cnt].str[1],strlen(entries[cnt].str[1])+1);
   }

   AFPrintf(NULL, sout, SA[45]);
   CleanUp(NULL);
}
//-
/// HandleBuf()
void HandleBuf()
{
   UBYTE instr = FALSE;
   char  str[2][256];
   char *sptr  =   0;
   char *bptr;

   for(bptr = buf; *bptr; bptr++)
   {
      Chk_Abort();

      if (instr)
      {
         if (*bptr!='"')
         {
            *sptr++ = *bptr;
            continue;
         }

         *sptr  = 0;
         instr = FALSE;

         if (whichstr)
         {
            Write(ofh,str[0],strlen(str[0])+1);
            Write(ofh,str[1],strlen(str[1])+1);
            counter++;
         }

         whichstr = !whichstr;
         continue;
      }

      if (*bptr=='"')
      {
         instr = TRUE;
         sptr  = str[whichstr];
      }
   }
}
//-
/// MakeEntries()
void MakeEntries(void)
{
   char          *ptr;
   unsigned short cnt;

   ptr = mem;

   for(cnt=0;cnt<counter;cnt++)
   {
      for(whichstr=0;whichstr<2;whichstr++)
      {
         entries[cnt].str[whichstr]=ptr;
         for(;*ptr;ptr++);
         ptr++;
      }
   }
}
//-
/// cmp()
int cmp(struct ScreenEntry *a, struct ScreenEntry *b)
{
   Chk_Abort();
   return(Stricmp(a->str[0],b->str[0]));
}
//-
/// _CXBRK
void _CXBRK(void)
{
   CleanUp("***Break\n");
}
//-
/// CleanUp()
void CleanUp(char *s)
{
   if (entries)   free(entries);
   if (mem)       free(mem);

   if (ifh)       Close(ifh);
   if (ofh)       Close(ofh);

   CloseLibrary(DLGBase);

   if (s)
   {
      Write(sout, "\n Error: ", 9);
      Write(sout, s, strlen(s));
      Write(sout, "\n\n", 2);
   }

   exit(s?5:0);
}
//-
