/*
***************************************************************************
*
* Datei:
*    RSysIntuiCtrl.c
*
* Inhalt:
*    void *LockWindow(struct Window *win);
*    void UnlockWindow(void *req);
*    void EnableGadget(struct Window *Wnd, struct Gadget *gad, int on_off);
*    void makelabelvisible(struct Gadget *gad);
*    char *gadgetbuff(struct Gadget *gad);
*    void DisableSysRequest(int disable);
*    void MakeWindowRefresh(struct Window *window);
*    void RefreshMainWindowPattern(void);
*    void InitListView(struct Window *wind, struct Gadget *gad, struct List *list, int top);
*    void RefreshListView(void);
*    void EmptyListView(void);
*    void ClearIntuiMsgPort(struct Window *wnd);
*    void PrintHeader(enum ListTypes type, char *text);
*    void PrintInfo(char *text, int speakit, int waitit);
*    void PrintStatistics(void);
*    short MyEasyRequest(struct Window *wind, unsigned char *title, unsigned char *Gadgets, unsigned char *Body, ...);
*    void OpenMainWindow(void);
*    void CloseASysWindow(struct Window **wind, struct Gadget **windgadlist, struct Menu **windmenus);
*    int OpenASysWindow(int (*func)(), int kill);
*    void CenterWindow(struct Screen *scr, unsigned short *top, unsigned short *left, unsigned short width, unsigned short height);
*
* Bemerkungen:
*    Intuition Supportroutinen für die Verwaltung der Intuitionobjekte
*    des Hauptwindows von RSys.
*    (Aus RSysUtils.c ausgelagert)
*
* Erstellungsdatum:
*    25-Jun-93    Rolf Böhme
*
* Änderungen:
*    25-Jun-93    Rolf Böhme    Erstellung
*    25-Jun-93    Rolf Böhme    makelabelvisible() hinzugefügt
*
***************************************************************************
*/

#include "RSysDebug.h"
#include "RSysFunc.h"

   /*
    * LockWindow() öffnet einen Requester der Größe 1x1 und sperrt
    * das Window damit gegen Eingaben
    */
APTR
LockWindow(struct Window * win)
{
   struct Requester *req;

   DPOS;

   req = (struct Requester *) MyAllocVec(sizeof(struct Requester),
                                         MEMF_ANY | MEMF_CLEAR, NO_KILL);

   if (req)
   {
      req->LeftEdge = 1;
      req->TopEdge = 1;
      req->Width = 1;
      req->Height = 1;
      req->Flags = SIMPLEREQ | NOREQBACKFILL;

      Request(req, win);
   }

   return ((APTR) req);
}

   /*
    * UnlockWindow() gibt ein mit LockWindow() gesperrtes Window
    * wieder frei. Es ist dann wieder für Benutzereingaben
    * zugänglich
    */
void
UnlockWindow(APTR req)
{
   DPOS;

   if (req)
   {
      EndRequest((struct Requester *) req, ((struct Requester *) req)->RWindow);
      MyFreeVec(req);
   }

   return;
}

   /*
    * EnableGadget() schaltet ein Gadget auf einem Window ein oder
    * aus
    */
void
EnableGadget(struct Window *Wnd, struct Gadget *gad, int on_off)
{
   DPOS;

   GT_SetGadgetAttrs(gad, Wnd,
                     NULL,
                     GA_Disabled, NOT(on_off),
                     TAG_DONE);

   return;
}

void
makelabelvisible(struct Gadget *gad)
{
   extern int bgc, bpc;

   if(gad->GadgetText)
   {
      gad->GadgetText->DrawMode |= JAM2;
      /*
      gad->GadgetText->BackPen   = bgc ? bgc : 0;
      gad->GadgetText->FrontPen  = bpc ? bpc : 1;
      */
      gad->GadgetText->BackPen   = 0;
      gad->GadgetText->FrontPen  = 1;
   }

   return;
}

   /*
    * gadgetbuff() ermittelt den String, der in einem Stringgadget
    * steht
    */
char *
gadgetbuff(struct Gadget *gad)
{
   DPOS;

   return ((char *)(((struct StringInfo *) (gad->SpecialInfo))->Buffer));
}


   /*
    * DisableSysRequest() unterdrückt die Anzeige von
    * Systemrequestern, die beispielsweise nach einem Zugriff auf
    * einen nicht existierenden Datenträger erscheinen
    */
