/*----------------------------------------------------------------------------
   File   :    IconSwap.c
   Projekt:    IconSwap
   Inhalt :    OpenAll  (die berühmte "Öffne-Mir-Alles"-Routine)
               CloseAll (Zumachen tu ich das dann auch wieder)
               SwapPlane(tauscht zwei Bitplanes aus)
               SwapIcon (Bearbeitet ein Icon (s.o.))
               ShowHelp (Gibt den Hilfe-Text in CLI-Fenster aus)
               main     (zumindest mal ein HauptPrg)

   Version:    0.14
   Datum  :    23./24./29. und 31.März 1991
   Autor  :    Uwe Röhm
   Adresse:    Auber Str. 25,  W-6209 Hohenstein 4
    (Semester) Wörthstr. 18    W-8390 Passau
   Bemerkung:
   "IconSwap" soll das leidige Problem mit den vertauschten 2.0 und 1.3 Farben
   in den Griff kriegen...
----------------------------------------------------------------------------*/
short PRGVersion = 0;
short PRGRevision= 14;

#include <exec/Types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <workbench/icon.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include "IconSwap.h"

#ifndef LATTICE
   #include <functions.h>
#else
   #include <proto/dos.h>
   #include <proto/exec.h>
   #include <proto/icon.h>
/* Lattice-CTRL-C Handling ausschalten... */
   int CXBRK (void)     {  return (0); }
#endif
#include <string.h>
#include <stdlib.h>

/*  --------------------  Globale Variablen   --------------------  */
struct Library *IconBase;
struct FileInfoBlock *FIB;
extern struct DosLibrary *DOSBase;
BOOL FromWB;
BPTR fh;


/*  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
   Funktion  : OpenAll
   Parameter : --
   Rückgabe  : BOOL (TRUE+ => alles korrekt geöffnet, sonst FALSE)

   Aufruf von: main (s.u.)
   UnterFunks: --
   Autor     : Floyd (das bin ich)
   Datum     : 29.03.1991
   Bemerkung :
   Die benötigte Icon-Library wird geöffnet und - sofern vom CLI gestartet -
   die Standart-Output ermittelt...
--  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  */
BOOL OpenAll ()
{
   if (!FromWB)
      fh = Output ();

   FIB = (struct FileInfoBlock *) AllocMem (sizeof (*FIB), MEMF_CLEAR | MEMF_PUBLIC);

   IconBase = OpenLibrary ("icon.library", 33);
   return (( (IconBase == NULL) || (FIB == NULL) ) ? FALSE : TRUE);
}


/*  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
   Funktion  : CloseAll
   Parameter : --
   Rückgabe  : --

   Aufruf von: main (s.u.)
   UnterFunks: --
   Autor     : immer noch Floyd
   Datum     : 23.03.91
   Bemerkung :
   Meine globale ShowDown-Funktion. Was mit "OpenAll" aufgemacht wurde, sollte
   hier auch wieder geschlossen werden. ACHTUNG! Die Standart-Output schließt
   meine C-Exitroutine (ich lasse also die Finger davon, sonst GURU)!
--  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  */
VOID CloseAll ()
{
   if (FIB)
   {  FreeMem (FIB, sizeof (*FIB));
      FIB = NULL;
   }

   if (IconBase)
   {  CloseLibrary (IconBase);
      IconBase = NULL;
   }
}


/*  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
   Funktion  :  SwapPlane
   Parameter :  struct Image *(Zeiger auf Image mit zu vertauschenden Daten)
   Rückgabe  :  BOOL (ob getauscht wurde...)

   Aufruf von:  SwapIcon (s.u.)
   UnterFunks:  --
   Autor     :  Floyd
   Datum     :  31.03.91
   Bemerkung:
   "SwapPlane" vertauscht in 4farbigen Info-Dateien die beiden BitPlanes
--  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  */
BOOL SwapPlane (struct Image *Im)
{
   USHORT *p1, *p2, mitte, swap, i;

   if ( Im->Depth == 2 )
   {  mitte = Im->Height *
              (((Im->Width % 16) == 0) ? (Im->Width / 16) : (Im->Width / 16 + 1));
      p1 = Im->ImageData;
      p2 = p1 + mitte;
      for (i = 0; i < mitte; i++, p1++, p2++)
      {  swap = *p1;
         *p1  = *p2;
         *p2  = swap;
      }
      return TRUE;
   }
   return FALSE;
}


