/**
 * Scout - The Amiga System Monitor
 *
 *------------------------------------------------------------------
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * You must not use this source code to gain profit of any kind!
 *
 *------------------------------------------------------------------
 *
 * @author Andreas Gelhausen
 * @author Richard Körber <rkoerber@gmx.de>
 */



#include "system_headers.h"

extern struct GfxBase   *GfxBase;
extern struct ExecBase  *SysBase;
extern APTR AboutText;

UBYTE  updatetimetext[] = "1.0\0\0\0\0\0";
ULONG  updatetimestate;

ULONG MakeListID (char a, char b, char c, char d) {

   if (opts.SingleWindows) {
      return ((ULONG) ('L')<<24 | (ULONG) ('I')<<16 | (ULONG) ('S')<<8 | (ULONG) ('T'));
   } else {
      return ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d));
   }
}

ULONG MakeDetailID (char a, char b, char c, char d) {

//   if (opts.SingleWindows) {
//      return ((ULONG) ('M')<<24 | (ULONG) ('O')<<16 | (ULONG) ('R')<<8 | (ULONG) ('E'));
//   } else {
      return ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d));
//   }
}

struct Node *HandleNodeDetails (APTR list, char *type) {
   struct ListEntry  *entryp;
   struct Node       *node = NULL;

   if (entryp = GetActiveEntry (list)) {
      node = MyFindName (type, entryp->le_address);
      if (!node)
         MyRequest ("Continue", "Sorry, can't find that %s!", type);
   }
   return (node);
}

void MySetContents (APTR textfield, char *fmt, ...) {
   va_list arg;
   char buf[512];

   va_start(arg,fmt);
   RawDoFmt(fmt, arg, (void (*)())"\x16\xc0\x4e\x75", buf);
   va_end(arg);

   set (textfield, MUIA_Text_Contents, buf);
}

void MySetContentsHealed (APTR textfield, char *fmt, ...) {
   va_list arg;
   char buf[512];

   va_start(arg,fmt);
   RawDoFmt(fmt, arg, (void (*)())"\x16\xc0\x4e\x75", buf);
   va_end(arg);

   healstring (buf);
   set (textfield, MUIA_Text_Contents, buf);
}

void MyFreePoolStructs (APTR *pool, APTR listtext1, APTR listtext2, APTR list)
{
    if (*pool) {
        if (AP_Scout) {
            if (listtext1) set (listtext1, MUIA_Text_Contents, "");
            if (listtext2) set (listtext2, MUIA_Text_Contents, "");
            if (list) DoMethod (list, MUIM_List_Clear);
        }
        tbDeletePool(*pool);
        *pool = NULL;
    }
}

void SetCountText (APTR counttext, int structcnt) {
   MySetContents (counttext, ESC "r%04ld", structcnt);
}

void SetCloseRequest (APTR window, int id) {
   DoMethod (window,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,AP_Scout,2,MUIM_Application_ReturnID,id);
}

struct WinFree *SingleDetailWinFree = NULL;

char *MyGetWindowTitle (char *titleptr, char *type) {
   int ok, i;

   if (type[0] == '\0') {
      strcpy (tmpstr, "SCOUT");
   } else {
      _sprintf (tmpstr, "SCOUT: %s", type);
   }
   Forbid();
   ok = (FindPort ("AMITCP") != NULL);
   Permit();
   if (ok) {
      if (opts.Host) {
         strcat (tmpstr, "   [ ");
         strcat (tmpstr, opts.Host);
         strcat (tmpstr, " ]");
      } else {
         strcat (tmpstr, "   [ LOCALHOST ]");
      }
   }

   for (i = 7; i < strlen (tmpstr); i++) {
      tmpstr[i] = toupper (tmpstr[i]);
   }
   strcpy (titleptr, tmpstr);
   return (titleptr);
}

