(*------------------------------------------

  :Module.      CatalogOutput.mod
  :Author.      Albert Weinert  [awn]
  :Address.     Krähenweg 21 , D-5000 Köln 30
  :EMail.       Usenet_> aweinert@darkness.gun.de
  :EMail.       Z-Netz_> A.WEINERT@DARKNESS.ZER
  :Phone.       0221 / 580 29 84
  :Revision.    R.1
  :Date.        29-May-1993
  :Copyright.   Albert Weinert
  :Language.    Oberon-2
  :Translator.  Amiga Oberon 3.00d
  :Contents.    Erstellt einen Catalog für lokalisierte Programme
  :Imports.     <Importiertes, Name/ShortCut des Autors>
  :Remarks.     <Was Du willst, evtl. Usage>
  :Bugs.        <Bekannte Fehler>
  :Usage.       <Angaben zur Anwendung>
  :History.     .0     [awn] 23-May-1993 : Erstellt
  :History.     .1     [awn] 29-May-1993 : Catalog ist lauffähig

--------------------------------------------*)
MODULE CatalogOutput;

IMPORT  SYSTEM,
        ip:=IFFParse,
        Dos,
        Strings,
        cd:=C2OData,
        io,
        cl:=KitCatLocale,
        ms:=MoreStrings,
        BT:=BasicTypes,
        sc:=StringConvert,
        ll:=LinkedLists;

CONST idCTLG = SYSTEM.VAL(LONGINT,"CTLG");
      idFVER = SYSTEM.VAL(LONGINT,"FVER");
      idLANG = SYSTEM.VAL(LONGINT,"LANG");
      idCSET = SYSTEM.VAL(LONGINT,"CSET");
      idSTRS = SYSTEM.VAL(LONGINT,"STRS");

  PROCEDURE Create*(name:ARRAY OF CHAR):BOOLEAN;
  (*------------------------------------------
    :Input.     name : Name des zu Erzeugenden Catalogs
    :Output.    TRUE bei Erfolgreicher Erstellung
    :Semantic.  Erstellt einen Catalog
    :Note.
    :Update.    29-May-1993 [awn] - erstellt.
  --------------------------------------------*)
    VAR iff: ip.IFFHandlePtr;
        sn, tn : ll.Node;
        string:BT.DynString;
        size: LONGINT;
        writeok : BOOLEAN;
        array32 : ARRAY 32 OF SYSTEM.BYTE;
    BEGIN
      writeok:=FALSE;
      iff:=ip.AllocIFF();
      writeok:=iff#NIL;

      FOR size:= 0 TO LEN(array32)-1 DO (* `size' kurzeitig als Zähler missbraucht *)
        array32[size]:=0;
      END;

      IF writeok THEN
        iff.stream:=SYSTEM.VAL(LONGINT,Dos.Open(name,Dos.newFile));
        writeok:=iff.stream#NIL;
        IF writeok THEN
          ip.InitIFFasDOS(iff);
          writeok:=ip.OpenIFF (iff,ip.write)=0;

          (* Begin des Catalogs *)
          IF writeok THEN
            writeok:=ip.PushChunk(iff,idCTLG,ip.idFORM, ip.sizeUnknown)=0;
            (* VersionStrings setzen *)
            IF writeok THEN
              writeok:=ip.PushChunk(iff,idCTLG,idFVER, ip.sizeUnknown)=0;
              IF writeok THEN
                writeok:=ip.WriteChunkBytes(iff,cd.CTList.version,Strings.Length(cd.CTList.version)+1) >=0;
              END;
              IF writeok THEN
                writeok:=ip.PopChunk(iff)=0;
              END;
            END;
            (* Language setzen *)
            IF writeok THEN
              writeok:=ip.PushChunk(iff,idCTLG,idLANG, ip.sizeUnknown)=0;
              IF writeok THEN
                writeok:=ip.WriteChunkBytes(iff,cd.CTList.language,Strings.Length(cd.CTList.language)+1)>=0;
              END;
              IF writeok THEN
                writeok:=ip.PopChunk(iff)=0;
              END;
            END;
            (* CodeSet setzen *)
            IF writeok THEN
              writeok:=ip.PushChunk(iff,idCTLG,idCSET, ip.sizeUnknown)=0;
              IF writeok THEN
                writeok:=ip.WriteChunkBytes(iff,array32,LEN(array32))>0; (* kein Ahung warum gerade 32 Bytes,
                                                                            war so im vom CatComp erzeugten Catalog *)
              END;
              IF writeok THEN
                writeok:=ip.PopChunk(iff)=0;
              END;
            END;
            (* Strings setzen *)
            IF writeok THEN
              writeok:=ip.PushChunk(iff,idCTLG,idSTRS, ip.sizeUnknown)=0;

              tn:=cd.CTList.head;
              WHILE (tn # NIL) & writeok DO
                IF tn(cd.CTNode).converted^ # tn(cd.CTNode).dnode.converted^ THEN
                  (* ID Nummer setzen *)
                  writeok:=ip.WriteChunkBytes(iff,tn(cd.CTNode).idNumber,4)>=0;
                  IF writeok THEN
                    size:=Strings.Length(tn(cd.CTNode).converted^)+tn(cd.CTNode).lengthbytes ;
                    (* Wenn die Länge durch 4 Teilbar ist dann muss noch ein
                       Byte drangehangen werden, ich glaube das es wegem dem
                       NullByte, merkwürdig es auf alle Fälle *)
                    IF size MOD 4 = 0 THEN INC(size) END;
                    (* Länge setzen *)
                    writeok:=ip.WriteChunkBytes(iff,size,4)>=0;
  
  
                    IF writeok THEN
                      (* String einsetzen *)
                      writeok:=sc.SetLengthBytes(tn(cd.CTNode).converted^,tn(cd.CTNode),tn(cd.CTNode).lengthbytes,FALSE);
                      IF writeok THEN
                        writeok:=ip.WriteChunkBytes(iff,tn(cd.CTNode).converted^,size)>=0;
                      END;
                    END;
                    IF writeok THEN
  
                      (* Auf eine durch 4 Teilbare länge aufrunden *)
                      writeok:=ip.WriteChunkBytes(iff,array32,4-(size MOD 4))>=0;
                    END;
                  END;
                END;
                tn:=tn.next;
              END;

              IF writeok THEN
                writeok:=ip.PopChunk(iff)=0;
              END;
            END;
            IF writeok THEN
              writeok:=ip.PopChunk(iff)=0;
            END;
          ip.CloseIFF (iff);
          ELSE;
            cd.error:=cl.errOpenIFF;
          END;
          Dos.OldClose (SYSTEM.VAL(Dos.FileHandlePtr,iff.stream));
        ELSE;
          cd.error:=cl.errOpenCat;
        END;
        ip.FreeIFF(iff);
      ELSE;
        cd.error:=cl.errOpenIFF;
      END;
      IF (~writeok) & (cd.error = NIL) THEN
        cd.error:=cl.errCreateCat;
      END;
      RETURN writeok;
    END Create;

END CatalogOutput.
