/*
***************************************************************************
*
* Datei:
*	  RSysHelp.c
*
* Inhalt:
*
*      --- Globale Routinen ---
*
*    int CloseHelpOnScreen ( void );
*    void HandleHelp ( enum RSysNumbers Link );
*    void Help ( void );
*    void OpenHelpOnScreen ( int openit );
*    void ShowStatus ( void );
*
*      --- Lokale  Routinen ---
*
*    static void DisplayError ( LONG err1 , LONG err2 );
*    static void HandleAmigaGuide ( void );
*    static void HandleFirstAmigaGuideMsg ( void );
*    static void InitAsyncAGuide ( void );
*    static void RemoveAsyncAGuide ( void );
*    static void WaitForAGuideActivated ( void );
*    static void WaitForAGuideCmdReady ( void );
*
* Bemerkungen:
*	  Prozeduren zur Verwaltung der Hilfefunktion von RSys.
*
* Erstellungsdatum:
*	  07-Jul-93 	Rolf Böhme
*
* Änderungen:
*	  07-Jul-93 	Rolf Böhme	  Erstellung
*
***************************************************************************
*/

#include "RSys.h"

/* RSysHelp.c (statische Prototypen) */
static void RemoveAsyncAGuide ( void );
static void HandleAmigaGuide ( void );
static void DisplayError ( LONG err1, LONG err2 );
static void WaitForAGuideCmdReady ( void );
static void WaitForAGuideActivated ( void );
static void HandleFirstAmigaGuideMsg ( void );
static void InitAsyncAGuide ( void );

static struct NewAmigaGuide *nag = NULL;
static AMIGAGUIDECONTEXT AmigaGuide_context = NULL;

static struct Screen *lasthelpscreen;

static TEXT PortName[]= (STRPTR) NAME "-AGuide-Port";
static TEXT BaseName[]= (STRPTR) NAME "Guide";


/********************************************************************
 *                                                                  *
 *    ******************** AGuide entfernen ********************    *
 *                                                                  *
 ********************************************************************/

static void
RemoveAsyncAGuide(void)
{
   Flags.helpmode = 0;

   PrintInfo("Close AGuide document...", SPEAK, 0);

   if (AmigaGuide_context)
   {
      HandleAmigaGuide();

      ExpungeDataBases((BOOL)TRUE);

      CloseAmigaGuide(AmigaGuide_context);

      AmigaGuide_context = NULL;
   }

   MyFreeVec(nag);

   if(AmigaGuideBase) CloseLibrary((struct Library *) AmigaGuideBase);

   return;
}



/********************************************************************
 *                                                                  *
 *   ******************** AGuide verarbeiten ********************   *
 *                                                                  *
 ********************************************************************/

static void
DisplayError(LONG err1, LONG err2)
{
   UBYTE *errstr1 = GetAmigaGuideString(err1), *errstr2 = GetAmigaGuideString(err2);

   MyEasyRequest(SysWnd, (UBYTE *) NAME " - AmigaGuide error message",
                 (UBYTE *) "Continue",
                 (UBYTE *) "Primary Number  : %lD\n"
                           "Secondary Error : %s (Nr.: %lD)",
                 err1, errstr2, err2);

   return;
}

static void
HandleAmigaGuide(void)
{
   struct AmigaGuideMsg *agm;

   while (agm = GetAmigaGuideMsg(AmigaGuide_context))
   {
      if (agm->agm_Pri_Ret || agm->agm_Sec_Ret) DisplayError(agm->agm_Pri_Ret, agm->agm_Sec_Ret);

      ReplyAmigaGuideMsg(agm);
   }

   return;
}

static void
WaitForAGuideCmdReady(void)
{
   struct AmigaGuideMsg *agm;
   BYTE out = FALSE;

   do
   {
      while (agm = GetAmigaGuideMsg(AmigaGuide_context))
      {
         if(agm->agm_Type == ToolCmdReplyID) out = TRUE;

         if (agm->agm_Pri_Ret || agm->agm_Sec_Ret)
            DisplayError(agm->agm_Pri_Ret, agm->agm_Sec_Ret);

         ReplyAmigaGuideMsg(agm);
      }
   } while(!out);

   return;
}

static void
WaitForAGuideActivated(void)
{
   struct AmigaGuideMsg *agm;
   BYTE out = FALSE;

   do
   {
      while (agm = GetAmigaGuideMsg(AmigaGuide_context))
      {
         if(agm->agm_Type == ActiveToolID) out = TRUE;

         if (agm->agm_Pri_Ret || agm->agm_Sec_Ret)
            DisplayError(agm->agm_Pri_Ret, agm->agm_Sec_Ret);

         ReplyAmigaGuideMsg(agm);
      }
   } while(!out);

   return;
}

   /*
    * HandleFirstAmigaGuideMsg() wartet auf eine AGuide-Nachricht
    * vom Typ ActiveToolID. Ist diese Nachricht angekommen, kann
    * sofort mit entsprechenden Aktionen begonnen werden.
    * Hier wird sofort das AGuide-Window mit dem Main-Node
    * geöffnet.
    */
static void
HandleFirstAmigaGuideMsg(void)
{
   WaitForAGuideActivated();

   if(SetAmigaGuideContext(AmigaGuide_context, (long)MAIN_HELP, NULL))
      SendAmigaGuideContext(AmigaGuide_context, NULL);

   if(SysWnd)
   {
      WaitForAGuideCmdReady();

      WaitTOF();

      WindowToFront(SysWnd);

      lasthelpscreen = SysWnd->WScreen;
   }

   return;
}