void HandleFlagsButtonPressed (APTR button, struct WinFree *ptr, char *title2, char *fieldname, ULONG flags, struct LongFlag *longflag, struct MaskedLongFlag *mlongflag, char fieldtype) {
   struct WinFlag *winflag;

   if (!ptr->wf_Pool) ptr->wf_Pool = tbCreatePool(MEMF_CLEAR, 4096, 4096);

   if (winflag = tbAllocPooled(ptr->wf_Pool, sizeof(struct WinFlag))) {
      winflag->wf_title2 = title2;
      winflag->wf_fieldname = fieldname;
      winflag->wf_flags = flags;
      winflag->wf_longflag = longflag;
      winflag->wf_mlongflag = mlongflag;
      winflag->wf_fieldtype = fieldtype;
      DoMethod (button,MUIM_Notify,MUIA_Pressed,FALSE,AP_Scout,3,MUIM_WriteLong,(ULONG) winflag,(ULONG *) &WinFlag_ToDo);
   }
}

void HandleWindowOpen (struct WinFree *ptr, char *titlepart1, char *titlepart2) {
   UBYTE *fulltitle;
   UBYTE *titlepart2ptr;

   if (opts.SingleWindows && SingleDetailWinFree) {
      WinFree_ToDo = SingleDetailWinFree;
      RemoveWinFree ();
   }
   SingleDetailWinFree = ptr;
   titlepart2ptr = nonetest (titlepart2);

   if (!ptr->wf_Pool) ptr->wf_Pool = tbCreatePool(MEMF_CLEAR, 4096, 4096);
   fulltitle = tbAllocPooled(ptr->wf_Pool, strlen(titlepart1) + strlen(titlepart2ptr) + 4);
   _sprintf (fulltitle, "%s%s", titlepart1, titlepart2ptr);
   healstring (fulltitle);

   set (ptr->wf_Window,MUIA_Window_Title,fulltitle);
   DoMethod (AP_Scout,OM_ADDMEMBER,ptr->wf_Window);
   SetWindowOpen (ptr->wf_Window,ptr->wf_ActiveObject,FALSE);
}

void HandleWindowClose (struct WinFree *ptr) {
   DoMethod (ptr->wf_Window,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,AP_Scout,3,MUIM_WriteLong,(ULONG) ptr,(ULONG *) &WinFree_ToDo);
   SetCloseRequest (ptr->wf_Window,ID_REMOVEWINFREE);
}

ULONG LastListID = 0;

void SetWindowOpen (APTR window, APTR active, ULONG ListID) {
   if (opts.SingleWindows) {
      if (ListID) {
         if (LastListID && (LastListID != ListID)) {
            if (SingleDetailWinFree) {
               WinFree_ToDo = SingleDetailWinFree;
               RemoveWinFree ();
            }
          DoMethod (AP_Scout,MUIM_Application_ReturnID,LastListID);
         }
         LastListID = ListID;
      }
   }

   set (window,MUIA_Window_Open,TRUE);
   if (active) set(window, MUIA_Window_ActiveObject, active);
}

void SetWindowClose (APTR window, BOOL IsList) {
   if (opts.SingleWindows && IsList) {
      if (SingleDetailWinFree) {
         WinFree_ToDo = SingleDetailWinFree;
         RemoveWinFree ();
      }
   }
   set (window,MUIA_Window_Open,FALSE);
}

void ApplicationSleep (void) {
   set (AP_Scout,MUIA_Application_Sleep,TRUE);
}

void AwakeApplication (void) {
   set (AP_Scout,MUIA_Application_Sleep,FALSE);
}

void RedrawActiveEntry (APTR list) {
   DoMethod (list, MUIM_List_Redraw, MUIV_List_Redraw_Active);
}

void RemoveActiveEntry (APTR list) {
   DoMethod (list, MUIM_List_Remove, MUIV_List_Redraw_Active);
}

void InsertBottomEntry (APTR list, APTR *entry) {
   DoMethod (list, MUIM_List_Insert, entry, 1, MUIV_List_Insert_Bottom);
}

void InsertSortedEntry (APTR list, APTR *entry) {
   DoMethod (list, MUIM_List_Insert, entry, 1, MUIV_List_Insert_Sorted);
}

