//
//  $Log: ui-MUI.c,v $
//  Revision 1.11  1994/09/10  23:01:47  hakan
//  Changed all button-notifies to FALSE.  They operate on releasing the
//  button now.
//
//  Revision 1.10  1994/09/10  14:32:32  hakan
//  ScanPing wurx
//
//  Revision 1.9  1994/08/15  22:46:42  hakan
//  Minor glitch.  Forgot a break.
//
//  Revision 1.8  1994/08/15  22:32:50  hakan
//  Should be finished.
//
//  Revision 1.7  1994/08/10  09:39:59  hakan
//  All scanning functions ready
//
//  Revision 1.6  1994/07/12  22:10:43  hakan
//  DecodeHost with accessory functions programmed
//
//  Revision 1.5  1994/07/12  21:01:30  hakan
//  Just another paranoia ci
//
//  Revision 1.4  1994/06/19  23:37:35  hakan
//  Intermediate ci.  Just getting paranoid :)
//  Lot's of UI and a HostRequest are functional
//
//  Revision 1.3  1994/06/19  15:34:06  hakan
//  Lotz'a stuff
//
//  Revision 1.2  1994/06/15  01:55:36  hakan
//  GUI faithfully copied from version 3.x
//
//  Revision 1.1  1994/06/14  20:30:25  hakan
//  Initial revision
//
//

static char* RCSId = "$Id: ui-MUI.c,v 1.11 1994/09/10 23:01:47 hakan Exp $";

#include "extern.h"
#include "ui-MUI.h"



static void HandleCheckBox (APTR CheckBox, APTR StringGadget);
static void BuildConfiguration (void);
static void DecodeHost (Host* foo);
static void Add (APTR list, char* string);



struct Library*         MUIMasterBase;
struct DiskObject*      icon;
char                    pathbuf [256];
char                    hostbuf [32 + 32 + 1];
static struct NewMenu   mnNetProbe[] =
{
    { NM_TITLE, "Project",          0,  0,  0,  0,},
    {  NM_ITEM, "About",           "?", 0,  0,  (void*) ID_About,},
    {  NM_ITEM, NM_BARLABEL,        0,  0,  0,  0,},
    {  NM_ITEM, "Save List",       "W", 0,  0,  (void*) ID_Save_List,},
    {  NM_ITEM, "Preferences...",  "P", 0,  0,  (void*) ID_Prefs,},
    {  NM_ITEM, NM_BARLABEL,        0,  0,  0,  0,},
    {  NM_ITEM, "Quit",            "Q", 0,  0,  (void*) ID_Quit,},

    {   NM_END, 0,                  0,  0,  0,  0,},
};

APTR    MUIApp;

APTR    MUIwinMain,
        MUIbtScanRealms,
        MUIbtScanHosts,
        MUIbtScanAllHosts,
        MUIbtQuit,
        MUIbtScanPing,
        MUIbtScanPingHost,
        MUIcbOwner,         MUIstOwner,
        MUIcbIPAddr,        MUIstIPAddr,
        MUIcbKickStart,     MUIstKickStart,
        MUIcbWorkBench,     MUIstWorkBench,
        MUIcbNIPC,          MUIstNIPC,
        MUIcbFastMem,       MUIstFastMem,
        MUIcbChipMem,       MUIstChipMem,
        MUIcbProcessor,     MUIstProcessor,
        MUIcbChips,         MUIstChips,
                            MUIlvRealms,
                            MUIlvHosts,
        MUIcbServices,      MUIlvServices,
        MUIcbEntities,      MUIlvEntities;

APTR    MUIwinPrefs,
        MUIstScanTime,
        MUIstScanPackets,
        MUIstSaveFileName,
        MUIstPingHost,
        MUIbt402Kludge,
        MUIbtPingHost,
        MUIbtPrefsPath,
        MUIbtPrefsSave,
        MUIbtPrefsUse,
        MUIbtPrefsCancel;

APTR    MUIwinScan,
        MUIfgScanTime,
        MUIbtStopScan;



