#include "includes.h"
#include "structs.h"
#include <libraries/commodities.h>
#include <dos/notify.h>

extern struct tm_settings dftm;

extern struct Window           *my_window;
extern struct TextFont         *my_text_font,
                               *my_clock_font_1,
                               *my_clock_font_2;
extern struct RastPort         *my_rastport,
                                my_rp,
                                my_rp_2;
extern struct BitMap           *my_bitmap,
                               *my_b1,
                               *my_b2,
                               *my_b;
extern struct BitMapHeader     *my_header;
extern struct Screen           *my_pub_screen;
extern struct Object           *my_dtobject;
extern UBYTE                    numoflines,numofvols;
extern ULONG                    gauge_x_pos,
                                gauge_y_pos_2,
                                gauge_x_size,
                                info_x_size,
                                space;
extern char                    *LoadedVolList[64],
                               *LoadedVolList_1[64];
extern UBYTE                    were_on_public;
extern UWORD                    yypos[32];
extern UWORD                    xxpos[32];

extern struct Library          *DataTypesBase;

ULONG                        my_window_mask;
struct Library              *ScreenNotifyBase=0L;
struct DateTime              dt;
struct DateStamp            *ptr_ds;
struct timeval               my_val;

intui_handler(struct MsgPort *broker_mp, CxObj *broker, ULONG cxsigflag)
{
    struct IntuiMessage        *m;
    BOOL                        running = TRUE;
    ULONG                       my_m_x,my_m_y;
    ULONG                       sigs;
    ULONG                       my_test_port_mask;
    ULONG                       my_time_mask_clock;
    ULONG                       my_port_mask;
    struct MsgPort             *my_time_port_clock;
    struct MsgPort             *my_port;
    struct MsgPort             *my_test_port;
    ULONG                      *my_handler;
    struct timerequest         *my_time_request_clock;
    struct TestSettingsMessage *my_test_message;
    ULONG                       interval,
                                mem_val=0,
                                vol_val=0;
    struct NotifyRequest       *notifyrequest;
    LONG                        not_sig;

    get_avail_ram_and_display(1,numofvols);
    get_avail_ram_and_display(2,numofvols);
/*    DisplayCLOCK(&dt,((numoflines-1)/dftm.colums)+1);*/

    my_test_port=(struct MsgPort *)CreatePort("TinyMeter",0 );
    my_test_port_mask = 1L << (my_test_port->mp_SigBit);
    if(dftm.UseScreenNotify)
    {
        if(!(ScreenNotifyBase=(struct Library *)OpenLibrary("screennotify.library",SCREENNOTIFY_VERSION))) exit(0);
        my_port=(struct MsgPort *)CreateMsgPort();
        my_handler=((!were_on_public)|(!strcmp(&dftm.pubscreen_name[0],"Workbench"))) ? (ULONG *)AddWorkbenchClient(my_port,0) : (ULONG *)AddCloseScreenClient(my_pub_screen, my_port, 0) ;
        my_port_mask    = 1L << my_port->mp_SigBit;
    }
    if(my_time_port_clock=(struct MsgPort *)CreateMsgPort())
    {
        if(my_time_request_clock = (struct timerequest *)CreateIORequest(my_time_port_clock,sizeof(struct timerequest)))
        {
            if(!OpenDevice("timer.device",UNIT_WAITUNTIL,my_time_request_clock,NULL))
            {
                if(notifyrequest = AllocVec(sizeof(struct NotifyRequest), MEMF_CLEAR))
                {
                    if ((not_sig = AllocSignal(-1L)) != -1)
                    {
                        notifyrequest->nr_Name = "ENV:sys/WBPattern.prefs";
                        notifyrequest->nr_Flags = NRF_SEND_SIGNAL;
                        notifyrequest->nr_stuff.nr_Signal.nr_Task = (struct Task *) FindTask(NULL);
                        notifyrequest->nr_stuff.nr_Signal.nr_SignalNum = not_sig;
                        if ((StartNotify(notifyrequest)) == DOSTRUE)
                        {

                            my_time_mask_clock    = 1L << (my_time_port_clock->mp_SigBit);
                            init_time_request(my_time_request_clock,my_time_mask_clock);

                            while(running)
                            {
                                if (running) sigs = Wait(my_port_mask | my_window_mask  | my_time_mask_clock | my_test_port_mask | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | (1L << not_sig) | cxsigflag );
                                if (sigs & (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D)) running=FALSE;
                                if (sigs & (1L << not_sig))
                                {
                                    Delay(100L);
                                    while((m=(struct IntuiMessage *)GetMsg( my_window->UserPort )))ReplyMsg( m );
                                    my_window_mask=0L;
                                    draw_borders_and_background();
                                    get_avail_ram_and_display(2,numofvols);
                                }
                                if (sigs & cxsigflag)
                                {
                                    CxMsg *msg;
                                    ULONG sigrcvd, msgid, msgtype;

                                    while(msg = (CxMsg *)GetMsg(broker_mp))
                                    {
                                        msgid = CxMsgID(msg);
                                        msgtype = CxMsgType(msg);
                                        if(msgtype==CXM_COMMAND)
                                        switch(msgid)
                                        {
                                            case    CXCMD_DISABLE:
                                                    {
                                                        BOOL pause=TRUE;
                                                        ActivateCxObj(broker, 0L);
                                                        while(pause)
                                                        {
                                                            Wait(cxsigflag);
                                                            while(msg = (CxMsg *)GetMsg(broker_mp))
                                                            {
                                                                msgid = CxMsgID(msg);
                                                                msgtype = CxMsgType(msg);
                                                                ReplyMsg((struct Message *)msg);
                                                                if(msgtype==CXM_COMMAND) if(msgid==CXCMD_ENABLE) pause=FALSE;
                                                            }
                                                        }
                                                        ActivateCxObj(broker, 1L);
                                                    }
                                                    break;
                                            case    CXCMD_ENABLE:
                                                    ActivateCxObj(broker, 1L);
                                                    break;
                                            case    CXCMD_KILL:
                                                    running=FALSE;
                                                    break;
                                        }
                                        ReplyMsg((struct Message *)msg);
                                    }
                                }

                                if ((sigs & my_test_port_mask))
                                {
                                    while(my_test_message=(struct TestSettingsMessage *)GetMsg(my_test_port))
                                    {
                                        if(my_test_message->ts_type==0L)
                                        {
                                            free_all();
                                            CopyMem(my_test_message->ts_NewSettings,&dftm, sizeof(struct tm_settings));
                                            if(!ScreenNotifyBase)dftm.UseScreenNotify=FALSE;
                                            if(dftm.VolRefreshTime==0)  dftm.VolRefreshTime=10;
                                            if(dftm.colums<1)           dftm.colums=1;
                                            ReplyMsg(my_test_message);
                                            makeall();
                                        }
                                        else
                                        {
                                            my_test_message->ts_NewSettings=(ULONG)my_window;
                                            ReplyMsg(my_test_message);
                                        }
                                    }
                                }

                                if (sigs & my_time_mask_clock)
                                {
                                    if(!CheckIO(my_time_request_clock)) AbortIO(my_time_request_clock);
                                    WaitIO(my_time_request_clock);
                                    if(my_window)
                                    {
                                        if(dftm.DisplayDIGITAL | dftm.DisplayDATE)
                                        {
                                            DateStamp(&dt.dat_Stamp);
                                            DisplayCLOCK(&dt,((numoflines-1)/dftm.colums)+1);
                                        }
                                        mem_val++;
                                        if(mem_val>=dftm.RefreshTime)
                                        {
                                            mem_val=0;
                                            get_avail_ram_and_display(0,numofvols);
                                        }
                                        vol_val++;
                                        if(vol_val>=dftm.VolRefreshTime)
                                        {
                                            vol_val=0;
                                            get_avail_ram_and_display(2,numofvols);
                                        }
                                    }
                                    switch(dftm.WindowBackFront)
                                    {
                                        case    1:
                                                WindowToBack(my_window);
                                                break;
                                        case    2:
                                                WindowToFront(my_window);
                                                break;
                                    }
                                    init_time_request(my_time_request_clock,my_time_mask_clock);
                                }

                                if(dftm.UseScreenNotify)
                                {
                                    if (ScreenNotifyBase)
                                    if (sigs & my_port_mask)
                                    {
                                        struct ScreenNotifyMessage *snm;
                                        while (snm = (struct ScreenNotifyMessage *) GetMsg(my_port))
                                        {
                                            switch(snm->snm_Type)
                                            {
                                                case    SCREENNOTIFY_TYPE_CLOSESCREEN:
                                                        running=FALSE;
                                                        break;
                                                case    SCREENNOTIFY_TYPE_WORKBENCH:
                                                        switch ((ULONG)snm->snm_Value)
                                                        {
                                                            case    FALSE:
                                                                    if (my_window) free_all();
                                                                    break;
                                                            case    TRUE:
                                                                    if (!my_window)
                                                                    {
                                                                        Delay(50L); /* Safety time */
                                                                        makeall();
                                                                    }
                                                                    break;
                                                        }
                                                        break;
                                            }
                                            ReplyMsg((struct Message *) snm);
                                        }
                                    }
                                }

                                if (sigs & my_window_mask )
                                {
                                    while((m=(struct IntuiMessage *)GetMsg( my_window->UserPort )))
                                    {
                                        switch ( m->Class )
                                        {
                                            case    IDCMP_CHANGEWINDOW:
                                                    if(dftm.back_pic==2)
                                                    {
                                                        ReplyMsg( m );
                                                        while((m=(struct IntuiMessage *)GetMsg( my_window->UserPort )))ReplyMsg( m );
                                                        my_window_mask=0L;
                                                        draw_borders_and_background();
                                                        get_avail_ram_and_display(2,numofvols);
                                                    }
                                                    break;
                                            case    IDCMP_CLOSEWINDOW:
                                                    running=FALSE;
                                                    ReplyMsg( m );
                                                    break;
                                            case    IDCMP_NEWSIZE:
                                                    {
                                                        int k;
                                                        new_window_size();
                                                        RefreshGList(my_window->FirstGadget,my_window,NULL,0L);
                                                        SetRast(my_rastport,0);
                                                        gauge_x_size    = ((my_window->Width)/dftm.colums)-gauge_x_pos-BSIZX;
                                                        for(k=0;k<dftm.colums;k++) xxpos[k]=(gauge_x_pos)*(k+1)+((BSIZX+gauge_x_size)*k)+1;
                                                        info_x_size     = ((my_window->Width)/dftm.colums)-(BSIZX<<1);
                                                        if(dftm.back_pic==2)
                                                        {
                                                            ReplyMsg( m );
                                                            while((m=(struct IntuiMessage *)GetMsg( my_window->UserPort )))ReplyMsg( m );
                                                            my_window_mask=0L;
                                                            draw_borders_and_background();
                                                            get_avail_ram_and_display(2,numofvols);
                                                        }
                                                        else
                                                        {
                                                            draw_borders_and_background();
                                                            ReplyMsg( m );
                                                            get_avail_ram_and_display(2,numofvols);
                                                        }
                                                    }
                                                    break;
                                            case    IDCMP_VANILLAKEY:
                                                    switch(m->Code)
                                                    {
                                                        case    'S':
                                                        case    's':
                                                                {
                                                                    UBYTE *my_file;
                                                                    dftm.x_pos=my_window->LeftEdge;
                                                                    dftm.y_pos=my_window->TopEdge;
                                                                    dftm.x_siz=my_window->Width;
                                                                    if(my_file=(UBYTE *)Open("ENV:TinyMeter",MODE_NEWFILE))
                                                                    {
                                                                        Write(my_file,&dftm,(ULONG)sizeof(struct tm_settings));
                                                                        Close(my_file);
                                                                    }
                                                                    if(my_file=(UBYTE *)Open("ENVARC:TinyMeter",MODE_NEWFILE))
                                                                    {
                                                                        Write(my_file,&dftm,(ULONG)sizeof(struct tm_settings));
                                                                        Close(my_file);
                                                                    }
                                                                }
                                                                break;
                                                        case    'F':
                                                        case    'f':
                                                                {
                                                                    ULONG   my_mem;
                                                                    Forbid();
                                                                    my_mem= AllocVec(2000000000L,MEMF_PUBLIC); 
                                                                    if(my_mem)FreeVec(my_mem);
                                                                    Permit();
                                                                }
                                                                break;
                                                        case    'Q':
                                                        case    'q':
                                                                running=FALSE;
                                                                break;
                                                        case    'p':
                                                        case    'P':
                                                                Execute("run >NIL: <NIL: SYS:Prefs/TinyMeterPrefs",0L,0L);
                                                                break;
                                                    }
                                                    ReplyMsg( m );
                                                    break;
                                            case    IDCMP_MOUSEBUTTONS:
                                                    if((m->Code&129)==1)
                                                    {
                                                         get_avail_ram_and_display(1,numofvols);
                                                         get_avail_ram_and_display(2,numofvols);
                                                    }
                                                    ReplyMsg( m );
                                                    break;
                                            default :
                                                    ReplyMsg( m );
                                                    break;
                                        }
                                    }
                                }
                            }
                        }
                        FreeSignal(not_sig);
                    }
                    FreeVec(notifyrequest);
                }
                if(!CheckIO(my_time_request_clock))
                    AbortIO(my_time_request_clock);

                WaitIO(my_time_request_clock);
                CloseDevice(my_time_request_clock);

            }
            DeleteIORequest(my_time_request_clock);
        }
        DeleteMsgPort(my_time_port_clock);
    }
    if(dftm.UseScreenNotify)
    {
        if((!were_on_public)|(!strcmp(&dftm.pubscreen_name[0],"Workbench")))
            while(!RemWorkbenchClient(my_handler)) Delay(10);
        else
            while(!RemCloseScreenClient(my_handler)) Delay(10);
        DeleteMsgPort(my_port);
    }
    if(my_test_port) DeletePort(my_test_port);
    if(ScreenNotifyBase) CloseLibrary( ScreenNotifyBase );
}