struct ListEntry *GetActiveEntry (APTR list) {
   struct ListEntry *result = NULL;
   
   if (list)
      DoMethod (list,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&result);
   return (result);
}

void SetListActive (APTR list, int id) {
   DoMethod (list,MUIM_Notify,MUIA_List_Active,MUIV_EveryTime,AP_Scout,2,MUIM_Application_ReturnID,id);
}

void SetListviewDoubleClick (APTR list, int id) {
   if (! clientstate)
      DoMethod (list,MUIM_Notify,MUIA_Listview_DoubleClick,TRUE,AP_Scout,2,MUIM_Application_ReturnID,id);
}

APTR KeyButtonA (char *buttontext, int buttonid) {
   APTR result;
   result = MUI_MakeObject (MUIO_Button, buttontext, MUIA_CycleChain, TRUE);
   DoMethod (result,MUIM_Notify,MUIA_Pressed,FALSE,AP_Scout,2,MUIM_Application_ReturnID,buttonid);
   return (result);
}

APTR KeyButtonB (char *buttontext, char key, int buttonid) {
   APTR result;
   result = KeyButton (buttontext, key);
   set(result, MUIA_CycleChain, TRUE);
   DoMethod (result,MUIM_Notify,MUIA_Pressed,FALSE,AP_Scout,2,MUIM_Application_ReturnID,buttonid);
   return (result);
}

APTR KeyButtonF (char fieldtype, ULONG flags) {
   APTR result;
   char buttontext[16];

   if (fieldtype == 'l') {
      _sprintf (buttontext, ESC "b$%08lx", (ULONG) flags);
   } else if (fieldtype == 'w') {
      _sprintf (buttontext, ESC "b$%04lx", (UWORD) flags);
   } else {
      _sprintf (buttontext, ESC "b%%%s", ltob ((ULONG) flags, 8));
   }
   result = TextObject,\
                ButtonFrame,\
                      MUIA_Text_Contents, buttontext,\
                MUIA_Text_PreParse, "\33r",\
                MUIA_InputMode    , MUIV_InputMode_RelVerify,\
                MUIA_Background   , MUII_ButtonBack,\
                MUIA_CycleChain   , TRUE, \
                End;

   DoMethod (result,MUIM_Notify,MUIA_Pressed,FALSE,AP_Scout,2,MUIM_Application_ReturnID,ID_FLAGWINDOW);
   return (result);
}

__asm __saveds LONG flaglist_dspfunc(register __a2 char **array, register __a1 struct FlagEntry *flagentry, register __a0 struct Hook *hook)
{
   if (flagentry) {
      *array++ = flagentry->fe_name;
      *array++ = flagentry->fe_text;
      *array   = NULL;
   }
   return(0);
}

struct Hook flaglist_dsphook = {
 {NULL, NULL},
 (ULONG (* )())flaglist_dspfunc,
 NULL, NULL
};