BOOL CreateUI (int argc, char* argv[])
{
    long exportid = 1;


    if (!(MUIMasterBase = OpenLibrary ("muimaster.library", 3)))
    {
        return (FALSE);
    }


    //
    //  First,  we need an application
    //

    MUIApp = ApplicationObject,
        MUIA_Application_Title,         "NetProbe",
		MUIA_Application_Version,       getVersTag (),
        MUIA_Application_Copyright,     "©1993,1994, Hakan Tandogan",
        MUIA_Application_Author,        "Hakan Tandogan",
        MUIA_Application_Description,   "Scans an Envoy Network",
        MUIA_Application_Base,          "NETPROBE",
        MUIA_Application_Menu,          mnNetProbe,
        MUIA_Application_DiskObject,    icon = GetDiskObject ("NetProbe"),
        MUIA_HelpFile,                  "NetProbe.guide",

        End;

    if (!(MUIApp))
    {
        return (FALSE);
    }


    //
    //  Primary preferences items
    //

    MUIstScanTime = StringObject, StringFrame,
        MUIA_String_MaxLen,     5,
        MUIA_String_Format,     MUIV_String_Format_Left,
        MUIA_String_Accept,     "0123456789",
        MUIA_ExportID,          exportid++,
        End;

    MUIstScanPackets = StringObject, StringFrame,
        MUIA_String_MaxLen,     5,
        MUIA_String_Format,     MUIV_String_Format_Left,
        MUIA_String_Accept,     "0123456789",
        MUIA_ExportID,          exportid++,
        End;

    MUIstSaveFileName = StringObject, StringFrame,
        MUIA_String_Format,     MUIV_String_Format_Left,
        MUIA_ExportID,          exportid++,
        End;

    MUIstPingHost = StringObject, StringFrame,
        MUIA_String_Format,     MUIV_String_Format_Left,
        MUIA_ExportID,          exportid++,
        End;

    MUIbt402Kludge  = KeyCheckmark (TRUE, 'k', exportid++);
    MUIbtPingHost   = KeyCheckmark (TRUE, 's', exportid++);

    if (!(MUIstScanTime  && MUIstScanPackets && MUIstSaveFileName
       && MUIbt402Kludge && MUIbtPingHost    && MUIstPingHost))
    {
        return (FALSE);
    }


    //
    //  Now we create our main window
    //

    MUIwinMain = WindowObject,
        MUIA_Window_Title,  getWindowVersionString(), //  "NetProbe 4.3",
        MUIA_Window_ID,     MAKE_ID ('M','A','I','N'),

        WindowContents, VGroup,
            //
            //  Top three gadgets
            //
            Child, HGroup,
                MUIA_Group_SameSize, TRUE,
                Child, MUIbtScanRealms      = KeyButton ("Scan Realms", 'r'),
                Child, MUIbtScanHosts       = KeyButton ("Scan Hosts", 'h'),
                Child, MUIbtScanAllHosts    = KeyButton ("Scan All", 'a'),
                Child, MUIbtQuit            = KeyButton ("Quit", 'q'),
                End,

            //
            //  Ping-Host stuff
            //
            Child, HGroup,
                MUIA_Group_SameSize, TRUE,
                Child, MUIbtScanPing = KeyButton ("Ping Host", 'g'),
                Child, HGroup,
                    MUIA_Group_SameSize, FALSE,
                    Child, MUIstPingHost,
                    Child, MUIbtScanPingHost = PopupGadget,
                    End,
                End,

            //
            //  Here comes Information
            //
            Child, RectangleObject, MUIA_Rectangle_HBar, TRUE, MUIA_FixHeight, 8, End,

            Child, ColGroup (2),
                Child, HGroup,
                    Child, VGroup,
                        Child, MUIlvRealms = ListviewObject,
                            MUIA_Weight, 50,
                            MUIA_Listview_List, ListObject,
                                InputListFrame,
                                End,
                            End,

                        Child, MUIlvHosts = ListviewObject,
                            MUIA_Weight, 200,
                            MUIA_Listview_List, ListObject,
                                InputListFrame,
                                End,
                            End,

                        End,
                    End,

                    Child, VGroup,
                        ListViewWithKey (MUIcbServices, MUIlvServices,  exportid++, 's',    "Services"),
                        ListViewWithKey (MUIcbEntities, MUIlvEntities,  exportid++, 'e',    "Entities"),
                        End,
                    End,

                Child, RectangleObject, MUIA_Rectangle_HBar, TRUE, MUIA_FixHeight, 8, End,

                Child, ColGroup (3),
                    GadgetLine (MUIcbOwner,     MUIstOwner,     exportid++, 'o', "Owner:"),
                    GadgetLine (MUIcbIPAddr,    MUIstIPAddr,    exportid++, 'i', "IP-Addr"),
                    GadgetLine (MUIcbKickStart, MUIstKickStart, exportid++, 'k', "Kickstart:"),
                    GadgetLine (MUIcbWorkBench, MUIstWorkBench, exportid++, 'w', "Workbench:"),
                    GadgetLine (MUIcbNIPC,      MUIstNIPC,      exportid++, 'n', "NIPC:"),
                    GadgetLine (MUIcbFastMem,   MUIstFastMem,   exportid++, 'f', "Fast Memory:"),
                    GadgetLine (MUIcbChipMem,   MUIstChipMem,   exportid++, 'y', "Chip Memory:"),
                    GadgetLine (MUIcbProcessor, MUIstProcessor, exportid++, 'p', "Processor:"),
                    GadgetLine (MUIcbChips,     MUIstChips,     exportid++, 'c', "Custom Chips:"),
                End,
            End,
        End;

    if (!(MUIwinMain))
    {
        return (FALSE);
    }

    DoMethod (MUIwinMain,        MUIM_Notify, MUIA_Window_CloseRequest, TRUE,           MUIApp, 2, MUIM_Application_ReturnID, ID_Quit);
    DoMethod (MUIbtScanRealms,   MUIM_Notify, MUIA_Pressed,             FALSE,          MUIApp, 2, MUIM_Application_ReturnID, ID_Scan_Realms);
    DoMethod (MUIbtScanHosts,    MUIM_Notify, MUIA_Pressed,             FALSE,          MUIApp, 2, MUIM_Application_ReturnID, ID_Scan_Hosts);
    DoMethod (MUIbtScanAllHosts, MUIM_Notify, MUIA_Pressed,             FALSE,          MUIApp, 2, MUIM_Application_ReturnID, ID_Scan_All);
    DoMethod (MUIbtScanPing,     MUIM_Notify, MUIA_Pressed,             FALSE,          MUIApp, 2, MUIM_Application_ReturnID, ID_Scan_Ping);
    DoMethod (MUIbtQuit,         MUIM_Notify, MUIA_Pressed,             FALSE,          MUIApp, 2, MUIM_Application_ReturnID, ID_Quit);

    DoMethod (MUIbtScanPingHost, MUIM_Notify, MUIA_Pressed,             FALSE,          MUIApp, 2, MUIM_Application_ReturnID, ID_HostRequest);

    DoMethod (MUIlvHosts,        MUIM_Notify, MUIA_List_Active,         MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_LV_Hosts_Changed);
    DoMethod (MUIlvRealms,       MUIM_Notify, MUIA_List_Active,         MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_LV_Realms_Changed);
    DoMethod (MUIlvRealms,       MUIM_Notify, MUIA_Listview_DoubleClick, MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_Scan_Hosts);

    DoMethod (MUIcbEntities,     MUIM_Notify, MUIA_Selected,            MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_BT_Entities);
    DoMethod (MUIcbServices,     MUIM_Notify, MUIA_Selected,            MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_BT_Services);
    DoMethod (MUIcbOwner,        MUIM_Notify, MUIA_Selected,            MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_BT_Owner);
    DoMethod (MUIcbIPAddr,       MUIM_Notify, MUIA_Selected,            MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_BT_IPAddr);
    DoMethod (MUIcbKickStart,    MUIM_Notify, MUIA_Selected,            MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_BT_KickStart);
    DoMethod (MUIcbWorkBench,    MUIM_Notify, MUIA_Selected,            MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_BT_WorkBench);
    DoMethod (MUIcbNIPC,         MUIM_Notify, MUIA_Selected,            MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_BT_NIPC);
    DoMethod (MUIcbFastMem,      MUIM_Notify, MUIA_Selected,            MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_BT_FastMem);
    DoMethod (MUIcbChipMem,      MUIM_Notify, MUIA_Selected,            MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_BT_ChipMem);
    DoMethod (MUIcbProcessor,    MUIM_Notify, MUIA_Selected,            MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_BT_Processor);
    DoMethod (MUIcbChips,        MUIM_Notify, MUIA_Selected,            MUIV_EveryTime, MUIApp, 2, MUIM_Application_ReturnID, ID_BT_Chips);

    DoMethod (MUIwinMain, MUIM_Window_SetCycleChain,
        MUIbtScanRealms,
        MUIbtScanHosts,
        MUIbtScanAllHosts,
        MUIbtQuit,
        MUIbtScanPing,
        MUIstPingHost,
        MUIlvRealms,
        MUIlvHosts,
        NULL );

    DoMethod (MUIwinMain, MUIA_Window_ActiveObject, MUIbtScanHosts);

    DoMethod (MUIApp, OM_ADDMEMBER, MUIwinMain);


    //
    //  Here goes the preferences window
    //

    MUIwinPrefs = WindowObject,
        MUIA_Window_Title,  "NetProbe Preferences",
        MUIA_Window_ID,     MAKE_ID ('P','R','F','S'),

        WindowContents, VGroup,
            Child, ColGroup (2),
                Child, Label2 ("Max. Scan Time: "), Child, MUIstScanTime,
                Child, Label2 ("Max. Packets: "),   Child, MUIstScanPackets,
                Child, Label2 ("Save file Path: "), Child, HGroup,
                                                        Child, MUIstSaveFileName,
                                                        Child, MUIbtPrefsPath = PopupGadget,
                                                        End,

                Child, Label1 ("40.2-Kludge: "),    Child, HGroup,
                                                        Child, MUIbt402Kludge,
                                                        Child, HSpace (0),
                                                        End,
                Child, Label1 ("Ping Hosts: "),     Child, HGroup,
                                                        Child, MUIbtPingHost,
                                                        Child, HSpace (0),
                                                        End,
                End,

            Child, VSpace (0),

            Child, HGroup,
                MUIA_Group_SameSize, TRUE,

                Child, MUIbtPrefsSave   = KeyButton ("Save", 's'),
                Child, MUIbtPrefsUse    = KeyButton ("Use", 'u'),
                Child, MUIbtPrefsCancel = KeyButton ("Cancel", 'c'),
                End,

            End,

        End;

    if (!(MUIwinPrefs))
    {
        return (FALSE);
    }

    DoMethod (MUIwinPrefs,      MUIM_Notify, MUIA_Window_CloseRequest, TRUE,            MUIApp, 2, MUIM_Application_ReturnID, ID_Prefs_Quit);
    DoMethod (MUIbtPrefsPath,   MUIM_Notify, MUIA_Pressed,             FALSE,           MUIApp, 2, MUIM_Application_ReturnID, ID_Prefs_Path);
    DoMethod (MUIbtPrefsSave,   MUIM_Notify, MUIA_Pressed,             FALSE,           MUIApp, 2, MUIM_Application_ReturnID, ID_Prefs_Save);
    DoMethod (MUIbtPrefsUse,    MUIM_Notify, MUIA_Pressed,             FALSE,           MUIApp, 2, MUIM_Application_ReturnID, ID_Prefs_Use);
    DoMethod (MUIbtPrefsCancel, MUIM_Notify, MUIA_Pressed,             FALSE,           MUIApp, 2, MUIM_Application_ReturnID, ID_Prefs_Cancel);
    DoMethod (MUIbtPingHost,    MUIM_Notify, MUIA_Selected,            MUIV_EveryTime,  MUIApp, 2, MUIM_Application_ReturnID, ID_BT_PingHost);

    DoMethod (MUIwinPrefs, MUIM_Window_SetCycleChain,
        MUIstScanTime,
        MUIstScanPackets,
        MUIstSaveFileName,
        MUIbtPrefsPath,
        MUIbtPrefsSave,
        MUIbtPrefsUse,
        MUIbtPrefsCancel,
        NULL );

    DoMethod (MUIwinPrefs, MUIA_Window_ActiveObject, MUIbtPrefsUse);

    DoMethod (MUIApp, OM_ADDMEMBER, MUIwinPrefs);


    //
    //  This is the scanning window
    //

    MUIwinScan = WindowObject,
        MUIA_Window_Title,  "NetProbe Scanning",
        MUIA_Window_ID,     MAKE_ID ('S','C','A','N'),
        MUIA_Window_Menu,   MUIV_Window_Menu_NoMenu,

        WindowContents, VGroup,
            Child,
                ColGroup (3),
                    Child, HSpace (0),
                    Child, Label1 ("Scanning"),
                    Child, HSpace (0),
                End,

                Child, MUIfgScanTime = GaugeObject, GaugeFrame, MUIA_Gauge_Horiz, TRUE, End,

                Child, VSpace (0),
                
                Child, MUIbtStopScan = KeyButton ("Stop", 's'),
            End,
        End;

    if (!(MUIwinScan))
    {
        return (FALSE);
    }

    DoMethod (MUIbtStopScan, MUIM_Notify, MUIA_Pressed, FALSE, MUIApp, 2, MUIM_Application_ReturnID, ID_Stop_Scan);

    DoMethod (MUIwinScan, MUIM_Window_SetCycleChain,
        MUIbtStopScan,
        NULL );

    DoMethod (MUIwinScan, MUIA_Window_ActiveObject, MUIbtStopScan);

    DoMethod (MUIApp, OM_ADDMEMBER, MUIwinScan);


    //
    //  The application is set up,  so load our preferences
    //

    {
        char* foo;


        DoMethod (MUIApp, MUIM_Application_Load, "ENV:"PATH_PREFS);

        get (MUIstScanTime, MUIA_String_Contents, &foo);
        if ((*foo == 0) || (atol (foo) == 0))
        {
            set (MUIstScanTime, MUIA_String_Contents, "1");
        }

        get (MUIstScanPackets, MUIA_String_Contents, &foo);
        if ((*foo == 0) || (atol (foo) == 0))
        {
            set (MUIstScanPackets, MUIA_String_Contents, "10");
        }

        get (MUIstSaveFileName, MUIA_String_Contents, &foo);
        if (*foo == 0)
        {
            set (MUIstSaveFileName, MUIA_String_Contents, "NetProbe.list");
        }

        get (MUIstPingHost, MUIA_String_Contents, &foo);
        if (*foo == 0)
        {
            set (MUIstPingHost, MUIA_String_Contents, "kahalo:kahalo");
        }
    }


    //
    //  Hey,  we did it!
    //

    return (TRUE);
}