void
DisableSysRequest(int disable)
{
   static APTR wind;
   struct Process *p = (struct Process *) FindTask(NULL);

   DPOS;

   if (disable)
   {
      wind = (APTR) p->pr_WindowPtr;
      p->pr_WindowPtr = (APTR) (-1);
   }
   else
      p->pr_WindowPtr = wind;

   return;
}

   /*
    * MakeWindowRefresh() führt die Standard-System-Routinen zur
    * Erneuerung eines Windows aus
    */
void
MakeWindowRefresh(struct Window *window)
{
   GT_BeginRefresh(window);
   GT_EndRefresh(window, TRUE);
   return;
}

   /*
    * RefreshMainWindowPattern() erneuert das Patternmuster
    * des Hauptfensters von RSys
    */
void
RefreshMainWindowPattern(void)
{
   int gl[] = {GD_ListeLV, GD_TextHeader, GD_InfoMsgGad};

   RefreshRastPort(SysWnd, SysGadgets, gl, 3);

   return;
}


   /*
    * InitListView() initialisiert ein ListView in einem Fenster
    * mit einer anzugebenden Liste. Ist die Liste NULL, wird das
    * ListView systemgemäß mit ~0 initialisiert
    */
void
InitListView(struct Window *wind, struct Gadget *gad, struct List *list, int top)
{
   struct List *lvlist = (list != NULL) ? list : (struct List *)(~0);

   DPOS;

   if(list != NULL)
      GT_SetGadgetAttrs(gad, wind,NULL,GTLV_Labels, (~0), TAG_DONE);

   if(top == UNSETLVPOS)
      GT_SetGadgetAttrs(gad, wind,
                        NULL,
                        GTLV_Labels, lvlist,
                        TAG_DONE);
   else
      GT_SetGadgetAttrs(gad, wind,
                        NULL,
                        GTLV_Labels, lvlist,
                        GTLV_Top, top,
                        GTLV_Selected, (~0),
                        TAG_DONE);
}

   /*
    * RefreshListView() erneuert das ListView auf dem Hauptwindow
    */
void
RefreshListView(void)
{
   DPOS;

   InitListView(SysWnd,SysGadgets[GD_ListeLV],&ListeLVList,UNSETLVPOS);
   return;
}

   /*
    * EmptyListView() löscht die Einträge des Haupt-ListViews
    */
void
EmptyListView(void)
{
   DPOS;

   InitListView(SysWnd,SysGadgets[GD_ListeLV],NULL,0);

   NewList(&ListeLVList);

   RefreshListView();

   GT_RefreshWindow(SysWnd, NULL);

   return;
}

   /*
    * ClearIntuiMsgPort() beantwortet alle anliegenden Messages
    * eines Windows
    */
void
ClearIntuiMsgPort(struct Window *wnd)
{
   struct IntuiMessage *message;

   DPOS;

   while (message = (struct IntuiMessage *) GT_GetIMsg(wnd->UserPort))
      GT_ReplyIMsg(message);

   return;
}

   /*
    * PrintHeader() gibt einen Text im Titelfeld über dem
    * Haupt-ListView aus
    */
void
PrintHeader(enum ListTypes type, char *text)
{
   DPOS;

   LastID = type;

   GT_SetGadgetAttrs(SysGadgets[GD_TextHeader], SysWnd,
                     NULL,
                     GTTX_Text, (UBYTE *) ((text == NULL) ?
                                    EntryAttr[type].ea_header :
                                    text),
                     TAG_DONE);

   return;
}

   /*
    * PrintInfo() gibt einen Text im Messagefeld vom Hauptfenster
    * aus. Falls der Sprachmodus aktiviert ist und der Text
    * gesprochen werden soll, wird er zusätzlich auf dem
    * Narrator-Device ausgegeben
    */
void
PrintInfo(char *text, int speakit,int waitit)
{
   static char help[BUFSIZE];
   int   i,
         len = strlen(text),
         fill = ((BUFSIZE - len) >> 1);

   DPOS;

   for (i = 0; i < fill; i++)
      help[i] = ' ';

   help[fill] = STRINGEND;

   strcat(help, text);

   if (SysWnd)
   {
      GT_SetGadgetAttrs(SysGadgets[GD_InfoMsgGad], SysWnd,
                        NULL,
                        GTTX_Text, (UBYTE *) help,
                        TAG_DONE);

      if (NOT(Flags.fastmode))
         WaitTOF();
   }

   if (Flags.speakmode && speakit)
      Speak(help);

   if(waitit != 0)
      Delay(waitit);

   return;
}

   /*
    * PrintStatistics() gibt für bestimmte Listen eine
    * Zusammenfasung (Anzahl der ermittelten Einträge) aus
    */