void GetFlagsMore (char *title2, char *fieldname, ULONG flags, struct LongFlag *longflag, struct MaskedLongFlag *mlongflag, char fieldtype) {
   unsigned char     flaglabel[40];
   struct   WinFree  *ptr;
   APTR  flagsmorelist;


   if (fieldtype == 'l') {
      _sprintf ((char *) &flaglabel, "%ls = $%08lx", fieldname, flags);
   } else if (fieldtype == 'w') {
      _sprintf ((char *) &flaglabel, "%ls = $%04lx", fieldname, flags);
   } else {
      _sprintf ((char *) &flaglabel, "%ls = %%%s", fieldname, ltob ((ULONG) flags, 8));
   }

   if (ptr = AllocWinFree()) {
      ptr->wf_Window = (APTR) WindowObject,

//      MUIA_Window_SizeGadget, FALSE,
      MUIA_Window_ID, MakeDetailID('F','L','A','G'),
      WindowContents, VGroup,
         Child, HGroup,
            Child, MyHSpace (0),
            Child, MyLabel2 (flaglabel),
            Child, MyHSpace (0),
         End,
         Child, flagsmorelist = ListviewObject,
            MUIA_Listview_DoubleClick, TRUE,
            MUIA_Listview_Input, FALSE,
            MUIA_Listview_List, ListObject,
            MUIA_List_Format, "COL=0 DELTA=8,COL=1",
//            MUIA_List_Title, TRUE,
            MUIA_List_DisplayHook, &flaglist_dsphook,
            ReadListFrame,
            End,
         MUIA_CycleChain, TRUE,
         End,
      End, End;

      if (ptr->wf_Window) {
         int i = 0;

         set(flagsmorelist,MUIA_List_Quiet,TRUE);
         if (longflag) {
            while (((struct LongFlag *) &longflag[i])->lf_name) {
               if (flags & ((struct LongFlag *) &longflag[i])->lf_value) {
                  DoMethod (flagsmorelist,MUIM_List_InsertSingle,((struct FlagEntry *) &((struct LongFlag *) &longflag[i])->lf_name),MUIV_List_Insert_Bottom);
               }
               i++;
            }
         }
         i = 0;
         if (mlongflag) {
            while (((struct MaskedLongFlag *) &mlongflag[i])->mlf_name) {
               if ((flags & ((struct MaskedLongFlag *) &mlongflag[i])->mlf_mask) == ((struct MaskedLongFlag *) &mlongflag[i])->mlf_value) {
                  DoMethod (flagsmorelist,MUIM_List_InsertSingle,((struct FlagEntry *) &((struct MaskedLongFlag *) &mlongflag[i])->mlf_name),MUIV_List_Insert_Bottom);
               }
               i++;
            }
         }
         set(flagsmorelist,MUIA_List_Quiet,FALSE);

         HandleWindowOpen (ptr, "FLAGS  ", title2);
         set (ptr->wf_Window,MUIA_Window_ActiveObject,flagsmorelist);
         HandleWindowClose (ptr);
      }
   }
}

APTR MyListviewObject (unsigned char *formatstring, APTR displayhook ) {
   return (ListviewObject,
            MUIA_Listview_List, ListObject,
            MUIA_List_Format, formatstring,
            MUIA_List_Title, TRUE,
            MUIA_List_DisplayHook, displayhook,
            InputListFrame,
           End,
           MUIA_CycleChain, TRUE,
           End);
}

APTR MySortedListviewObject (unsigned char *formatstring, APTR displayhook, APTR comparehook) {
   return (ListviewObject,
            MUIA_Listview_List, ListObject,
            MUIA_List_Format, formatstring,
            MUIA_List_Title, TRUE,
            MUIA_List_DisplayHook, displayhook,
            MUIA_List_CompareHook, comparehook,
            InputListFrame,
           End,
           MUIA_CycleChain, TRUE,
           End);
}

/*
APTR MyBelowSortedListview (APTR *text, APTR *count, APTR *cycle, const char *sorttext[], int sortstate) {
 return (HGroup,
            Child, VGroup,
               Child, *text = MyTextObject5(SPACE40),
                  Child, MyLabel ("sorted by:"),
               End,
               Child, VGroup, MUIA_HorizWeight, 0,
                  Child, HGroup,
                     Child, MyLabel (" Cnt:"),
                     Child, *count = MyTextObject4("0000"),
                  End,
                  Child, *cycle = CycleObject,
                     MUIA_Cycle_Entries, sorttext,
                     MUIA_Cycle_Active, sortstate,
                  End,
               End,
            End);
}
*/

APTR MyBelowSortedListview (APTR *text, APTR *count, APTR *cycle, const char *sorttext[], int sortstate) {
 return (HGroup,
            Child, *text = MyTextObject5(SPACE40),
            Child, HGroup, MUIA_HorizWeight, 0,
               Child, MyLabel (" Cnt:"),
               Child, *count = MyTextObject4("0000"),
               Child, MyLabel ("sorted by:"),
               Child, *cycle = CycleObject,
                  MUIA_Cycle_Entries, sorttext,
                  MUIA_Cycle_Active, sortstate,
               End,
            End,
         End);
}