/*  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
   Funktion  :  SwapIcon
   Parameter :  char * (Name der .info-Datei)
   Rückgabe  :  --

   Aufruf von:  main (s.u.)
   UnterFunks:  SwapPlane (s.o.)
   Autor     :  Floyd
   Datum     :  24.3.91
   Bemerkung:
   sorgt für den Austausch von Select- und Normalen ImageDaten und schreibt
   dann das Icon unter dem selben Namen zurück.
--  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  */
VOID SwapIcon (char *name)
{
   struct DiskObject *Icon;

   if (strlen (name) > 0)
   {
      Icon = GetDiskObject (name);
      if (Icon->do_Gadget.GadgetRender != NULL)
      {
         if (SwapPlane ((struct Image *) Icon->do_Gadget.GadgetRender))
         {
            if (Icon->do_Gadget.SelectRender != NULL)
               SwapPlane ((struct Image *) Icon->do_Gadget.SelectRender);

            PutDiskObject (name, Icon);
         }
      }
      FreeDiskObject (Icon);
   }
}


/*  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
   Funktion  :  ShowHelp
   Parameter :  --
   Rückgabe  :  --

   Aufruf von:  main (s.u.)
   UnterFunks:  --
   Autor     :  Floyd, der Römer
   Datum     :  29.03.91
   Bemerkung :
   Gibt eine Kurzbeschreibung dieses wahrhaften tollen PRGs aus (wenn ich den
   Sinn mal vergessen sollte, werde ich noch dankbar sein...).
--  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  */
VOID ShowHelp ()
{
   Write (fh, "USAGE: IconSwap <Name1> <Name2> ....\n", 37);
   Write (fh, "'IconSwap' tauscht in Icons mit vier Farben (Depth == 2)\n", 57);
   Write (fh, "die beiden Bitplanes aus und ermöglicht es so, Icons unter\n", 59);
   Write (fh, "2.0 Style und 1.3 Style auszutauschen. Die Endung '.info'\n", 58);
   Write (fh, "wird vom Program selbständig an die Dateinnamen angehängt.\n", 59);

   Write (fh, "Compiliert am:   ",17);
   Write (fh, __DATE__, strlen (__DATE__));
   Write (fh, "  um  ", 6);
   Write (fh, __TIME__, strlen (__TIME__));
   Write (fh, ".\n",2);
}


/*  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
   Funktion  :  main
   Parameter :  int arc      (Zahl der CLI-Parameter)
                char *argv[] (einzelne Paramterstrings)
   Rückgabe  :  --

   Aufruf von:  Benutzer über CLI
   UnterFunks:  OpenAll (s.o.)
                CloseAll (s.o.)
                SwapPlane (s.o.)
   Autor     :  Floyd
   Datum     :  29.März 1991
   Bemerkung:
   Das Hauptprogramm sorgt für die richtige Unterscheidung zwischen CLI und
   WB-Aufruf. Unter der WB versuche ich zudem verzweifelt, daß ich auch Drawer
   und Disk-Dateien korrekt anspreche. Da ich "_tinymain" und "exit ()" ver-
   wende, muß ich zwar selbst die Standart-Output suchen, brauche diese und
   die DOSBase aber nicht selbst zu schließen!
--  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  */
VOID __stdargs __saveds main (int argc, char *argv[])
{
int i;
BPTR cd, pd;
BOOL retcode;
struct WBArg *wbarg;
struct WBStartup *WBMsg;

   FromWB = (argc == 0) ? TRUE : FALSE;

   if (retcode = OpenAll ())
   {
      if (!FromWB)
      {  Write (fh, HAILTEXT, strlen (HAILTEXT));

         if (argc == 1)
            Write (fh, "Keinen Filenamen angegeben...\n", 30);
         else
         if ((argc == 2) && (strcmp (argv[1], "?") == 0))
            ShowHelp ();
         else
            for (i = 1; i < argc; i++)
               SwapIcon (argv[i]);
      }
      else
      {  WBMsg = (struct WBStartup *) argv;
         for (i = 1, wbarg = (WBMsg->sm_ArgList + 1); i < WBMsg->sm_NumArgs; i++, wbarg++)
         {  if ( wbarg->wa_Lock != NULL )
            {  cd = CurrentDir (wbarg->wa_Lock);

               if (strlen (wbarg->wa_Name) == 0)/* Länge 0, aber Pointer != NULL*/
               {
                  Examine (wbarg->wa_Lock, FIB); /* Namen von Dir holen */
                  if (pd = ParentDir (wbarg->wa_Lock)) /* ein Dir */
                  {  CurrentDir (pd);
                     SwapIcon (FIB->fib_FileName);
                     UnLock (pd);
                  }
                  else  /* also wohl ROOT - und damit 'Disk.info' */
                     SwapIcon ("Disk");
               }
               else
                  SwapIcon (wbarg->wa_Name);
               (void) CurrentDir (cd);
            }
         }
      }
   }

   CloseAll ();
   exit ( (retcode == TRUE) ? 0 : 1 );
}