void
PrintStatistics(void)
{
   char  help[BUFSIZE];

   DPOS;

   if(countentries == 0)
      sprintf(help, "No %s entries read", EntryAttr[LastID].ea_type);
   else
      if (EntryAttr[LastID].ea_counted)
         sprintf(help, "%ld %s entries read", countentries,
                 EntryAttr[LastID].ea_type);
      else
         sprintf(help, "%s entries read", EntryAttr[LastID].ea_type);

   PrintInfo(help, SPEAK, 0);

   if (SysWnd)
      RefreshListView();

   return;
}

   /*
    * MyEasyRequest() erzeugt nach Vorgaben einen
    * System-Standard-Requester
    */
WORD
MyEasyRequest(struct Window * wind, UBYTE * title,
              UBYTE * Gadgets, UBYTE * Body,...)
{
   struct EasyStruct Easy;
   WORD  Result;
   va_list VarArgs;
   APTR  req;

   DPOS;

   Easy.es_StructSize = sizeof(struct EasyStruct);

   Easy.es_Flags = NULL;
   Easy.es_Title = title;
   Easy.es_TextFormat = Body;
   Easy.es_GadgetFormat = Gadgets;

   if (wind)
      req = LockWindow(wind);

   va_start(VarArgs, Body);
   Result = EasyRequestArgs(wind, &Easy, NULL, VarArgs);
   va_end(VarArgs);

   if (wind)
      UnlockWindow(req);

   return (Result);
}

   /*
    * OpenMainWindow() öffnet das Hauptffenster
    */
void
OpenMainWindow(void)
{
   DPOS;

   if (!SetupScreen())
      OpenASysWindow(OpenSysWindow, KILL);
   else
      ErrorHandle(SCREEN_ERR, INFO_FAIL, KILL);

   return;
}

   /*
    * CloseASysWindow() schließt ein von RSys verwaltetes Window
    */
void
CloseASysWindow(struct Window **wind,
                struct Gadget **windgadlist,
                struct Menu **windmenus)
{
   DPOS;

   if (windmenus && *windmenus)
   {
      ClearMenuStrip(*wind);
      FreeMenus(*windmenus);
      *windmenus = NULL;
   }

   if (wind && *wind)
   {
      CloseWindow(*wind);
      *wind = NULL;
   }

   if (windgadlist && *windgadlist)
   {
      FreeGadgets(*windgadlist);
      *windgadlist = NULL;
   }

   return;
}

   /*
    * OpenASysWindow() öffnet Window mit einer
    * vorzugebenden Funktion und mit einer allgemeinen
    * Fehlerbehandlung
    */
int
OpenASysWindow(int (*func) (void), int kill)
{
   ULONG failed = (*func) ();

   DPOS;

   switch (failed)
   {
      case 1L:
      case 2L:
      case 3L:
         ErrorHandle(GADGET_MENU_ERR, CREATE_FAIL, kill);
         break;

      case 4L:
         ErrorHandle(WINDOW_ERR, OPEN_FAIL, kill);
         break;
   }

   return (failed ? FALSE : TRUE);
}

   /*
    * CenterWindow() ermittelt die Fensterposition, um das
    * Fenster zentriert auf einem Screen erscheinen zu lassen
    */
void
CenterWindow(struct Screen *scr, UWORD * top, UWORD * left,
             UWORD width, UWORD height)
{
   WORD  LE,
         TE;

   DPOS;

   if (scr)
   {
      WORD restwidth  = scr->Width  - width,
           restheight = scr->Height - height;

      LE = (Flags.mousewindow ? scr->MouseX : (scr->Width  >> 1)) -
           (width  >> 1);
      TE = (Flags.mousewindow ? scr->MouseY : (scr->Height >> 1)) -
           (height >> 1);

      *left = (LE < 0) ? (UWORD)0 : ((LE > restwidth ) ? restwidth  : LE);
      *top  = (TE < 0) ? (UWORD)0 : ((TE > restheight) ? restheight : TE);
   }

   return;
}