APTR MyBelowListview (APTR *text, APTR *count) {
 return (HGroup,
         Child, *text = MyTextObject5(SPACE40),
         Child, HGroup, MUIA_HorizWeight, 0,
            Child, MyLabel (" Cnt:"),
            Child, *count = MyTextObject4("0000"),
         End,End);
}

APTR MyLabel (char *labeltext) {
   return (LabelA (labeltext));
}

APTR MyLabel2 (char *labeltext) {
   return (LabelB (labeltext));
}

APTR MyHSpace (int size) {
   return (HSpace (size));
}

APTR MyVSpace (int size) {
   return (VSpace (size));
}

APTR MyTextObject () {
   return ( TextObject, MyTextFrame, End );
}

APTR MyTextObject2 () {
   return ( TextObject, MyTextFrame, MUIA_Text_SetMax, TRUE, End );
}

APTR MyTextObject3 (char *text) {
   return ( TextObject, MyTextFrame, MUIA_Text_Contents, text, End );
}

APTR MyTextObject4 (char *text) {
   return ( TextObject, MyTextFrame, MUIA_Text_SetMax, TRUE, MUIA_Text_Contents, text, End );
}

APTR MyTextObject5 (char *text) {
   return ( TextObject, MyTextFrame, MUIA_Text_SetMin, TRUE, MUIA_Text_Contents, text, End );
}

APTR MyTextObject6 (char *text, struct TextFont *font) {
   return ( TextObject, MyTextFrame, MUIA_Text_SetMin, TRUE, MUIA_Text_Contents, text, MUIA_Font, font, End );
}

__asm __saveds LONG list_cmpaddressfunc (register __a1 struct ListEntry *le1, register __a2 struct ListEntry *le2) {
   return (strcmpi (le1->le_address, le2->le_address));
}

struct Hook list_cmpaddresshook = {
 {NULL, NULL},
 (ULONG (* )())list_cmpaddressfunc,
 NULL, NULL
};

__asm __saveds LONG list_cmpnormalfunc (register __a1 struct ListEntry *le1, register __a2 struct ListEntry *le2)
{
   return (1);
}

struct Hook list_cmpnormalhook = {
 {NULL, NULL},
 (ULONG (* )())list_cmpnormalfunc,
 NULL, NULL
};

__asm __saveds LONG list_cmpnamefunc (register __a1 struct ListEntry *le1, register __a2 struct ListEntry *le2)
{
   return strcmpi (le1->le_name, le2->le_name);
}

struct Hook list_cmpnamehook = {
 {NULL, NULL},
 (ULONG (* )())list_cmpnamefunc,
 NULL, NULL
};

char main_title[WINDOWTITLELEN];