void
HandleHelp(enum RSysNumbers Link)
{
   if (!Flags.helpmode) return;

   HandleAmigaGuide();

   if (Link >= 0)
   {
      if(SetAmigaGuideContext(AmigaGuide_context, (long)Link, NULL))
         SendAmigaGuideContext(AmigaGuide_context, NULL);
   }

   HandleAmigaGuide();

   return;
}



/********************************************************************
 *                                                                  *
 *  ******************** AGuide installieren ********************   *
 *                                                                  *
 ********************************************************************/

static void
InitAsyncAGuide(void)
{
   if (AmigaGuideBase = (struct AmigaGuideBase *)
                        OpenLibrary((STRPTR) "amigaguide.library", 33))
   {
      Flags.helpmode = 1;

      PrintInfo("Please wait! Loading AGuide document...", SPEAK, 0);

      nag = MyAllocVec(sizeof(struct NewAmigaGuide), MEMF_PUBLIC | MEMF_CLEAR, NO_KILL);
      if(nag)
      {
         nag->nag_Lock        = NULL;
         nag->nag_Name        = RSysFiles.Guide;
         nag->nag_PubScreen   = namebuffer;
         nag->nag_ClientPort  = PortName;
         nag->nag_BaseName    = BaseName;
         nag->nag_Flags       = HTF_NOACTIVATE;
         nag->nag_Context     = context;
         nag->nag_Client      = NULL;

         if (AmigaGuide_context = OpenAmigaGuideAsync(nag, NULL))
         {
            SetAmigaGuideContext(AmigaGuide_context, 0L, NULL);
            HandleFirstAmigaGuideMsg();
         }
      }
      else
      {
         RemoveAsyncAGuide();
         ErrorHandle("Alloc NewAmigaGuide", MEMORY_ERR, ALLOC_FAIL, NO_KILL);
      }
   }

   return;
}


/********************************************************************
 *                                                                  *
 *     ******************** AGuide Support ********************     *
 *                                                                  *
 ********************************************************************/

void
Help(void)
{
   DisableSysRequest(TRUE);

   if (!Flags.helpmode)
   {
      OffMenu(SysWnd,FULLMENUNUM(7,3,0));

      InitAsyncAGuide();

         /*
          * Iconify() und erneutes Laden der Nodes verbieten
          */
      if(AmigaGuide_context) OffMenu(SysWnd,FULLMENUNUM(0,0,0));
      else
         OnMenu(SysWnd,FULLMENUNUM(7,3,0));
   }
   else
   {
      RemoveAsyncAGuide();

         /*
          * Iconify() und erneutes Laden der Nodes zulassen
          */
      OnMenu(SysWnd,FULLMENUNUM(0,0,0));
      OnMenu(SysWnd,FULLMENUNUM(7,3,0));
   }

   DisableSysRequest(FALSE);

   PrintStatistics();

   return;
}

int
CloseHelpOnScreen(void)
{
   if(Flags.helpmode && (Scr != lasthelpscreen))
   {
      Help();

      Flags.helpmode = 1;

      return TRUE;
   }

   return FALSE;
}

void
OpenHelpOnScreen(int openit)
{
   if(openit)
   {
      Flags.helpmode = 0;

      Help();

      HandleHelp(GD_JumpGad);
   }

   return;
}


void
ShowStatus(void)
{
   extern long maxentries;
   extern int newlvh;
   long cnt = 0;
   struct Node *node;
   char *onoff[]= { "OFF", "ON" };

   HandleHelp(MN_ShowStatus);

   for(node = Libraries.lh_Head; node->ln_Succ; node = node->ln_Succ)
      cnt += CountNodes(&(((LIBRARY *)node)->l_functions));

   MyEasyRequest(SysWnd, (UBYTE *) NAME " - Status information",
                 (UBYTE *) "Ok",
                 (UBYTE *) "--- Flags ---\n"
                 "Fast mode  : %3s  Sorting       : %3s  Work bar     : %3s\n"
                 "Speaking   : %3s  Auto front    : %3s  Mouse window : %3s\n"
                 "Topaz font : %3s  Save asking   : %3s  App Icon     : %3s\n"
                 "WB Start   : %3s\n"
                 "\n--- Memory ---\n"
                 "Current entries : %5lD  Max entries    : %5lD\n"
                 "Hardware types  : %5lD  Context nodes  : %5lD\n"
                 "Library nodes   : %5lD  Function nodes : %5lD\n"
                 "Listviewheight  : %5lD\n"
                 "\n--- Files ---\n"
                 "Hardware data       : %s (%s)\n"
                 "Library offset data : %s (%s)\n"
                 "Guide file          : %s (%s)\n"
                 "Guide context       : %s (%s)\n"
                 "Action file         : %s (%s)\n",
                 onoff[Flags.fastmode], onoff[Flags.sortmode],
                 onoff[Flags.workingbar], onoff[Flags.speakmode],
                 onoff[Flags.autofront], onoff[Flags.mousewindow],
                 onoff[Flags.sysfont], onoff[Flags.saveasking],
                 onoff[Flags.appicon], onoff[Flags.wb_start],
                 countentries, maxentries, CNT_DEVELOPER,
                 sizeof(context)/sizeof(char *), CountNodes(&Libraries), cnt,
                 newlvh,
                 RSysFiles.Hardware, (Flags.dummy1 ? "loaded" : "unload"),
                 RSysFiles.LibOffsets, (Flags.dummy2 ? "loaded" : "unload"),
                 RSysFiles.Guide, (Flags.dummy3 ? "loaded" : "unload"),
                 RSysFiles.GuideContext, (Flags.dummy3 ? "loaded" : "unload"),
                 RSysFiles.ActionFile, (Actions ? "loaded" : "unload"));

   return;
}

