/**************************************************************************
**********  Project:       DecodeBT V1.00
**********  Program:       DecodeBT.c
**********  Last Update:   17.07.1988, 15:04 / HSt
**********  Author:        Bernstein-Zirkel Softworks
**********                 - Hartmut Stein
**********                 Kölnerstr. 7
**********                 D-5090 Leverkusen 3
**********                 Tel.: 02171 / 44195
**********
**********  Remarks:       Übersetzt ein BeckerText-File in ein durch-
**********                 formatiertes ASCII-File
**********
**********  Usage:         DecodeBT ReadFile WriteFile [-INDENTxx] [-NO_NEW]
**********                                             [-SUPERfb]  [-SUBfb]
**********
**********  Parameters:    ReadFile:  Pfad- und Filename d. BeckerText-Files
**********                 WriteFile: Pfad- und Filename d. zu schreibenden
**********                            Files
**********                 -INDENTxx: Alle Zeilen werden um xx Zeichen ein-
**********                            gerückt
**********                 -NO_NEW:   Formfeeds werden unterdrückt
**********                 -SUPERfb:  Alle hochgestellten Zeichen werden mit
**********                            Vordergrundfarbe f und Hintergrund-
**********                            farbe b ausgegeben
**********                 -SUBfb:    Das gleiche für alle tiefgestellten
**********                            Zeichen
**********
**************************************************************************/

#include <stdio.h>
#include <exec/types.h>

#define PRINT(a) fputs(a, stdout);
#define OUTPUT(a) putc(a, out_file);
#define ESCAPE(a, f, b) Escape (a, f, b, out_file);


/**************************************************************************
********** Escape (a, f, b, o) : Gibt das Zeichen a und - wenn TRUE - die
**********                       Vorder- und Hintergrundfarben f und b als
**********                       Escape-Sequenz über den Filehandle o aus.
**********                       f und b dürfen Werte zwischen 1 und 4 ent-
**********                       halten.
**********                       Wird hier vom Macro ESCAPE () aufgerufen.
**************************************************************************/

void Escape (val, fg, bg, out_file)
   UBYTE  val, fg, bg;
   FILE  *out_file;

   {
   OUTPUT (0x1B);
   OUTPUT (0x5B);
   OUTPUT (val);
   if (fg)
      {
      OUTPUT (';');
      OUTPUT ('3');
      OUTPUT (fg + 0x2F);
      }
   if (bg)
      {
      OUTPUT (';');
      OUTPUT ('4');
      OUTPUT (bg + 0x2F);
      }
   OUTPUT (0x6D);
   }


/**************************************************************************
********** BadValue (a) : Gibt eine Fehlermeldung über den String a aus und
**********                beendet das Programm
**************************************************************************/

void BadValue (a)
   BYTE *a;

   {
   PRINT ("Bad value '");
   PRINT (a);
   PRINT ("'\nUse only '0, 1, 2, 3' (= Blue, White, Black, Orange) !\n");
   exit (10);
   }


/**************************************************************************
********** s_toupper (a): Übersetzt den String, auf den a zeigt, in Groß-
**********                buchstaben
**************************************************************************/

void s_toupper (a)
   BYTE *a;

   {
   BYTE i = 0;

   while (a [i] = toupper (a [i]))
      i++;
   }


