{$IFDEF WtrGate}{$IFDEF UseOvr}{$O+,F+}{$ENDIF}{$ENDIF}
UNIT Language;

{$i platform.inc}

{ all multi-language specific things are gathered in this unit }

INTERFACE

FUNCTION  InitLang (Path : STRING) : BOOLEAN;
PROCEDURE JunkLang;
FUNCTION  GetLang0 (Number : WORD) : STRING;
FUNCTION  GetLang1 (Number : WORD; Arg1 : STRING) : STRING;
FUNCTION  GetLang2 (Number : WORD; Arg1,Arg2 : STRING) : STRING;
FUNCTION  GetLang3 (Number : WORD; Arg1,Arg2,Arg3 : STRING) : STRING;
{$IFDEF WtrConf}
FUNCTION  CheckLang (Path : STRING) : BOOLEAN;
{$ENDIF}

VAR LangSize : WORD;  { for DebugMem }

IMPLEMENTATION

USES Ramon,
     Globals,
     Logs;

CONST MAXLANGENTRIES = 100; { for starters }
      FILENAME_LANG  = 'WTRGATE.LNG';

TYPE LangBlok    = ARRAY[0..65528] OF CHAR;
     LangBlokPtr = ^LangBlok;

TYPE LangMapRecord = RECORD
                           Number : WORD;
                           Index  : WORD;
                     END;

{ all the required language numbers and index that will be updated later }
CONST LangCount = 85;

CONST LangIndex : ARRAY[1..LangCount] OF LangMapRecord = (
(Number:100),  (Number:102),  (Number:103),  (Number:105),
(Number:107),  (Number:108),  (Number:109),
(Number:120),  (Number:121),  (Number:122),  (Number:123),  (Number:124),
(Number:125),
(Number:130),
(Number:200),  (Number:201),  (Number:202),  (Number:203),  (Number:204),
(Number:205),  (Number:206),
(Number:1000), (Number:1001), (Number:1002), (Number:1003), (Number:1004),
(Number:1005), (Number:1010), (Number:1011), (Number:1012),
(Number:1020), (Number:1021), (Number:1022), (Number:1023), (Number:1024),
(Number:1030), (Number:1031), (Number:1032), (Number:1033), (Number:1034),
(Number:1035),
(Number:1040), (Number:1041), (Number:1042),
(Number:2000), (Number:2001), (Number:2002), (Number:2003), (Number:2004),
(Number:2005), (Number:2006), (Number:2007), (Number:2008), (Number:2009),
(Number:2010), (Number:2011), (Number:2012), (Number:2013), (Number:2014),
(Number:2015), (Number:2016), (Number:2017), (Number:2018), (Number:2019),
(Number:2020), (Number:2021), (Number:2022), (Number:2023), (Number:2024),
(Number:2025), (Number:2026), (Number:2027), (Number:2028), (Number:2029),
(Number:2030), (Number:2031), (Number:2032), (Number:2033), (Number:2034),
(Number:2035), (Number:2036), (Number:2037), (Number:2038), (Number:2039),
(Number:2040)
);

VAR LangPtr : LangBlokPtr;


{---------------------------------------------------------------------------}
{ InitLang                                                                  }
{                                                                           }
{ Deze routine initialiseert de multi-language routine. De file WTRGATE.LNG }
{ wordt ingelezen en alle gegevens worden in het geheugen opgeslagen. De    }
{ totale language file mag niet meer dan 25kb innemen en er wordt een index }
{ aangelegd voor de gebruikte nummers.                                      }
{                                                                           }
FUNCTION InitLang (Path : STRING) : BOOLEAN;

CONST TEMPSIZE = 25000;

VAR LangFile : TEXT;
    IORes    : BYTE;
    TempPtr  : LangBlokPtr;
    FreeIdx  : WORD;
    Regel    : STRING;
    LineNr   : WORD;
    P        : BYTE;
    LangNr   : WORD;
    Nop      : ValNop;
    Info     : STRING[40];
    Lp       : WORD;
    Found    : BOOLEAN;

