/*
 * Tools.c
 *
 * Sammlung nützlicher Funktionen
 *
 * freenull             Routine für Speicherfreigabe
 * ActivateTabGadget    aktiviere erstes Tabcyle-Gadget
 * OpenLib              OpenLibrary mit Fehlermeldung
 * CheckErr             UMS-Error - Fehlermeldung in EasyRequest
 * ErrorBeep
 * StrDup               kopiert und alloziert Stringspace
   
   todo 
   WindowClass 
   - WC_OPEN, WC_CLOSE
   - winpointer
   - Ereignistabelle als globale Execliste für die application.
     Events aufnehmen. austragen. ändern. ausgeben.
     Signal triggert --> Auswerten lt. Tabelle --> Routine starten
     Problem: Datenstruktur der Ereignistabelle
 */

/* Tools.c: weitere kleine Routinen aufnehmen, todo */

//freenull.c            /* Routine für Speicherfreigabe */

/* freenull */

void 
FreeNull (void *Pointer)
{
  if (Pointer)
    {
      free (Pointer);
      Pointer = NULL;
    }
}


//ActivateTabGadget.c   /* aktiviere erstes Tabcyle-Gadget */

/*
 * ActivateTabGadget()
 *
 * This function scans a window's gadget list and activates the
 * first gadget that supports tab cycling.
 *
 * It should be called when your window gets a VANILLAKEY message
 * with a TAB code (0x09).  This gives the user a way to start
 * tab cycling through gadgets.
 */

void 
ActivateTabGadget (struct Window *window)
{
  struct Gadget *gad;

  for (gad = window->FirstGadget; gad != NULL; gad = gad->NextGadget)
    {
      if ((gad->Flags & GFLG_TABCYCLE) && !(gad->Flags & GFLG_DISABLED))
	{
	  ActivateGadget (gad, window, NULL);
	  break;
	}
    }
}


//OpenLib.c             /* OpenLibrary mit Fehlermeldung     */


/*
 * OpenLib
 *
 * öffnet Library, bei Mißerfolg Fehlermeldung mit Text.
todo: libraries in Array.
 *
 * INPUTS
 *   UBYTE        *libName   - String mit Library-[Pfad]/Name
 *   unsigned long version   - Die älteste noch akzeptierte Version
 *
 * RESULT
 *   Zeiger auf Library-Struktur, oder NULL bei einem Fehler
 */

struct Library *
OpenLib (UBYTE * libName, unsigned long version)
{
  struct Library *LibBase;

  LibBase = OpenLibrary (libName, version);

  if (LibBase == NULL)
    {
      printf ("Hinweis:\n"
	      "Library '%s', Version %ld konnte nicht geöffnet werden.\n\n"
	      "Bitte legen Sie diese Library in das passende Verzeichnis.\n"
	      "Starten Sie dann erneut " NB_NAME ".\n", libName, version);
    }
  return (LibBase);
}


//CheckErr.c            /* UMS-Error - Fehlermeldung  */

/* für Kleinigkeiten: */

void 
ErrorBeep (void)
{
  DisplayBeep (NULL);
}

/* für größere Fehler */

