#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <exec/types.h>
#include <libraries/dosextens.h>

#include <dlg/dlg.h>

#include <link/io.h>

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

#include <pragmas/dlg.h>

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

int  main(int, char **);
void Interpret(char *, char *);
void CleanUp(char *);


struct Library   *DLGBase = NULL;
BPTR              sout    = NULL;

char             *lang    = NULL;
long             *offsets = NULL;
FILE             *lfp     = NULL;


int main(int argc, char **argv)

{ULONG size;
 ULONG position;
 ULONG opercent = (ULONG)-1;
 ULONG percent;
 char *s;
 char *b;

 SHORT numstrings = 0;

 char  filename[60];
 char  buf    [256];
 char  conv   [256];

 sout = Output();
 if (argc < 2)                                       CleanUp("Usage: CompileLang <language>");
 if (!(DLGBase = OpenLibrary(DLGNAME, DLGVERSION)))  CleanUp("Can't open dlg.library");

 ASPrintf(NULL, filename, "DLGConfig:Languages/%.20s.lang", argv[1]);
 if (FileSize(filename, &size) == -1)  CleanUp("Unable to open language file from DLGCONFIG:Languages/");
 if (!size)                            CleanUp("No language strings");
 if (!(lang    = malloc(size)))        CleanUp("Can't alloc string memory");
 if (!(offsets = malloc(16000 * 4)))   CleanUp("Can't alloc offset memory");

 if (!(lfp = fopen(filename, "r")))    CleanUp("Unable to open language file from DLGCONFIG:Languages/");

 AFPrintf(NULL, sout, "\n\n ");
 s = lang;
 while(fgets(buf, 255, lfp))
      {fgetpos(lfp, &position);
       percent = (position * 100 / size);
       if (opercent != percent)
          {AFPrintf(NULL, sout, "\r Reading File...%d%% done", percent);
           opercent = percent;
          }

       for(b = buf; *b == ' '; b++);
       if (*b  &&  *b != ';')
          {Interpret(b, conv);

           for(b=lang; b < s; b = b + strlen(b) + 1)
               if (!strcmp(b, conv))  break;

          *(offsets+numstrings) = (b - lang);

           if (b == s)
              {strcpy(s, conv);
               s = s + strlen(conv) + 1;
              }

           numstrings++;
          }
      }
 fclose(lfp);
 AFPrintf(NULL, sout, "\n\n %d language strings read\n\n", numstrings);

 ASPrintf(NULL, filename, "DLGConfig:Languages/%.20s.dat", argv[1]);
 if (!(lfp = fopen(filename, "w")))  CleanUp("Unable to create language data in DLGCONFIG:Languages/");

 AFPrintf(NULL, sout, " Writing data...");
 fwrite(&numstrings, 2, 1, lfp);
 fwrite(offsets, 4, numstrings, lfp);
 fwrite(lang,    s - lang,   1, lfp);
 AFPrintf(NULL, sout, "done\n\n");

 CleanUp(NULL);
}


void Interpret(char *ptr, char *out)

{long  x;
 long  quotecount = 0;
 UBYTE inslash    = FALSE;

 for(; *ptr; ptr++)
    {if (inslash)
        {if (*ptr == '\\')
            {*out++ = '\\';
             inslash   =  FALSE;
             continue;
            }

         if (*ptr == 'n')
            {*out++ = 10;
             inslash   = FALSE;
             continue;
            }

         if (*ptr == 'r')
            {*out++ = 13;
             inslash   = FALSE;
             continue;
            }

         if ((*ptr == 'x')  ||  ((*ptr == '0') && (*(ptr+1) == 'x')))
            {if (*ptr == '0')
                  ptr += 2;
                 else
                  ptr++;

             sscanf(ptr, "%x", &x);
             while(isxdigit(*ptr))
                   ptr++;

             ptr--;
            *out++ = (char)x;
             inslash  =  FALSE;
             continue;
            }

         if (*ptr >= '0'  &&  *ptr <= '7')
            {sscanf(ptr, "%o", &x);
             while(*ptr >= '0'  &&  *ptr <= '7')
                   ptr++;

             ptr--;
            *out++ = (char)x;
             inslash  =  FALSE;
             continue;
            }

        *out++ = *ptr;
         inslash  =  FALSE;
         continue;
        }

     if (*ptr == '\\')
        {inslash = TRUE;
         continue;
        }

     if (*ptr == 34)
        {if (!quotecount)
            {quotecount++;
             continue;
            }

          break;
        }

     *out++ = *ptr;
    }

 *out = 0;
}


void CleanUp(char *s)

{if (DLGBase)  CloseLibrary(DLGBase);
 if (lfp)      fclose(lfp);
 if (lang)     free(lang);
 if (offsets)  free(offsets);

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

 exit(s?5:0);
}