main (argc, argv)
   BYTE   argc,
        **argv;
   {
   register FILE  *in_file,            /*   'register' macht das Pro-   */
                  *out_file;           /*   gramm etwas schneller, wenn */
   register ULONG  i;                  /*   beide Files im RAM stehen   */
   register UBYTE  ch,                 /*   und verkürzt das Programm   */
                   indent = 0,         /*   um etwa 170 Bytes           */
                   indent_all = 0,
                   super_fg = 0,
                   super_bg = 0,
                   sub_fg = 0,
                   sub_bg = 0,
                   newpage = TRUE;

   if (argc < 3 || argv [1] [0] == '?')
      {
      PRINT ("\nUsage: ");
      PRINT (argv [0]);
      PRINT (" ReadFile WriteFile [-INDENTxx] [-NO_NEW] [-SUPERfb] [-SUBfb]\n\n");
      exit (0);
      }

   for (i = 3; i < argc; i++)
      {
      s_toupper (argv [i]);
      if (! strncmp (argv [i], "-INDENT", 7))
         {
         indent_all = (argv [i] [7] - 48) * 10;
         if (! argv [i] [8])
            indent_all /= 10;
         else
            indent_all += (argv [i] [8] - 48);
         PRINT ("Indent all lines\n");
         }
      else if (! strcmp (argv [i], "-NO_NEW"))
         {
         newpage = FALSE;
         PRINT ("Don't insert newpage-chars !\n");
         }
      else if (! strncmp (argv [i], "-SUPER", 5))
         {
         if (((super_fg = argv [i] [6] - 0x2F) > 4) ||
             ((super_bg = argv [i] [7] - 0x2F) > 4) ||
              (! super_fg) || (! super_bg))
            BadValue (&argv [i] [0]);
         }
      else if (! strncmp (argv [i], "-SUB", 3))
         {
         if (((sub_fg = argv [i] [4] - 0x2F) > 4) ||
             ((sub_bg = argv [i] [5] - 0x2F) > 4) ||
              (! sub_fg) || (! sub_bg))
            BadValue (&argv [i] [0]);
         }
      else
         {
         PRINT ("----- Unknown option ");
         PRINT (argv [i]);
         PRINT (" ignored -----\n");
         }
      }

   if (( in_file = fopen (argv [1], "r")) &&
       (out_file = fopen (argv [2], "w")))
      {
      for (i = 0; i < 0xE3; i++)          /*   als erste überlesen wie  */
         getc (in_file);                  /*   mal den Header ...       */

      while ((BYTE) (ch = getc (in_file)) != -1)
         {
         switch (ch)
            {
            case 0x00:                    /*   neue Zeile               */
               indent = getc (in_file);   /*   Einrückung bearbeiten    */
               for (i = 0; i < 4; i++)
                  ch = getc (in_file);
               if (ch & 0x80 && newpage)  /*   neue Seite (CTRL-L)      */
                  OUTPUT (0x0C);
               for (i = 0; i < indent + indent_all; i++)
                  OUTPUT (' ');
               break;
            case 0x01:                    /*   Formatierungs-Punkt      */
            case 0x16:                    /*   Shift-Space              */
               OUTPUT (' ');
               break;
            case 0x04:                    /*   Trennstrich              */
               OUTPUT ('-');
               break;
            case 0x7F:                    /*   Div. Schriftarten:       */
               {
               BYTE fg = 0,
                    bg = 0;

               ch = getc (in_file);
               ESCAPE ('0', 0, 0)
               if (ch & 0x20)             /*   Rot                      */
                  fg = 4;
               if (ch & 0x08)             /*   Hochsetzen               */
                  {
                  fg = super_fg;
                  bg = super_bg;
                  }
               else if (ch & 0x10)        /*   Tiefsetzen               */
                  {
                  fg = sub_fg;
                  bg = sub_bg;
                  }
               if (ch & 0x01)             /*   Unterstreichen           */
                  {
                  ESCAPE ('4', fg, bg);
                  fg = bg = 0;
                  }
               if (ch & 0x02)             /*   Fett                     */
                  {
                  ESCAPE ('1', fg, bg);
                  fg = bg = 0;
                  }
               if (ch & 0x04)             /*   Kursiv                   */
                  {
                  ESCAPE ('3', fg, bg);
                  fg = bg = 0;
                  }
               if (fg)
                  ESCAPE ('0', fg, bg);
               break;
               }
            default:
               OUTPUT (ch);
               break;
            }                             /*   switch (ch)              */
         }                                /*   while (getc ())          */
      fclose (in_file);
      fclose (out_file);
      }                                   /*   if (in_file && out_file) */
   else
      {
      PRINT ("Couldn't open files ");
      PRINT (argv [1]);
      PRINT (" and ");
      PRINT (argv [2]);
      PRINT (" !\n");
      }
   }                                      /*   main ()                  */