BOOL 
CheckErr (void)
{
  UMSError err;
  err = UMSErrNum (account);

  /* Fehler aufgetreten? */
  if (err != UMSERR_OK)
    {
      STRPTR errorstring = UMSErrTxt (account);
      STRPTR userhelp = NULL;
      struct EasyStruct myES =
      {
	sizeof (struct EasyStruct),
	0,
	"UMS-Hinweis",
	"(%ld)\n%s\n%s",	/*todo: lokalisieren */
	"Weiter",		/*todo: lokalisieren */
      };

      switch (err)
      {
      case UMSERR_Unknown:
        userhelp = "Die Fehlerursache ist leider nicht genau einzugrenzen.\n"
                   "Versuchen Sie es erneut. Oder brechen Sie NewsBreaker ab.";
        break;

      case UMSERR_NoSubject:
        userhelp = "Fügen Sie bitte eine Betreffzeile (Subject) ein.";
        break;

      case UMSERR_ToBig:
        userhelp = "Ihre Nachricht ist zu lang. Kürzen Sie Ihren Text.";
        break;

      case UMSERR_NotRunning:
        userhelp = "Der UMS-Server läuft jetzt nicht.\nLoggen Sie sich neu ein.";
        break;

      case UMSERR_NoToName:
        userhelp = "Wer soll die Nachricht bekommen? Legen Sie den Empfänger fest.";
        break;

      case UMSERR_CfgLocked :
        userhelp = "Der Zugriff auf die UMS-Konfiguration wurde verweigert.\n"
                   "Beenden Sie die dafür verantwortlichen Programme.";
        break;

      case UMSERR_MsgCorrupted:
        userhelp = "Die Nachricht ist beschädigt und verfälscht.\n"
                   "Mit einem Hilfsprogramm können Sie vielleicht die Nachricht retten." ;
        break;

      case UMSERR_NoHdrSpace :
        userhelp = "Kein Platz für Nachrichten-Header. Ändern Sie die\n"
                   "entsprechenden UMS-Konfigurations-Einstellungen.\n"
                   "Tip: versuchen Sie es mit einer kürzeren Betreffzeile.";
        break;

      case UMSERR_NoSuchMsg :
        userhelp = "Diese Nachricht gibt es in Ihrer Messagebase nicht.\n"
                   "Vielleicht wurde die Nachricht von einem Tool gelöscht\n"
                   "oder an einen anderen Platz verschoben.";
        break;

      case UMSERR_BadName :
        userhelp = "Der gewählte Name ist nicht zulässig. "
                   "Verwenden Sie einen gültigen Namen.";
        break;

      case UMSERR_MissingTag :
        userhelp = "Interner Fehler: Wichtiger Tag wurde vergessen. "
                   "Schreiben Sie bitte dem Autor " NB_AUTHOR_NAME "\n"
                   "einen kurzen Fehlerbericht. Danke!" ;
        break;

      case UMSERR_NotFound:
        userhelp = "Der versuchte Zugriff war leider erfolglos.";
        break;

      case UMSERR_BadPattern :
        userhelp = "Falsches Namensmuster (Pattern). Überprüfen Sie\n"
                   "Ihre UMS-Konfiguration auf fehlerhafte Pattern.";
        break;


      case UMSERR_BadVarname  :
        userhelp = "In Ihrer UMS-Konfiguration taucht eine nicht erlaubte\n"
                   "Variable auf. Ändern Sie das: lesen Sie die Dokumentation\n"
                   "über zulässige Konfigurationsvariablen.\n";
        break;

      case UMSERR_FsFull  :
        userhelp = "Es gibt keinen Disk-Platz für neue Nachrichten.\n"
                   "Brechen Sie NewsBreaker ab. Starten Sie SetExpire.\n"
                   "Danach Servercontrol Cleanup. Durch dieses Aufräumen\n"
                   "sollte wieder Platz für neue Nachrichten freiwerden.";
        break;

      case UMSERR_NoMsgMem  :
        userhelp = "Zuwenig RAM-Speicher, um Nachricht einzulesen.\n"
                   "Entfernen Sie unbenötigte Programme. Schließen Sie geöffnete "
                   "Fenster.";
        break;
      case UMSERR_ServerTerminated  :
        userhelp = "Aus irgendeinem Grund hat sich der UMS-Server "
                   "ausgeschaltet. Loggen Sie sich bitte neu ein.\n";
        break;

      default:
        userhelp = "Bitte lesen Sie die UMS-Dokumentation.\n"
                   "Hier finden Sie Hilfen zur Problemlösung \n"
                   "und Fehlerbeseitigung.";
        break;
      }

      EasyRequest (0, &myES, NULL, err, errorstring, userhelp);
    }
  return (err);
}


//StrDup.c              /* kopiert und alloziert Stringspace */

/*
 * strdup(const char *s)
 *
 * Kopiert den String, auf den s zeigt, reserviert Platz,
 * gibt Zeiger auf den neuen String als Ergebnis zurück.
 * Ausnahme: s = NULL. Dann wird kein Stringspeicher reserviert.
 *
 * Der reservierte Platz muß später mit free(neuerstring) an das
 * System zurückgegeben werden.
 *
 * Benötigt strcpy(), malloc()
 */

char *
strdup (const char *string)
{
  /* Zeiger auf neuen String */
  char *newstring;

  if (string)			/* wenn string vorhanden */
    {
      /* belege Speicher, kopiere String */
      if (NULL != (newstring = malloc (strlen (string) + 1)))
	strcpy (newstring, string);
      return newstring;
    }
  else
    return NULL;		/* wenn string = NULL */
}


// WindowClass

/*   todo
   WindowClass
   - WC_OPEN, WC_CLOSE
   - winpointer
   - Ereignistabelle als globale Execliste für die application.
     Events aufnehmen. austragen. ändern. ausgeben.
     Signal triggert --> Auswerten lt. Tabelle --> Routine starten
     Problem: Datenstruktur der Ereignistabelle
*/

#define WC_NEW  11
#define WC_DISPOSE 22

typedef struct wcdata
 {
 Window * wc_win;
 /* weitere Daten hier hin */
 };

ULONG
WindowClass (ULONG * handle, ULONG type, ULONG taglist)
{

switch(type)
{
case WC_NEW:
     {
	  handle = (ULONG *)OpenWindowTags (NULL,
          /* Defaults beachten */

				WA_Flags, WFLG_DEPTHGADGET |
				WFLG_DRAGBAR |
				WFLG_CLOSEGADGET |
				WFLG_SIZEGADGET |
				WFLG_SIZEBBOTTOM |
				WFLG_SIZEBRIGHT,
				WA_Activate, TRUE,
				WA_SmartRefresh, TRUE,
				WA_IDCMP, CLOSEWINDOW |
				REFRESHWINDOW |
				LISTVIEWIDCMP |
				BUTTONIDCMP |
				IDCMP_NEWSIZE,
				WA_MinWidth, 200,
				WA_MinHeight, 80,
				WA_Title, NB_NAME,
				TAG_DONE);
    break;
    }

case WC_DISPOSE:
    {
    CloseWindow( (Window *) handle);
    break;
    }
}
return (TRUE);
}

// Kludge

/* "Kludge:" Ersatz für fehlerhaftes "SetGadgetAttrs" in einer link-lib :-( */
/* 25.12.95 */

ULONG 
SetGadgetAttrsX (struct Gadget *gadget, struct Window *window,
		 struct Requester *requester, unsigned long tag1,...)
{
  return SetGadgetAttrsA (gadget, window, requester, (struct TagItem *) &tag1);
}

/* verwende also SetGadgetAttrsX() statt dem Original <SetGadgetAttrs()> */
