/**
 * 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 UBYTE *intType[] = {
    "TBE (ser.transmit buffer empty)",
    "DSKBLK (disk block complete)",
    "SOFTINT (software interrupt)",
    "PORTS (external INT2 & CIAA)",
    "COPPER (graphics coprocessor)",
    "VERTB (vertical blank interval)",
    "BLITTER (blitter finished)",
    "AUDIO0 (audio channel 0)",
    "AUDIO1 (audio channel 1)",
    "AUDIO2 (audio channel 2)",
    "AUDIO3 (audio channel 3)",
    "RBF (ser. receive buffer full)",
    "DSKSYNC (disk sync patt. found)",
    "EXTER (external INT6 & CIAB)",
    "INTEN (special (master enable))",
    "NMI (non-maskable interrupt)"
};

static void SetDetails( struct IClass *cl,
                        Object *obj,
                        struct InterruptEntry *ie )
{
    struct InterruptsDetailWinData *idwd = INST_DATA(cl, obj);

    MySetContents(idwd->idwd_InterruptMoreText[0], ie->ie_Name);
    MySetContents(idwd->idwd_InterruptMoreText[1], MUIX_R "%s\n" MUIX_C "%ld\n" MUIX_C "%s", ie->ie_Address, ie->ie_Addr->is_Node.ln_Pri, GetNodeType(ie->ie_Addr->is_Node.ln_Type));
    MySetContents(idwd->idwd_InterruptMoreText[2], MUIX_R "%s\n%s\n" MUIX_C "%s", ie->ie_Data, ie->ie_Code, ie->ie_Kind);
    MySetContents(idwd->idwd_InterruptMoreText[3], intType[ie->ie_IntNumber]);

    set(obj, MUIA_Window_Title, MyGetChildWindowTitle("INTERRUPT", ie->ie_Name, idwd->idwd_Title, sizeof(idwd->idwd_Title)));
}

static ULONG __saveds mNew( struct IClass *cl,
                            Object *obj,
                            struct opSet *msg )
{
    APTR intmoretext[4];

    if (obj = (Object *)DoSuperNew(cl, obj,
        MUIA_HelpNode, InterruptsText,
        MUIA_Window_ID, MakeID('.','I','N','T'),
        WindowContents, HGroup,
            Child, VGroup, MUIA_Group_SameWidth, TRUE,
                Child, MyLabel2("Name:"),
                Child, MyLabel2("Address:\nPri:\nType:"),
                Child, MyLabel2("IntName:"),
            End,
            Child, VGroup, MUIA_Group_SameWidth, TRUE,
                Child, intmoretext[0] = MyTextObject(),
                Child, HGroup,
                    Child, intmoretext[1] = MyTextObject2(),
                    Child, MyLabel("Data:\nCode:\nIntType:"),
                    Child, intmoretext[2] = MyTextObject2(),
                End,
                Child, intmoretext[3] = MyTextObject(),
            End,
        End,
        TAG_MORE, msg->ops_AttrList))
    {
        struct InterruptsDetailWinData *idwd = INST_DATA(cl, obj);
        APTR parent;

        CopyMem(intmoretext, idwd->idwd_InterruptMoreText, sizeof(idwd->idwd_InterruptMoreText));

        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 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, (APTR)tag->ti_Data, 2, MUIM_Window_RemChildWindow, obj);
                break;

            case MUIA_InterruptsDetailWin_Interrupt:
                SetDetails(cl, obj, (struct InterruptEntry *)tag->ti_Data);
                break;
        }
    }

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

ULONG __asm __saveds InterruptsDetailWinDispatcher( 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));
    }

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