BEGIN
     FOR Lp:=1 TO LangCount DO
         LangIndex[Lp].Index:=0; { = not found }

     IF (_MaxAvail < 2*TEMPSIZE) THEN
     BEGIN
          WriteLn ('þ Not enough memory to start loading the language file',#7);
          InitLang:=FALSE; { problem! }
          Exit;
     END;

     Assign (LangFile,Path+FILENAME_LANG);
     {$I-} Reset (LangFile); {$I+} IORes:=IOResult;
     IF (IORes <> 0) THEN
     BEGIN
          IF (IORes = 2) THEN
             WriteLn ('þ Cannot find language file '+Path+FILENAME_LANG,#7)
          ELSE
              WriteLn ('þ Cannot open language file '+Path+FILENAME_LANG+' (error '+Byte2String (IORes)+')',#7);

          InitLang:=FALSE; { problem! }
          Exit;
     END;

     {$IFDEF LogFileIO}PostOpenT (LangFile);{$ENDIF}

     InitLang:=TRUE;  { assume no problems }

     GetMem (TempPtr,TEMPSIZE);
     FreeIdx:=1;  { 0 cannot be used }

     LineNr:=0;
     WHILE (NOT Eof (LangFile)) DO
     BEGIN
          ReadLn (LangFile,Regel);
          Inc (LineNr);

          Regel:=DeleteFrontAndBackSpaces (Regel);

          IF (Regel = '') OR (Regel[1] = ';') THEN
             Continue;

          Info:=Word2String (LineNr)+' in '+Path+FILENAME_LANG;

          { converts tabs to spaces }
          Regel:=CleanTabs (Regel,1);

          Regel:=Regel+' ';  { altijd nummer pakken, inhoud _mag_ leeg zijn }
          P:=Pos (' ',Regel);
          Val (Copy (Regel,1,P-1),LangNr,Nop);

          IF (Nop <> 0) THEN
          BEGIN
               WriteLn ('þ Error in line '+Info,#7);
               InitLang:=FALSE; { problems! }
               Continue;
          END;

          { delete the number and the space }
          Delete (Regel,1,P);

          Regel:=DeleteFrontAndBackSpaces (Regel);

          {LogMessage ('Lang '+Word2String (LangNr)+' = "'+Regel+'"');}

          IF (TEMPSIZE-FreeIdx < Length (Regel)+1) THEN
          BEGIN
               WriteLn ('þ Language blok full. Cannot store item '+Word2String (LangNr)+' !!',#7);
               InitLang:=FALSE;
               Continue;
          END;

          IF (LangCount = MAXLANGENTRIES) THEN
          BEGIN
               WriteLn ('þ Out of language entries. Cannot store item '+Word2String (LangNr)+' !!',#7);
               Continue;
          END;

          { store this item }
          Found:=FALSE;
          FOR Lp:=1 TO LangCount DO
              IF (LangIndex[Lp].Number = LangNr) THEN
              BEGIN
                   LangIndex[Lp].Index:=FreeIdx;
                   Found:=TRUE;
                   Break;
              END;

          IF Found THEN
          BEGIN
               Move (Regel[0],TempPtr^[FreeIdx],Length (Regel)+1);
               Inc (FreeIdx,Length (Regel)+1);
          END ELSE
              LogMessage (liConfig,'Language item '+Word2String (LangNr)+' is not needed');

     END; { while }

     { allocate exactly enough memory for this block }
     LangSize:=FreeIdx;
     GetMem (LangPtr,LangSize);

     { copy the language strings into the target block }
     Move (TempPtr^,LangPtr^,LangSize);

     FreeMem (TempPtr,TEMPSIZE); { this leaves a gap! }
     PeekMem; { now is the time to check for the lowest memory reached }

     {$IFDEF LogFileIO}PreCloseT (LangFile);{$ENDIF}
     Close (LangFile);

     FOR Lp:=1 TO LangCount DO
         IF (LangIndex[Lp].Index = 0) THEN
         BEGIN
              Regel:='Missing required language item '+Word2String (LangIndex[Lp].Number);
              WriteLn ('þ '+Regel);
              LogMessage (liConfig,Regel);
              InitLang:=FALSE;
         END;
END;


{---------------------------------------------------------------------------}
{ JunkLang                                                                  }
{                                                                           }
{ Voor de netheid: deze routine ruimte al het voor de multi-language        }
{ support aangevraagde geheugen weer vrij.                                  }
{                                                                           }
PROCEDURE JunkLang;
BEGIN
     IF (LangPtr = NIL) THEN
        Exit;

     FreeMem (LangPtr,LangSize);

     LangPtr:=NIL;
     LangSize:=0;
END;


{---------------------------------------------------------------------------}
{ GetLang0                                                                  }
{                                                                           }
{ Deze routine geeft een regels terug aan de hand van het opgegeven nummer. }
{ Er zijn geen argumenten in de regel die vervangen moeten worden.          }
{                                                                           }
FUNCTION GetLang0 (Number : WORD) : STRING;

VAR Lp  : WORD;
    Ptr : StringPtr;

BEGIN
     FOR Lp:=1 TO LangCount DO
         IF (LangIndex[Lp].Number = Number) THEN
         BEGIN
              Ptr:=Addr (LangPtr^[LangIndex[Lp].Index]);
              GetLang0:=Ptr^;
              Exit;
         END;

     GetLang0:='*** Error: cannot find language entry '+Word2String (Number);
END;


{---------------------------------------------------------------------------}
{ GetLang1                                                                  }
{                                                                           }
{ Deze routine geeft een regels terug aan de hand van het opgegeven nummer. }
{ De in de tekst voorkomende @1@ wordt vervangen door Arg1.                 }
{                                                                           }
FUNCTION GetLang1 (Number : WORD; Arg1 : STRING) : STRING;

VAR Regel : STRING;
    P     : BYTE;

BEGIN
     Regel:=GetLang0 (Number);

     P:=Pos ('@1@',Regel);
     IF (P > 0) THEN
        Regel:=Copy (Regel,1,P-1)+Arg1+Copy (Regel,P+3,255);

     GetLang1:=Regel;
END;


{---------------------------------------------------------------------------}
{ GetLang2                                                                  }
{                                                                           }
{ Deze routine geeft een regels terug aan de hand van het opgegeven nummer. }
{ De in de tekst voorkomende @1@ wordt vervangen door Arg1 en de @2@ door   }
{ Arg2.                                                                     }
{                                                                           }
FUNCTION GetLang2 (Number : WORD; Arg1,Arg2 : STRING) : STRING;

VAR Regel : STRING;
    P     : BYTE;

BEGIN
     Regel:=GetLang0 (Number);

     P:=Pos ('@1@',Regel);
     IF (P > 0) THEN
        Regel:=Copy (Regel,1,P-1)+Arg1+Copy (Regel,P+3,255);

     P:=Pos ('@2@',Regel);
     IF (P > 0) THEN
        Regel:=Copy (Regel,1,P-1)+Arg2+Copy (Regel,P+3,255);

     GetLang2:=Regel;
END;


{---------------------------------------------------------------------------}
{ GetLang3                                                                  }
{                                                                           }
{ Deze routine geeft een regels terug aan de hand van het opgegeven nummer. }
{ De in de tekst voorkomende @1@ wordt vervangen door Arg1 en de @2@ door   }
{ Arg2 en @3@ door Arg3.                                                    }
{                                                                           }
FUNCTION GetLang3 (Number : WORD; Arg1,Arg2,Arg3 : STRING) : STRING;

VAR Regel : STRING;
    P     : BYTE;

BEGIN
     Regel:=GetLang0 (Number);

     P:=Pos ('@1@',Regel);
     IF (P > 0) THEN
        Regel:=Copy (Regel,1,P-1)+Arg1+Copy (Regel,P+3,255);

     P:=Pos ('@2@',Regel);
     IF (P > 0) THEN
        Regel:=Copy (Regel,1,P-1)+Arg2+Copy (Regel,P+3,255);

     P:=Pos ('@3@',Regel);
     IF (P > 0) THEN
        Regel:=Copy (Regel,1,P-1)+Arg3+Copy (Regel,P+3,255);

     GetLang3:=Regel;
END;

{$IFDEF WtrConf}
{---------------------------------------------------------------------------}
{ CheckLang                                                                 }
{                                                                           }
{ Onderdeel van WtrConf:CheckConfig. Controleert of alle entries aanwezig   }
{ zijn en meldt overtollige entries. Foutmelding via ListAddItem. Returns   }
{ TRUE als een fout gevonden is.                                            }
{ Functie is none-destructive voor huidige setup.                           }
{                                                                           }
FUNCTION CheckLang (Path : STRING) : BOOLEAN;

VAR LangTab  : ARRAY[1..LangCount] OF LangMapRecord;
    LangFile : TEXT;
    IORes    : BYTE;
    LineNr   : WORD;
    Regel    : STRING;
    P        : BYTE;
    LangNr   : WORD;
    Nop      : ValNop;
    Lp       : WORD;
    Found    : BOOLEAN;

BEGIN
     CheckLang:=FALSE; { assume no error }

     FOR Lp:=1 TO LangCount DO
         WITH LangTab[Lp] DO
         BEGIN
              Number:=LangIndex[Lp].Number;
              Index:=0; { = not found }
         END;

     Assign (LangFile,Path+FILENAME_LANG);
     {$I-} Reset (LangFile); {$I+} IORes:=IOResult;
     IF (IORes <> 0) THEN
     BEGIN
          ListAddItem ('    Error opening language file '+Path+FILENAME_LANG+' (error '+Byte2String (IORes)+')',65535,Bottom);
          CheckLang:=TRUE; { error found }
          Exit;
     END;

     LineNr:=0;
     WHILE (NOT Eof (LangFile)) DO
     BEGIN
          ReadLn (LangFile,Regel);
          Inc (LineNr);

          Regel:=DeleteFrontAndBackSpaces (Regel);

          IF (Regel = '') OR (Regel[1] = ';') THEN
             Continue;

          { converts tabs to spaces }
          Regel:=CleanTabs (Regel,1);

          Regel:=Regel+' ';  { altijd nummer pakken, inhoud _mag_ leeg zijn }
          P:=Pos (' ',Regel);
          Val (Copy (Regel,1,P-1),LangNr,Nop);

          IF (Nop <> 0) THEN
          BEGIN
               ListAddItem ('    Error in line '+Word2String (LineNr)+' in '+Path+FILENAME_LANG,65535,Bottom);
               CheckLang:=TRUE; { problems! }
               Continue;
          END;

          { delete the number and the space }
          Delete (Regel,1,P);

          Regel:=DeleteFrontAndBackSpaces (Regel);

          { store this item }
          Found:=FALSE;
          FOR Lp:=1 TO LangCount DO
              IF (LangTab[Lp].Number = LangNr) THEN
              BEGIN
                   LangTab[Lp].Index:=1;
                   Found:=TRUE;
                   Break;
              END;

          IF (NOT Found) THEN
          BEGIN
               ListAddItem ('    Language item '+Word2String (LangNr)+' is not needed',65535,Bottom);
               CheckLang:=TRUE; { error }
          END;
     END; { while }

     Close (LangFile);

     FOR Lp:=1 TO LangCount DO
         IF (LangTab[Lp].Index = 0) THEN
         BEGIN
              ListAddItem ('    Missing required language item '+Word2String (LangIndex[Lp].Number),65535,Bottom);
              CheckLang:=TRUE; { error }
         END;
END;
{$ENDIF}

{---------------------------------------------------------------------------}
{ unit initialization                                                       }
{                                                                           }
BEGIN
     LangPtr:=NIL; { nothing read yet }
     LangSize:=0;
END.
