/**
 * 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"

static struct LongFlag screenFlags1[] = {
    { SHOWTITLE,    "SHOWTITLE",    "$0010" },
    { BEEPING,      "BEEPING",      "$0020" },
    { CUSTOMBITMAP, "CUSTOMBITMAP", "$0040" },
    { SCREENBEHIND, "SCREENBEHIND", "$0080" },
    { SCREENQUIET,  "SCREENQUIET",  "$0100" },
    { SCREENHIRES,  "SCREENHIRES",  "$0200" },
    { PENSHARED,    "PENSHARED",    "$0400" },
    { NS_EXTENDED,  "NS_EXTENDED",  "$1000" },
    { AUTOSCROLL,   "AUTOSCROLL",   "$4000" },
    { 0,            NULL,           NULL }
};

static struct MaskedLongFlag screenFlags2[] = {
    { WBENCHSCREEN, SCREENTYPE, "WBENCHSCREEN", "$0001" },
    { PUBLICSCREEN, SCREENTYPE, "PUBLICSCREEN", "$0002" },
    { CUSTOMSCREEN, SCREENTYPE, "CUSTOMSCREEN", "$000F" },
    { 0,            0,          NULL,           NULL }
};

static struct LongFlag pubScreenFlags[] = {
    { PSNF_PRIVATE, "PSNF_PRIVATE", "0x0001" },
    { 0,            NULL,           NULL }
};

static struct LongFlag windowFlags1[] = {
    { WFLG_SIZEGADGET,    "WFLG_SIZEGADGET",    "$00000001" },
    { WFLG_DRAGBAR,       "WFLG_DRAGBAR",       "$00000002" },
    { WFLG_DEPTHGADGET,   "WFLG_DEPTHGADGET",   "$00000004" },
    { WFLG_CLOSEGADGET,   "WFLG_CLOSEGADGET",   "$00000008" },
    { WFLG_SIZEBRIGHT,    "WFLG_SIZEBRIGHT",    "$00000010" },
    { WFLG_SIZEBBOTTOM,   "WFLG_SIZEBBOTTOM",   "$00000020" },
    { WFLG_BACKDROP,      "WFLG_BACKDROP",      "$00000100" },
    { WFLG_REPORTMOUSE,   "WFLG_REPORTMOUSE",   "$00000200" },
    { WFLG_GIMMEZEROZERO, "WFLG_GIMMEZEROZERO", "$00000400" },
    { WFLG_BORDERLESS,    "WFLG_BORDERLESS",    "$00000800" },
    { WFLG_ACTIVATE,      "WFLG_ACTIVATE",      "$00001000" },
    { WFLG_WINDOWACTIVE,  "WFLG_WINDOWACTIVE",  "$00002000" },
    { WFLG_INREQUEST,     "WFLG_INREQUEST",     "$00004000" },
    { WFLG_MENUSTATE,     "WFLG_MENUSTATE",     "$00008000" },
    { WFLG_RMBTRAP,       "WFLG_RMBTRAP",       "$00010000" },
    { WFLG_NOCAREREFRESH, "WFLG_NOCAREREFRESH", "$00020000" },
    { WFLG_NEWLOOKMENUS,  "WFLG_NEWLOOKMENUS",  "$00200000" },
    { WFLG_NW_EXTENDED,   "WFLG_NW_EXTENDED",   "$00040000" },
    { WFLG_WINDOWREFRESH, "WFLG_WINDOWREFRESH", "$01000000" },
    { WFLG_WBENCHWINDOW,  "WFLG_WBENCHWINDOW",  "$02000000" },
    { WFLG_WINDOWTICKED,  "WFLG_WINDOWTICKED",  "$04000000" },
    { WFLG_VISITOR,       "WFLG_VISITOR",       "$08000000" },
    { WFLG_ZOOMED,        "WFLG_ZOOMED",        "$10000000" },
    { WFLG_HASZOOM,       "WFLG_HASZOOM",       "$20000000" },
    { 0,                  NULL,                 NULL }
};

static struct MaskedLongFlag windowFlags2[] = {
   { WFLG_SMART_REFRESH,  WFLG_REFRESHBITS, "WFLG_SMART_REFRESH",  "$00000000" },
   { WFLG_SIMPLE_REFRESH, WFLG_REFRESHBITS, "WFLG_SIMPLE_REFRESH", "$00000040" },
   { WFLG_SUPER_BITMAP,   WFLG_REFRESHBITS, "WFLG_SUPER_BITMAP",   "$00000080" },
   { WFLG_OTHER_REFRESH,  WFLG_REFRESHBITS, "WFLG_OTHER_REFRESH",  "$000000C0" },
   { 0,                   0,                NULL,                  NULL }
};

static struct LongFlag idcmpFlags[] = {
   { IDCMP_SIZEVERIFY,     "IDCMP_SIZEVERIFY",     "$00000001" },
   { IDCMP_NEWSIZE,        "IDCMP_NEWSIZE",        "$00000002" },
   { IDCMP_REFRESHWINDOW,  "IDCMP_REFRESHWINDOW",  "$00000004" },
   { IDCMP_MOUSEBUTTONS,   "IDCMP_MOUSEBUTTONS",   "$00000008" },
   { IDCMP_MOUSEMOVE,      "IDCMP_MOUSEMOVE",      "$00000010" },
   { IDCMP_GADGETDOWN,     "IDCMP_GADGETDOWN",     "$00000020" },
   { IDCMP_GADGETUP,       "IDCMP_GADGETUP",       "$00000040" },
   { IDCMP_REQSET,         "IDCMP_REQSET",         "$00000080" },
   { IDCMP_MENUPICK,       "IDCMP_MENUPICK",       "$00000100" },
   { IDCMP_CLOSEWINDOW,    "IDCMP_CLOSEWINDOW",    "$00000200" },
   { IDCMP_RAWKEY,         "IDCMP_RAWKEY",         "$00000400" },
   { IDCMP_REQVERIFY,      "IDCMP_REQVERIFY",      "$00000800" },
   { IDCMP_REQCLEAR,       "IDCMP_REQCLEAR",       "$00001000" },
   { IDCMP_MENUVERIFY,     "IDCMP_MENUVERIFY",     "$00002000" },
   { IDCMP_NEWPREFS,       "IDCMP_NEWPREFS",       "$00004000" },
   { IDCMP_DISKINSERTED,   "IDCMP_DISKINSERTED",   "$00008000" },
   { IDCMP_DISKREMOVED,    "IDCMP_DISKREMOVED",    "$00010000" },
   { IDCMP_WBENCHMESSAGE,  "IDCMP_WBENCHMESSAGE",  "$00020000" },
   { IDCMP_ACTIVEWINDOW,   "IDCMP_ACTIVEWINDOW",   "$00040000" },
   { IDCMP_INACTIVEWINDOW, "IDCMP_INACTIVEWINDOW", "$00080000" },
   { IDCMP_DELTAMOVE,      "IDCMP_DELTAMOVE",      "$00100000" },
   { IDCMP_VANILLAKEY,     "IDCMP_VANILLAKEY",     "$00200000" },
   { IDCMP_INTUITICKS,     "IDCMP_INTUITICKS",     "$00400000" },
   { IDCMP_IDCMPUPDATE,    "IDCMP_IDCMPUPDATE",    "$00800000" },
   { IDCMP_MENUHELP,       "IDCMP_MENUHELP",       "$01000000" },
   { IDCMP_CHANGEWINDOW,   "IDCMP_CHANGEWINDOW",   "$02000000" },
   { IDCMP_GADGETHELP,     "IDCMP_GADGETHELP",     "$04000000" },
   { IDCMP_LONELYMESSAGE,  "IDCMP_LONELYMESSAGE",  "$80000000" },
   { 0,                    NULL,                   NULL }
};

static void SetDetails( struct IClass *cl,
                        Object *obj,
                        struct WindowEntry *we )
{
    struct WindowsDetailWinData *wdwd = INST_DATA(cl, obj);

    if (stricmp(we->we_Type, "SCREEN") == 0) {
        struct Screen *screen = (struct Screen *)we->we_Addr;
        APTR addgroup;
        APTR screenmoretext0,screenmoretext1,screenmoretext2,screenmoretext3;
        APTR screenmoretext4,screenmoretext5a,screenmoretext5b,screenmoretext6,screenmoretext7;
        APTR screenmoretext8,screenmoretext9,screenmoretext10;
        APTR screenmoretext11,screenmoretext12,screenmoretext13,screenmoretext14,screenmoretext15;
        APTR AddGroup1,AddGroup2;
        struct List *publist;
        ULONG id;

        Child, addgroup = HGroup,
            Child, VGroup,
                Child, MyLabel2("Title:"),
                Child, MyLabel2("DefaultTitle:"),
                Child, MyVSpace(0),
                Child, MyLabel2("LeftEdge:\nTopEdge:\nWidth:\nHeight:\nDetailPen:"),
                Child, MyVSpace(0),
                Child, MyLabel2("ScreenMode:"),
                Child, MyLabel2("NextScreen:\nFirstWindow:"),
                Child, AddGroup1 = VGroup, MUIA_ShowMe, FALSE,
                    Child, MyLabel2("PublicName:"),
                    Child, MyLabel2("SigTask:"),
                End,
            End,
            Child, VGroup, MUIA_Group_SameWidth, TRUE,
                Child, screenmoretext0 = MyTextObject(),
                Child, screenmoretext1 = MyTextObject(),

                Child, HGroup,
                    Child, screenmoretext2 = MyTextObject2(),
                    Child, MyLabel("BarVBorder:\nBarHBorder:\nMenuVBorder:\nMenuHBorder:\nBlockPen:"),
                    Child, screenmoretext3 = MyTextObject2(),
                    Child, MyLabel("WBorTop:\nWBorLeft:\nWBorRight:\nWBorBottom:\nDepth:"),
                    Child, screenmoretext4 = MyTextObject2(),
                    Child, VGroup,
                        Child, MyLabel("MouseY:\nMouseX:\nBarHeight:\nSaveColor0:"),
                        Child, MyLabel("Flags:"),
                    End,
                    Child, VGroup, MUIA_Group_SameWidth, TRUE, MUIA_Weight, 0,
                        Child, screenmoretext5a = MyTextObject(),
                        Child, screenmoretext5b = MakeButton(""),
                    End,
                End,

                Child, HGroup, MUIA_Group_SameWidth, TRUE,
                    Child, screenmoretext10 = MyTextObject(),
                    Child, HGroup,
                        Child, MyLabel2("Font:"),
                        Child, screenmoretext9 = MyTextObject(),
                    End,
                End,

                Child, HGroup,
                    Child, screenmoretext6 = MyTextObject2(),
                    Child, MyLabel("FirstGadget:\nBarLayer:"),
                    Child, screenmoretext7 = MyTextObject2(),
                    Child, MyLabel("ExtData:\nUserData:"),
                    Child, screenmoretext8 = MyTextObject2(),
                End,

                Child, AddGroup2 = HGroup, MUIA_ShowMe, FALSE,
                    Child, VGroup,
                        Child, HGroup,
                            Child, screenmoretext11 = MyTextObject(),
                            Child, HGroup, MUIA_Weight, 0,
                                Child, MyLabel ("Flags:"),
                                Child, screenmoretext12 = MakeButton(""),
                            End,
                        End,
                        Child, screenmoretext13 = MyTextObject(),
                    End,
                    Child, VGroup,
                        Child, MyLabel2("Visitors:"),
                        Child, MyLabel2("SigBit:"),
                    End,
                    Child, VGroup, MUIA_Group_SameWidth, TRUE,
                        Child, screenmoretext14 = MyTextObject(),
                        Child, screenmoretext15 = MyTextObject2(),
                    End,
                End,
            End,
        End;

        DoMethod(wdwd->wdwd_MainGroup, OM_ADDMEMBER, addgroup);

        set(obj, MUIA_Window_ActiveObject, screenmoretext5b);

        DoMethod(screenmoretext5b, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_WindowsDetailWin_ScreenFlagsMore);
        DoMethod(screenmoretext12, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_WindowsDetailWin_PubScreenFlagsMore);

        MySetContents(screenmoretext0, nonetest(screen->Title));
        MySetContents(screenmoretext1, screen->DefaultTitle);
        MySetContents(screenmoretext2, MUIX_R "%ld\n%ld\n%3ld\n%ld\n%ld", screen->LeftEdge, screen->TopEdge, screen->Width, screen->Height, screen->DetailPen);
        MySetContents(screenmoretext3, MUIX_R "%ld\n%ld\n%3ld\n%ld\n%ld", screen->BarVBorder, screen->BarHBorder, screen->MenuVBorder, screen->MenuHBorder, screen->BlockPen);
        MySetContents(screenmoretext4, MUIX_R "%ld\n%ld\n%3ld\n%ld\n%ld", screen->WBorTop, screen->WBorLeft, screen->WBorRight, screen->WBorBottom, GetBitMapAttr(screen->RastPort.BitMap, BMA_DEPTH));
        MySetContents(screenmoretext5a, MUIX_R "%ld\n%ld\n%ld\n%ld", screen->MouseY, screen->MouseX, screen->BarHeight, screen->SaveColor0);
        MySetContents(screenmoretext5b, MUIX_B "$%04lx", screen->Flags);
        MySetContents(screenmoretext6, MUIX_R "$%08lx\n$%08lx", screen->NextScreen, screen->FirstWindow);
        MySetContents(screenmoretext7, MUIX_R "$%08lx\n$%08lx", screen->FirstGadget, screen->BarLayer);
        MySetContents(screenmoretext8, MUIX_R "$%08lx\n$%08lx", screen->ExtData, screen->UserData);
        MySetContents(screenmoretext9, "%s/%ld", screen->Font->ta_Name, screen->Font->ta_YSize);

        if (publist = LockPubScreenList()) {
            struct PubScreenNode *pubscreen;

            pubscreen = (struct PubScreenNode *)publist->lh_Head;

            while (pubscreen->psn_Node.ln_Succ) {
                if (pubscreen->psn_Screen == screen) {
                    set(AddGroup1, MUIA_ShowMe, TRUE);
                    set(AddGroup2, MUIA_ShowMe, TRUE);

                    MySetContents(screenmoretext11, pubscreen->psn_Node.ln_Name);
                    MySetContents(screenmoretext12, MUIX_B "$%04lx", pubscreen->psn_Flags);
                    MySetContents(screenmoretext14, MUIX_R "%ld", pubscreen->psn_VisitorCount);
                    if (pubscreen->psn_SigBit != -1) {
                        MySetContents(screenmoretext15, MUIX_R "%ld", pubscreen->psn_SigBit);
                    } else {
                        MySetContents(screenmoretext15, MUIX_R "---");
                    }
                    MySetContents(screenmoretext13, nonetest(GetTaskName(pubscreen->psn_SigTask)));

                    wdwd->wdwd_PubScreen = pubscreen;
                    break;
                }

                pubscreen = (struct PubScreenNode *)pubscreen->psn_Node.ln_Succ;
            }

            UnlockPubScreenList();
        }

        if (id = GetVPModeID (&screen->ViewPort)) {
            UBYTE *tmp;

            if (tmp = tbAllocVecPooled(globalPool, PATH_LENGTH)) {
                APTR handle;

                if (handle = FindDisplayInfo(id)) {
                    if (GetDisplayInfoData(handle, tmp, sizeof(struct NameInfo), DTAG_NAME, 0)) {
                        MySetContents(screenmoretext10, "%s ($%08lx)", ((struct NameInfo *)tmp)->Name, id);
                    } else {
                        struct MonitorSpec *mspc;

                        if (mspc = OpenMonitor(NULL, id)) {
                            ULONG i = 0;
                            struct DimensionInfo diminfo;

                            NameCopy(tmp, mspc->ms_Node.xln_Name);

                            GetDisplayInfoData(handle, (UBYTE *)&diminfo, sizeof(struct DimensionInfo), DTAG_DIMS, 0);
                            _snprintf(&tmp[strlen(tmp)], PATH_LENGTH - i, "%ld x %ld ($%08lx)", diminfo.Nominal.MaxX - diminfo.Nominal.MinX + 1, diminfo.Nominal.MaxY - diminfo.Nominal.MinY + 1, id);
                            MySetContents(screenmoretext10, tmp);
                            CloseMonitor(mspc);
                        }
                    }
                }

                tbFreeVecPooled(globalPool, tmp);
            }
        }

        set(obj, MUIA_Window_Title, MyGetChildWindowTitle("SCREEN", we->we_Title + 2, wdwd->wdwd_Title, sizeof(wdwd->wdwd_Title)));
    } else {
        struct Window *win = (struct Window *)we->we_Addr;
        APTR addgroup;
        APTR winmoretext0,winmoretext1,winmoretext2,winmoretext3,winmoretext4;
        APTR winmoretext5,winmoretext6a,winmoretext6b,winmoretext7a,winmoretext7b,winmoretext8,winmoretext9;
        APTR winmoretext10,winmoretext11,winmoretext12,winmoretext13,winmoretext14;

        Child, addgroup = HGroup,
            Child, VGroup, MUIA_Group_SameWidth, TRUE,
                Child, MyLabel2("Title:"),
                Child, MyLabel2("ScreenTitle:"),
                Child, MyLabel2("LeftEdge:\nTopEdge:\nMinWidth:\nMinHeight:\nBorderRight:\nBorderBottom:"),
                Child, MyLabel2("NextWindow:\nFirstRequest:\nRPort:\nParent:\nExtData:"),
                Child, MyLabel2("IDCMPFlags:"),
                Child, MyLabel2("ReqCount:"),
                Child, MyLabel2("UserPort:"),
                Child, MyLabel2("WindowPort:"),
            End,
            Child, VGroup, MUIA_Group_SameWidth, TRUE,
                Child, winmoretext0 = MyTextObject(),
                Child, winmoretext1 = MyTextObject(),
                Child, HGroup,
                    Child, winmoretext2 = MyTextObject2(),
                    Child, MyLabel("Width:\nHeight:\nMaxWidth:\nMaxHeight:\nPtrHeight:\nPtrWidth:"),
                    Child, winmoretext3 = MyTextObject2(),
                    Child, MyLabel("MouseY:\nMouseX:\nBorderLeft:\nBorderTop:\nXOffset:\nYOffset:"),
                    Child, winmoretext4 = MyTextObject2(),
                    Child, MyLabel("DetailPen:\nBlockPen:\nGZZMouseX:\nGZZMouseY:\nGZZWidth:\nGZZHeight:"),
                    Child, winmoretext5 = MyTextObject2(),
                End,
                Child, HGroup,
                    Child, VGroup, MUIA_Group_SameWidth, TRUE, MUIA_Weight, 0,
                        Child, winmoretext6a = MyTextObject(),
                        Child, winmoretext6b = MakeButton(""),
                        Child, winmoretext9 = MyTextObject(),
                        Child, winmoretext10 = MyTextObject(),
                        Child, winmoretext11 = MyTextObject(),
                    End,
                    Child, VGroup, MUIA_Group_SameWidth, TRUE, MUIA_Weight, 60,
                        Child, MyLabel("Flags:"),
                        Child, MyLabel("DMRequest:\nBorderRPort:\nDescendant:\nMessageKey:\nUserData:"),
                        Child, MyLabel("IFont:"),
                        Child, MyLabel("-> SigTask:"),
                        Child, MyLabel("-> SigTask:"),
                    End,
                    Child, VGroup,
                        Child, HGroup,
                            Child, VGroup, MUIA_Group_SameWidth, TRUE, MUIA_Weight, 0,
                                Child, winmoretext7a = MakeButton(""),
                                Child, winmoretext7b = MyTextObject(),
                            End,
                            Child, HGroup, MUIA_Weight, 60,
                                Child, MyLabel("MenuStrip:\nWScreen:\nFirstGadget:\nPointer:\nCheckMark:\nWLayer:"),
                            End,
                            Child, winmoretext8 = MyTextObject2(),
                        End,
                        Child, winmoretext12 = MyTextObject(),
                        Child, winmoretext13 = MyTextObject(),
                        Child, winmoretext14 = MyTextObject(),
                    End,
                End,
            End,
        End;

        DoMethod(wdwd->wdwd_MainGroup, OM_ADDMEMBER, addgroup);

        set(obj, MUIA_Window_ActiveObject, winmoretext7a);

        DoMethod(winmoretext7a, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_WindowsDetailWin_WindowFlagsMore);
        DoMethod(winmoretext6b, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_WindowsDetailWin_IDCMPFlagsMore);

        MySetContents(winmoretext0, nonetest(win->Title));
        MySetContents(winmoretext1, nonetest(win->ScreenTitle));
        MySetContents(winmoretext2, MUIX_R "%ld\n%ld\n%ld\n%ld\n%ld\n%ld", win->LeftEdge, win->TopEdge, win->MinWidth, win->MinHeight, win->BorderRight, win->BorderBottom);
        MySetContents(winmoretext3, MUIX_R "%ld\n%ld\n%ld\n%ld\n%ld\n%ld", win->Width, win->Height, win->MaxWidth, win->MaxHeight, win->PtrHeight, win->PtrWidth);
        MySetContents(winmoretext4, MUIX_R "%ld\n%ld\n%ld\n%ld\n%ld\n%ld", win->MouseY, win->MouseX, win->BorderLeft, win->BorderTop, win->XOffset, win->YOffset);
        MySetContents(winmoretext5, MUIX_R "%ld\n%ld\n%ld\n%ld\n%ld\n%ld", win->DetailPen, win->BlockPen, win->GZZMouseX, win->GZZMouseY, win->GZZWidth, win->GZZHeight);
        MySetContents(winmoretext6a, MUIX_R "$%08lx\n$%08lx\n$%08lx\n$%08lx\n$%08lx", win->NextWindow, win->FirstRequest, win->RPort, win->Parent, win->ExtData);
        MySetContents(winmoretext6b, MUIX_B "$%08lx", win->IDCMPFlags);
        MySetContents(winmoretext7a, MUIX_B "$%08lx", win->Flags);
        MySetContents(winmoretext7b, MUIX_R "$%08lx\n$%08lx\n$%08lx\n$%08lx\n$%08lx", win->DMRequest, win->BorderRPort, win->Descendant, win->MessageKey, win->UserData);
        MySetContents(winmoretext8, MUIX_R "$%08lx\n$%08lx\n$%08lx\n$%08lx\n$%08lx\n$%08lx", win->MenuStrip, win->WScreen, win->FirstGadget, win->Pointer, win->CheckMark, win->WLayer);
        MySetContents(winmoretext9, MUIX_R "%ld", win->ReqCount);
        MySetContents(winmoretext10, MUIX_R "$%08lx", win->UserPort);
        MySetContents(winmoretext11, MUIX_R "$%08lx", win->WindowPort);

        MySetContents(winmoretext12, "%s/%ld", win->IFont->tf_Message.mn_Node.ln_Name, win->IFont->tf_YSize);

        if (win->UserPort) MySetContentsHealed(winmoretext13, nonetest(GetTaskName(win->UserPort->mp_SigTask)));
        if (win->WindowPort) MySetContentsHealed(winmoretext14, nonetest(GetTaskName(win->WindowPort->mp_SigTask)));

        set(obj, MUIA_Window_Title, MyGetChildWindowTitle("WINDOW", we->we_Title, wdwd->wdwd_Title, sizeof(wdwd->wdwd_Title)));
    }
}

static ULONG __saveds mNew( struct IClass *cl,
                            Object *obj,
                            struct opSet *msg )
{
    APTR maingroup;

    if (obj = (Object *)DoSuperNew(cl, obj,
        MUIA_HelpNode, WindowsText,
        MUIA_Window_ID, MakeID('.','W','I','N'),
        WindowContents, maingroup = HGroup,

        End,
        TAG_MORE, msg->ops_AttrList))
    {
        struct WindowsDetailWinData *wdwd = INST_DATA(cl, obj);
        APTR parent;

        wdwd->wdwd_MainGroup = maingroup;

        parent = (APTR)GetTagData(MUIA_Window_ParentWindow, (ULONG)NULL, msg->ops_AttrList);

        DoMethod(parent, MUIM_Window_AddChildWindow, obj);
        DoMethod(obj,    MUIM_Notify,              MUIA_Window_CloseRequest, TRUE,  MUIV_Notify_Application, 5, MUIM_Application_PushMethod, parent, 2, MUIM_Window_RemChildWindow, obj);
    }

    return (ULONG)obj;
}

static ULONG __saveds mDispose( struct IClass *cl,
                                Object *obj,
                                struct opSet *msg )
{
    set(obj, MUIA_Window_Open, FALSE);

    return (DoSuperMethodA(cl, obj, msg));
}

static ULONG __saveds mSet( struct IClass *cl,
                            Object *obj,
                            Msg msg )
{
    struct WindowsDetailWinData *wdwd = INST_DATA(cl, obj);
    struct TagItem *tags, *tag;

    for (tags = ((struct opSet *)msg)->ops_AttrList; tag = NextTagItem(&tags); ) {
        switch (tag->ti_Tag) {
            case MUIA_Window_ParentWindow:
                DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, MUIV_Notify_Application, 5, MUIM_Application_PushMethod, tag->ti_Data, 2, MUIM_Window_RemChildWindow, obj);
                break;

            case MUIA_WindowsDetailWin_Object:
                wdwd->wdwd_Object = (struct WindowEntry *)tag->ti_Data;
                SetDetails(cl, obj, (struct WindowEntry *)tag->ti_Data);
                break;
        }
    }

    return (DoSuperMethodA(cl,obj,msg));
}

static ULONG __saveds mScreenFlagsMore( struct IClass *cl,
                                        Object *obj,
                                        Msg msg )
{
    struct WindowsDetailWinData *wdwd = INST_DATA(cl, obj);
    APTR flagsWin;

    if (flagsWin = FlagsWindowObject,
            MUIA_Window_Title, "Screen Flags",
            MUIA_Window_ParentWindow, obj,
        End) {
        DoMethod(flagsWin, MUIM_FlagsWin_ShowFlags, ((struct Screen *)wdwd->wdwd_Object->we_Addr)->Flags, MUIV_FlagsWin_FlagsType_Word, screenFlags1, screenFlags2, "Flags");
    }

    return 0;
}

static ULONG __saveds mPubScreenFlagsMore( struct IClass *cl,
                                           Object *obj,
                                           Msg msg )
{
    struct WindowsDetailWinData *wdwd = INST_DATA(cl, obj);
    APTR flagsWin;

    if (wdwd->wdwd_PubScreen) {
        if (flagsWin = FlagsWindowObject,
                MUIA_Window_Title, "PubScreen Flags",
                MUIA_Window_ParentWindow, obj,
            End) {
            DoMethod(flagsWin, MUIM_FlagsWin_ShowFlags, wdwd->wdwd_PubScreen->psn_Flags, MUIV_FlagsWin_FlagsType_Word, pubScreenFlags, NULL, "psn_Flags");
        }
    }

    return 0;
}

static ULONG __saveds mWindowFlagsMore( struct IClass *cl,
                                        Object *obj,
                                        Msg msg )
{
    struct WindowsDetailWinData *wdwd = INST_DATA(cl, obj);
    APTR flagsWin;

    if (flagsWin = FlagsWindowObject,
            MUIA_Window_Title, "Window Flags",
            MUIA_Window_ParentWindow, obj,
        End) {
        DoMethod(flagsWin, MUIM_FlagsWin_ShowFlags, ((struct Window *)wdwd->wdwd_Object->we_Addr)->Flags, MUIV_FlagsWin_FlagsType_Long, windowFlags1, windowFlags2, "Flags");
    }

    return 0;
}

static ULONG __saveds mIDCMPFlagsMore( struct IClass *cl,
                                       Object *obj,
                                       Msg msg )
{
    struct WindowsDetailWinData *wdwd = INST_DATA(cl, obj);
    APTR flagsWin;

    if (flagsWin = FlagsWindowObject,
            MUIA_Window_Title, "IDCMP Flags",
            MUIA_Window_ParentWindow, obj,
        End) {
        DoMethod(flagsWin, MUIM_FlagsWin_ShowFlags, ((struct Window *)wdwd->wdwd_Object->we_Addr)->IDCMPFlags, MUIV_FlagsWin_FlagsType_Long, idcmpFlags, NULL, "IDCMP Flags");
    }

    return 0;
}

ULONG __asm __saveds WindowsDetailWinDispatcher( register __a0 struct IClass *cl,
                                                 register __a2 Object *obj,
                                                 register __a1 Msg msg )
{
    switch (msg->MethodID) {
        case OM_NEW:                                   return (mNew(cl, obj, (APTR)msg));
        case OM_DISPOSE:                               return (mDispose(cl, obj, (APTR)msg));
        case OM_SET:                                   return (mSet(cl, obj, (APTR)msg));
        case MUIM_WindowsDetailWin_ScreenFlagsMore:    return (mScreenFlagsMore(cl, obj, (APTR)msg));
        case MUIM_WindowsDetailWin_PubScreenFlagsMore: return (mPubScreenFlagsMore(cl, obj, (APTR)msg));
        case MUIM_WindowsDetailWin_WindowFlagsMore:    return (mWindowFlagsMore(cl, obj, (APTR)msg));
        case MUIM_WindowsDetailWin_IDCMPFlagsMore:     return (mIDCMPFlagsMore(cl, obj, (APTR)msg));
    }

    return (DoSuperMethodA(cl, obj, msg));
}