APTR GetApplication (void) {
   AP_Scout = ApplicationObject,
      MUIA_Application_Title      , PROGNAME,
      MUIA_Application_Version    , version_date,
      MUIA_Application_Copyright  , COPYRIGHT,
      MUIA_Application_Author     , AUTHOR,
      MUIA_Application_Description, DESCRIPTION,
      MUIA_Application_Base       , PROGNAME,
      MUIA_Application_Commands   , arexx_list,
      MUIA_Application_Menu       , menu_list,
//      MUIA_Application_SingleTask , TRUE,
      MUIA_Application_DiskObject , GetDiskObject("PROGDIR:Scout"),
      MUIA_Application_HelpFile   , "scout.guide",
   End;

   if (AP_Scout) {
      WI_Main = WindowObject,
      MUIA_Window_Title, MyGetWindowTitle (main_title, ""),
         MUIA_HelpNode, "Main",
         MUIA_Window_ID, MakeID('M','A','I','N'),
         WindowContents, HGroup,
            MUIA_Group_SameHeight, TRUE,
            Child, VGroup,                  /* This is the SCOUT logo */
               MUIA_Weight    , 0,
               MUIA_Frame     , MUIV_Frame_Text,
               MUIA_Background, MUII_SHADOW,
               Child, VSpace(0),
               Child, BodychunkObject,
                  MUIA_FixWidth             , SCOUT_LOGO_WIDTH ,
                  MUIA_FixHeight            , SCOUT_LOGO_HEIGHT,
                  MUIA_Bitmap_Width         , SCOUT_LOGO_WIDTH ,
                  MUIA_Bitmap_Height        , SCOUT_LOGO_HEIGHT,
                  MUIA_Bodychunk_Depth      , SCOUT_LOGO_DEPTH ,
                  MUIA_Bodychunk_Body       , scout_logo_body  ,
                  MUIA_Bodychunk_Compression, SCOUT_LOGO_COMPRESSION,
                  MUIA_Bodychunk_Masking    , SCOUT_LOGO_MASKING,
                  MUIA_Bitmap_SourceColors  , scout_logo_colors,
                  MUIA_Bitmap_Transparent   , 0,
               End,
               Child, VSpace(0),
            End,
            Child, ColGroup(5), MUIA_Group_SameSize, TRUE,             /* And this are the buttons */
               Child, BT_Allocations  = KeyButtonB (AllocationsText  ,'a',ID_ALLOCATIONS),  // 5
               Child, BT_Assigns      = KeyButtonB (AssignsText      ,'g',ID_ASSIGNS),      // 16
               Child, BT_Classes      = KeyButtonB (ClassesText      ,'b',ID_CLASSES),      // 14
               Child, BT_Commodities  = KeyButtonB (CommoditiesText  ,'k',ID_COMMODITIES),  // 8
               Child, BT_Devices      = KeyButtonB (DevicesText      ,'d',ID_DEVICES),      // 2

               Child, BT_Expansions   = KeyButtonB (ExpansionsText   ,'x',ID_EXPANSIONS),   // 22
               Child, BT_Fonts        = KeyButtonB (FontsText        ,'f',ID_FONTS),        // 13
               Child, BT_InputHandler = KeyButtonB (InputHandlersText,'h',ID_INPUTHANDLER), // 15
               Child, BT_Interrupts   = KeyButtonB (InterruptsText   ,'i',ID_INTERRUPTS),   // 9
               Child, BT_Libraries    = KeyButtonB (LibrariesText    ,'l',ID_LIBRARIES),    // 1

               Child, BT_Locks        = KeyButtonB (LocksText        ,'o',ID_LOCKS),        // 17
               Child, BT_LowMemory    = KeyButtonB (LowMemoryText    ,'j',ID_LOWMEMORY),    // 24
               Child, BT_Memory       = KeyButtonB (MemoryText       ,'m',ID_MEMORY),       // 23
               Child, BT_Mount        = KeyButtonB (MountText        ,'n',ID_MOUNT),        // 18
               Child, BT_Ports        = KeyButtonB (PortsText        ,'p',ID_PORTS),        // 7

               Child, BT_Residents    = KeyButtonB (ResidentsText    ,'r',ID_RESIDENTS),    // 25
               Child, BT_Commands     = KeyButtonB (CommandsText     ,'c',ID_COMMANDS),     // 19
               Child, BT_Resources    = KeyButtonB (ResourcesText    ,'u',ID_RESOURCES),    // 3
               Child, BT_ScreenMode   = KeyButtonB (ScreenModeText   ,'z',ID_SCREENMODE),   // 11
               Child, BT_Semaphores   = KeyButtonB (SemaphoresText   ,'s',ID_SEMAPHORES),   // 4

               Child, BT_System       = KeyButtonB (SystemText       ,'y',ID_SYSTEM),       // 21
               Child, BT_Tasks        = KeyButtonB (TasksText        ,'t',ID_TASKS),        // 6
               Child, BT_Timer        = KeyButtonB (TimerText        ,'e',ID_TIMER),        // 20
               Child, BT_Vectors      = KeyButtonB (VectorsText      ,'v',ID_VECTORS),      // 10
               Child, BT_Windows      = KeyButtonB (WindowsText      ,'w',ID_WINDOWS),      // 12
            End,
         End,
      End;

      if (WI_Main) {
         DoMethod (AP_Scout,OM_ADDMEMBER,WI_Main);
         SetCloseRequest (WI_Main,(int) MUIV_Application_ReturnID_Quit);
         DoMethod (WI_Main,MUIM_Window_SetCycleChain,
                    BT_Libraries,BT_Devices,BT_Resources,BT_System,
                    BT_Tasks,BT_Ports,BT_Commands,BT_Commodities,
                    BT_Expansions,BT_Memory,BT_Residents,BT_LowMemory,
                    BT_Assigns,BT_Locks,BT_Mount,BT_Timer,
                    BT_InputHandler,BT_Interrupts,BT_Vectors,BT_Allocations,
                    BT_Fonts,BT_Semaphores,BT_Windows,BT_ScreenMode,NULL);

//         DoMethod (AP_Scout,MUIM_Notify,MUIA_Application_DoubleStart,TRUE,AP_Scout,2,MUIM_Application_ReturnID,ID_DOUBLESTART);
      }
   }
   return (AP_Scout);
}