void DestroyUI (void)
{
    if (icon)
    {
        FreeDiskObject (icon);
        icon = NULL;
    }

    if (MUIApp)
    {
        MUI_DisposeObject (MUIApp);
        MUIApp = NULL;
    }

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



void EventLoop (void)
{
    ULONG   signals = 0;
    BOOL    running = TRUE;


    if (!(RealmServerRunning ()))
    {
        set (MUIbtScanRealms,   MUIA_Disabled, TRUE);
        set (MUIbtScanAllHosts, MUIA_Disabled, TRUE);
        set (MUIlvRealms,       MUIA_Disabled, TRUE);
    }

    set (MUIwinMain,  MUIA_Window_Open, TRUE);

    while (running)
    {
        switch (DoMethod (MUIApp, MUIM_Application_Input, &signals))
        {
            case MUIV_Application_ReturnID_Quit:
            case ID_Quit:
                running = FALSE;
                break;

            case ID_About:
                MUI_Request (MUIApp, MUIwinMain, 0, NULL, "*Excellent",
                    "\33c%s\n"
                    "\33c\n"
                    "\33c© 1993,1994 Hakan Tandogan\n"
                    "\33cFreely  distributable\n"
                    "\33c\n"
                    "\33cPlease note the cardware status of\n"
                    "\33cthis program.\n"
                    "\33c\n"
                    "\33cThis is a MUI-Application.\n"
                    "\33cMUI is copyrighted by Stefan Stuntz.",
                    getAboutVersionString ());
                break;

            case ID_Save_List:
                {
                    char* SaveFileName;

                    get (MUIstSaveFileName, MUIA_String_Contents, &SaveFileName);
                    SaveList (SaveFileName);
                }
                break;

                
            case ID_HostRequest:    
                {
                    LONG topedge;
                    LONG height;
                    LONG leftedge;
                    LONG width;

                    get (MUIwinMain, MUIA_Window_TopEdge,   &topedge);
                    get (MUIwinMain, MUIA_Window_Height,    &height);
                    get (MUIwinMain, MUIA_Window_LeftEdge,  &leftedge);
                    get (MUIwinMain, MUIA_Window_Width,     &width);

                    if (HostRequest (HREQ_Title,    "NetProbe Host Request",
                                     HREQ_Top,      topedge + height / 4,
                                     HREQ_Height,   height / 2,
                                     HREQ_Left,     leftedge,
                                     HREQ_Width,    width,
                                     HREQ_Buffer,   &hostbuf,
                                     HREQ_BuffSize, sizeof (hostbuf) - 1,
                                     (!(RealmServerRunning)) ? HREQ_NoRealms : TAG_DONE,    0,
                                     TAG_DONE))

                    {
                        set (MUIstPingHost, MUIA_String_Contents, &hostbuf);
                    }
                }
                break;

            case ID_Prefs:
                set (MUIwinPrefs, MUIA_Window_Open, TRUE);
                break;

            case ID_Prefs_Quit:
                set (MUIwinPrefs, MUIA_Window_Open, FALSE);
                break;

            case ID_Prefs_Path:
                {
                    LONG                    leftedge;
                    LONG                    topedge;
                    struct FileRequester*   FileRequester;
                    struct Window*          parent;


                    get (MUIwinPrefs, MUIA_Window_Window,   &parent);
                    get (MUIwinPrefs, MUIA_Window_LeftEdge, &leftedge);
                    get (MUIwinPrefs, MUIA_Window_TopEdge,  &topedge);

                    if (FileRequester = MUI_AllocAslRequestTags (ASL_FileRequest,
                                                                 ASLFR_Window,          parent,
                                                                 ASLFR_InitialLeftEdge, leftedge,
                                                                 ASLFR_InitialTopEdge,  topedge,
                                                                 ASLFR_TitleText,       "Select Save File",
                                                                 TAG_DONE))
                    {
                        set (MUIwinPrefs, MUIA_Window_Sleep, TRUE);

                        if (MUI_AslRequestTags ((APTR) FileRequester, TAG_DONE))
                        {
                            stccpy (pathbuf, FileRequester->fr_Drawer, sizeof (pathbuf));

                            AddPart (pathbuf, FileRequester->fr_File, sizeof (pathbuf));

                            set (MUIstSaveFileName, MUIA_String_Contents, pathbuf);
                        }

                        set (MUIwinPrefs, MUIA_Window_Sleep, FALSE);

                        MUI_FreeAslRequest (FileRequester);
                    }
                }
                break;

            case ID_Prefs_Save:
                DoMethod (MUIApp, MUIM_Application_Save, "ENVARC:" PATH_PREFS);
                DoMethod (MUIApp, MUIM_Application_Save, "ENV:"    PATH_PREFS);
                set (MUIwinPrefs, MUIA_Window_Open, FALSE);
                break;

            case ID_Prefs_Use:
                DoMethod (MUIApp, MUIM_Application_Save, "ENV:"    PATH_PREFS);
                set (MUIwinPrefs, MUIA_Window_Open, FALSE);
                break;

            case ID_Prefs_Cancel:
                set (MUIwinPrefs, MUIA_Window_Open, FALSE);
                break;

            case ID_BT_PingHost:
                {
                    long selected;

                    get (MUIbtPingHost, MUIA_Selected, &selected);
                    if (selected)
                    {
                        set (MUIbtScanPing, MUIA_Disabled, FALSE);
                        set (MUIstPingHost, MUIA_Disabled, FALSE);
                    }
                    else
                    {
                        set (MUIbtScanPing, MUIA_Disabled, TRUE);
                        set (MUIstPingHost, MUIA_Disabled, TRUE);
                    }
                }
                break;

            case ID_BT_Entities:
                HandleCheckBox (MUIcbEntities,  MUIlvEntities);
                break;

            case ID_BT_Services:
                HandleCheckBox (MUIcbServices,  MUIlvServices);
                break;

            case ID_BT_Owner:
                HandleCheckBox (MUIcbOwner,     MUIstOwner);
                break;

            case ID_BT_IPAddr:
                HandleCheckBox (MUIcbIPAddr,    MUIstIPAddr);
                break;

            case ID_BT_KickStart:
                HandleCheckBox (MUIcbKickStart, MUIstKickStart);
                break;

            case ID_BT_WorkBench:
                HandleCheckBox (MUIcbWorkBench, MUIstWorkBench);
                break;

            case ID_BT_NIPC:
                HandleCheckBox (MUIcbNIPC,      MUIstNIPC);
                break;

            case ID_BT_FastMem:
                HandleCheckBox (MUIcbFastMem,   MUIstFastMem);
                break;

            case ID_BT_ChipMem:
                HandleCheckBox (MUIcbChipMem,   MUIstChipMem);
                break;

            case ID_BT_Processor:
                HandleCheckBox (MUIcbProcessor, MUIstProcessor);
                break;

            case ID_BT_Chips:
                HandleCheckBox (MUIcbChips,     MUIstChips);
                break;
                
            case ID_Scan_Realms:
                {
                    struct Node*    realm;

                    DoMethod (MUIlvRealms, MUIM_List_Clear);
                    BuildConfiguration ();
                    ScanRealms ();

                    for (realm = Realms()->lh_Head; realm->ln_Succ; realm = realm->ln_Succ)
                    {
                        DoMethod (MUIlvRealms, MUIM_List_Insert, &(realm->ln_Name), 1, MUIV_List_Insert_Sorted);
                    }
                }
                break;

            case ID_Scan_Hosts:
                {
                    struct Node*    host;
                    struct List*    hosts;
                    unsigned long   selected;
                    APTR            realmname = NULL;


                    get (MUIlvRealms, MUIA_List_Entries, &selected);
                    if (selected > 0)
                    {
                        get (MUIlvRealms, MUIA_List_Active, &selected);
                        if (selected != MUIV_List_Active_Off)
                        {
                            DoMethod (MUIlvRealms, MUIM_List_GetEntry, selected, &realmname);
                        }
                    }
                    
                    DoMethod (MUIlvHosts, MUIM_List_Clear);
                    BuildConfiguration ();
                    ScanHosts (realmname);
                    
                    hosts = Hosts ();

                    for (host = hosts->lh_Head; host->ln_Succ; host = host->ln_Succ)
                    {
                        DoMethod (MUIlvHosts, MUIM_List_Insert, &(host->ln_Name), 1, MUIV_List_Insert_Sorted);
                    }

                    if (!(IsListEmpty (hosts)))
                    {
                        set (MUIlvHosts, MUIA_List_Active, 0);
                    }
                }
                break;

            case ID_Scan_Ping:
                {
                    struct Node*    host;
                    struct List*    hosts;
                    char*           pingee;

                    get (MUIstPingHost, MUIA_String_Contents, &pingee);

                    DoMethod (MUIlvHosts, MUIM_List_Clear);
                    BuildConfiguration ();

                    NP_Config |= NP_SingleHost;
                    NP_ScanHost = pingee;

                    ScanPing ();

                    hosts = Hosts ();

                    for (host = hosts->lh_Head; host->ln_Succ; host = host->ln_Succ)
                    {
                        DoMethod (MUIlvHosts, MUIM_List_Insert, &(host->ln_Name), 1, MUIV_List_Insert_Sorted);
                    }

                    if (!(IsListEmpty (hosts)))
                    {
                        set (MUIlvHosts, MUIA_List_Active, 0);
                    }
                }
                break;

            case ID_Scan_All:
                {
                    struct Node*    node;
                    struct List*    list;

                    DoMethod (MUIlvHosts, MUIM_List_Clear);
                    DoMethod (MUIlvRealms, MUIM_List_Clear);
                    BuildConfiguration ();
                    ScanAll ();

                    list = Realms ();

                    for (node = list->lh_Head; node->ln_Succ; node = node->ln_Succ)
                    {
                        DoMethod (MUIlvRealms, MUIM_List_Insert, &(node->ln_Name), 1, MUIV_List_Insert_Sorted);
                    }

                    list = Hosts ();

                    for (node = list->lh_Head; node->ln_Succ; node = node->ln_Succ)
                    {
                        DoMethod (MUIlvHosts, MUIM_List_Insert, &(node->ln_Name), 1, MUIV_List_Insert_Sorted);
                    }

                    if (!(IsListEmpty (list)))
                    {
                        set (MUIlvHosts, MUIA_List_Active, 0);
                    }
                }
                break;

            case ID_LV_Hosts_Changed:
                {
                    long selected;
                    APTR hostname;

                    get (MUIlvHosts, MUIA_List_Active, &selected);
                    DoMethod (MUIlvHosts, MUIM_List_GetEntry, selected, &hostname);

                    DecodeHost (getHost (hostname));
                }
                break;

            case ID_LV_Realms_Changed:
                break;

            default:
                break;
        }

        if (running && signals) Wait(signals);
    }

    set (MUIwinMain,  MUIA_Window_Open, FALSE);
    set (MUIwinPrefs, MUIA_Window_Open, FALSE);
    set (MUIwinScan,  MUIA_Window_Open, FALSE);
}



BOOL OpenScanWindow (long max)
{
    set (MUIfgScanTime, MUIA_Gauge_Max,   max);
    set (MUIbtStopScan, MUIA_Selected,    FALSE);
    set (MUIbtStopScan, MUIA_Pressed,     FALSE);
    set (MUIwinScan,    MUIA_Window_Open, TRUE);

    return (TRUE);
}



void CloseScanWindow (void)
{
    set (MUIwinScan,  MUIA_Window_Open, FALSE);
}



BOOL ShowScan (long current)
{
    long MuiSignals;
    long Received;
    long running = TRUE;
    BOOL stopped = FALSE;
    
    struct MsgPort* time = TimePort ();


    DoMethod (MUIApp, MUIM_Application_Input, &MuiSignals);

    set (MUIfgScanTime, MUIA_Gauge_Current, current);
    
    SendIO (TimeRequest ());

    while (running)
    {
        Received = Wait (MuiSignals | (1L << time->mp_SigBit));

        switch (DoMethod (MUIApp, MUIM_Application_Input, &MuiSignals))
        {
            case ID_Stop_Scan:
                running = FALSE;
                stopped = TRUE;
                break;

            default:
                break;
        }

        if (Received & (1L << time->mp_SigBit))
        {
            running = FALSE;
            while (GetMsg (time))
                ;
        }
    }
    
    return (stopped);
}



static void HandleCheckBox (APTR CheckBox, APTR StringGadget)
{
    long selected;

    get (CheckBox, MUIA_Selected, &selected);
    if (selected)
    {
        set (StringGadget, MUIA_Disabled, FALSE);
    }
    else
    {
        set (StringGadget, MUIA_Disabled, TRUE);
    }
}



static void BuildConfiguration (void)
{
    char*   foo;
    long    selected;


    //
    //  First,  we need our numerical data
    //
    get (MUIstScanTime,     MUIA_String_Contents, &foo);
    NP_ScanTime = atol (foo);

    get (MUIstScanPackets,  MUIA_String_Contents, &foo);
    NP_ScanPackets = atol (foo);

    get (MUIstPingHost,     MUIA_String_Contents, &foo);
    NP_ScanHost = foo;



    //
    //  Now,  let's have a look at those buttons
    //
    NP_Config = NP_HostName;

    get (MUIcbIPAddr, MUIA_Selected, &selected);
    if  (selected)
    {
        NP_Config |= NP_IPAddr;
    }


    get (MUIcbOwner, MUIA_Selected, &selected);
    if  (selected)
    {
        NP_Config |= NP_Owner;
    }

    get (MUIcbKickStart, MUIA_Selected, &selected);
    if  (selected)
    {
        NP_Config |= NP_KickVersion;
    }


    get (MUIcbWorkBench, MUIA_Selected, &selected);
    if  (selected)
    {
        NP_Config |= NP_WBVersion;
    }


    get (MUIcbNIPC, MUIA_Selected, &selected);
    if  (selected)
    {
        NP_Config |= NP_NIPCVersion;
    }


    get (MUIcbFastMem, MUIA_Selected, &selected);
    if  (selected)
    {
        NP_Config |= NP_MaxFastMem;
        NP_Config |= NP_AvailFastMem;
    }


    get (MUIcbChipMem, MUIA_Selected, &selected);
    if  (selected)
    {
        NP_Config |= NP_MaxChipMem;
        NP_Config |= NP_AvailChipMem;
    }


    get (MUIcbProcessor, MUIA_Selected, &selected);
    if  (selected)
    {
        NP_Config |= NP_ATTNFlags;
    }


    get (MUIcbChips, MUIA_Selected, &selected);
    if  (selected)
    {
        NP_Config |= NP_ChipRevBits;
    }


    get (MUIcbServices, MUIA_Selected, &selected);
    if  (selected)
    {
        NP_Config |= NP_Services;
    }


    get (MUIcbEntities, MUIA_Selected, &selected);
    if  (selected)
    {
        NP_Config |= NP_Entities;
    }


    get (MUIbt402Kludge, MUIA_Selected, &selected);
    if  (selected)
    {
        NP_Config |= NP_402_Kludge;
    }
}



static void DecodeHost (Host* foo)
{
    char string[255];

    //
    //  Name of owner
    //
    set (MUIstOwner, MUIA_Text_Contents, foo->Owner);

    //
    //  IP-address of primary network interface
    //
    if (NP_Config & NP_IPAddr)
        sprintf (string, "%ld.%ld.%ld.%ld", ((foo->IPAddr >> 24) & 0xff), ((foo->IPAddr >> 16) & 0xff), ((foo->IPAddr >> 8) & 0xff), (foo->IPAddr & 0xff));
    else
        string[0] = 0;

    set (MUIstIPAddr, MUIA_Text_Contents, &string);

    //
    //  Kickstart version
    //
    if (NP_Config & NP_KickVersion)
        sprintf (string, "%ld.%ld", ((foo->KickVersion >> 16) & 0xffff), (foo->KickVersion & 0xffff));
    else
        string[0] = 0;

    set (MUIstKickStart, MUIA_Text_Contents, &string);

    //
    //  Kickstart version
    //
    if (NP_Config & NP_WBVersion)
        sprintf (string, "%ld.%ld", ((foo->WBVersion >> 16) & 0xffff), (foo->WBVersion & 0xffff));
    else
        string[0] = 0;

    set (MUIstWorkBench, MUIA_Text_Contents, &string);

    //
    //  NIPC version
    //
    if (NP_Config & NP_NIPCVersion)
        sprintf (string, "%ld.%ld", ((foo->NIPCVersion >> 16) & 0xffff), (foo->NIPCVersion & 0xffff));
    else
        string[0] = 0;

    set (MUIstNIPC, MUIA_Text_Contents, &string);

    //
    //  Chip memory
    //
    if (NP_Config & NP_MaxChipMem)
        sprintf (string, "%ld K", (foo->MaxChipMem / 1024));
    else
        string[0] = 0;

    set (MUIstChipMem, MUIA_Text_Contents, &string);

    //
    //  Fast memory
    //
    if (NP_Config & NP_MaxFastMem)
        sprintf (string, "%ld K", (foo->MaxFastMem / 1024));
    else
        string[0] = 0;

    set (MUIstFastMem, MUIA_Text_Contents, &string);

    //
    //  Processor configuration
    //
    if (NP_Config & NP_ATTNFlags)
        sprintf (string, "%s", DecodeATTNFlags (foo->ATTNFlags));
    else
        string[0] = 0;

    set (MUIstProcessor, MUIA_Text_Contents, &string);

    //
    //  Chipset
    //
    if (NP_Config & NP_ChipRevBits)
        sprintf (string, "%s", DecodeChipRevBits (foo->ChipRevBits));
    else
        string[0] = 0;

    set (MUIstChips, MUIA_Text_Contents, &string);

    //
    //  Services
    //
    DoMethod (MUIlvServices, MUIM_List_Clear);
    if (NP_Config & NP_Services)
    {
        if (!(IsListEmpty (&(foo->Services))))
        {
            struct Node* work;

            for (work = foo->Services.lh_Head; work->ln_Succ; work = work->ln_Succ)
            {
                Add (MUIlvServices, work->ln_Name);
            }
        }
    }

    //
    //  Entities
    //
    DoMethod (MUIlvEntities, MUIM_List_Clear);
    if (NP_Config & NP_Entities)
    {
        if (!(IsListEmpty (&(foo->Entities))))
        {
            struct Node* work;

            for (work = foo->Entities.lh_Head; work->ln_Succ; work = work->ln_Succ)
            {
                Add (MUIlvEntities, work->ln_Name);
            }
        }
    }
}



static void Add (APTR list, char* string)
{
    DoMethod (list, MUIM_List_Insert, &string, 1, MUIV_List_Insert_Sorted);
}