__asm __saveds void cpuinterval_callfunc(register __a1 unsigned char **contents) {
   int      i, j, t;
   long     micros = 0;
   UBYTE    text[8];

   if ((switchstate) && (*switchstate)) {
      AbortIO ((struct IORequest *) TimerIORequest);
   }

   strncpy (text, *contents, 6);

   i = 0;
   while ((text[i] != '\0') && (text[i] != '.')) {
      i++;
   }
   if (text[i] == '.') {
      t = 1;
      text[i] = '\0';
      while (isdigit (text[++i])) {
         if (j = (int) (text[i] - '0')) {
            t *= 10;
            micros += (1000000 / t) * j;
         }
      }
   }
   cpumicros = micros;
   cpuseconds = atol ((char const *) &text);
   strcpy (updatetimetext,*contents);

   if ((switchstate) && (*switchstate)) {
      TimerIORequest->tr_time.tv_secs = cpuseconds;
      TimerIORequest->tr_time.tv_micro = cpumicros;
      TimerIORequest->tr_node.io_Command = TR_ADDREQUEST;
      SendIO ((struct IORequest *) TimerIORequest);
   }
}

struct Hook cpuinterval_callhook = {
 {NULL, NULL},
 (ULONG (* )())cpuinterval_callfunc,
 NULL, NULL
};

/* Beispiel-EditHook aus RKM-Libraries Seite 164 */
/*
__asm __saveds ULONG realstring_editfunc(register __a0 struct Hook *hook, register __a2 struct SGWork *sgw, register __a1 ULONG *msg) {
   UBYTE *work_ptr;
   ULONG return_code;

   return_code = ~0L;

   if (*msg == SGH_KEY) {
      if ((sgw->EditOp == EO_REPLACECHAR) || (sgw->EditOp == EO_INSERTCHAR)) {
         if (!IsHexDigit (sgw->Code)) {
            sgw->Actions |= SGA_BEEP;
            sgw->Actions &= ~SGA_USE;
         } else {
            sgw->WorkBuffer[sgw->BufferPos - 1] = ToUpper (sgw->Code);
         }
      }
   } else if (*msg == SGH_CLICK) {
      if (sgw->BufferPos < sgw->NumChars) {
         work_ptr = sgw->WorkBuffer + sgw->BufferPos;
         *work_ptr = '0';
      }
   } else {
      return_code = 0;
   }
   return (return_code);
}
*/

__asm __saveds ULONG hexstring_editfunc (register __a0 struct Hook *hook, register __a2 struct SGWork *sgw, register __a1 ULONG *msg) {
   ULONG return_code;
   int   i = 0;
   char  c;

   return_code = ~0L;

   if (*msg == SGH_KEY) {
      long  tmplong;

      if ((sgw->EditOp == EO_REPLACECHAR) || (sgw->EditOp == EO_INSERTCHAR)) {
         if (sgw->WorkBuffer[0] == '$')
            i = 1;
         if (! strncmp ("0x", sgw->WorkBuffer, 2))
            i = 2;
         while (c = sgw->WorkBuffer[i]) {
            if ((! ((c >= '0') && (c <= '9'))) \
              && (! ((c >= 'a') && (c <= 'f'))) \
              && (! ((c >= 'A') && (c <= 'F')))) {
               sgw->Actions |= SGA_BEEP;
               sgw->Actions &= ~SGA_USE;
               break;
            }
            i++;
         }
      } else if ((sgw->EditOp == EO_ENTER) && (! IsHex (sgw->WorkBuffer, &tmplong))) { 
         sgw->Actions |= SGA_BEEP;
         sgw->Actions &= ~SGA_END;
      }
   } else {
      return_code = 0;
   }
   return (return_code);
}

struct Hook hexstring_edithook = {
 {NULL, NULL},
 (ULONG (* )())hexstring_editfunc,
 NULL, NULL
};

__asm __saveds ULONG realstring_editfunc(register __a0 struct Hook *hook, register __a2 struct SGWork *sgw, register __a1 ULONG *msg) {
   ULONG return_code;
   int   i = 0,punkte = 0,notzeros = 0;

   return_code = ~0L;

   if (*msg == SGH_KEY) {
      if ((sgw->EditOp == EO_REPLACECHAR) || (sgw->EditOp == EO_INSERTCHAR)) {
         while (sgw->WorkBuffer[i]) {
            if (sgw->WorkBuffer[i++] == '.')
               punkte++;
         }
         if ((punkte > 1) || ((!isdigit (sgw->Code)) && (sgw->Code != '.'))) {
            sgw->Actions |= SGA_BEEP;
            sgw->Actions &= ~SGA_USE;
         }
      } else if (sgw->EditOp == EO_ENTER) {
         while (sgw->WorkBuffer[i]) {
            if ((sgw->WorkBuffer[i] >= '1') && (sgw->WorkBuffer[i] <= '9'))
               notzeros++;
            i++;
         }
         if ((sgw->EditOp == EO_ENTER) && (!notzeros)) { 
            sgw->Actions |= SGA_BEEP;
            sgw->Actions &= ~SGA_END;
         }
      }
   } else {
      return_code = 0;
   }
   return (return_code);
}

struct Hook realstring_edithook = {
 {NULL, NULL},
 (ULONG (* )())realstring_editfunc,
 NULL, NULL
};

void AboutWindow (BOOL state) {
   if ((state) && (! WI_About)) {
      WI_About = WindowObject,
      MUIA_Window_Title, vers,
      WindowContents, VGroup,
         Child, AboutText= MyTextObject2(),
         Child, MyVSpace(4),
         Child, HGroup, MUIA_Group_SameSize, TRUE,
            Child, MyHSpace(0),
            Child, BT_AboutContinue = KeyButtonA (ContinueText,ID_ABOUTCONTINUE),
            Child, MyHSpace(0),
         End,
      End, End;

      if (WI_About) {
         MySetContents (AboutText, MUIX_C "\n" \
                                   "%s\n" \
                                   "%s\n" \
                                   "\n" \
                                   COPYRIGHT "\n" \
                                   "All Rights Reserved\n" \
                                   "\n" \
                                   "This program is \33bFreeware\33n.\n" \
                                   "EMail: " EMAIL "\n" \
                                   /* "URL: " URL "\n" \ */
                                   "\n" \
                                   "ARexx port name: %s\n", vstring, release, portname);

         DoMethod (AP_Scout,OM_ADDMEMBER,WI_About);
         SetCloseRequest (WI_About,ID_ABOUTCONTINUE);

         SetWindowOpen (WI_About,BT_AboutContinue,FALSE);
      }
   } else if ((! state) && (WI_About)) {
      SetWindowClose (WI_About,FALSE);

      DoMethod (AP_Scout,OM_REMMEMBER,WI_About);
      MUI_DisposeObject (WI_About);
      WI_About = NULL;
   }
}

