#include <intuition/classusr.h>
#include <intuition/gadgetclass.h>
#include <intuition/cghooks.h>
#include <intuition/icclass.h>
#include <intuition/classes.h>
#include <utility/tagitem.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <dos/notify.h>
#include <intuition/intuition.h>
#include <libraries/SysInfo.h>
#include <utility/tagitem.h>
#include <clib/macros.h>
#include <libraries/commodities.h>
#include <libraries/ScreenNotify.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/datatypes.h>
#include <datatypes/pictureclass.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include "gaugeclass.h"
#include "launchclass.h"
#include "tinymeter.h"

#define test_test       0
#define test_getwin     1

#define do_clock        1
#define do_mem          2
#define do_vol          3

struct TestMessage
{
    struct  Message ts_Message;
    ULONG   MethodID;
    struct  tm_sys_set  *set;
    struct  tm_gau_set  *list;
    ULONG   posx,
	    posy,
	    sizx;
};

void init_time_request(struct timerequest *my_time_request_clock, ULONG my_time_mask_clock)
{
    ULONG interval;
    my_time_request_clock -> tr_node.io_Command     = TR_GETSYSTIME;
    DoIO((struct IORequest *)my_time_request_clock);
    interval=my_time_request_clock -> tr_time.tv_secs;
    my_time_request_clock -> tr_node.io_Command     = TR_ADDREQUEST;
    my_time_request_clock -> tr_time.tv_secs        = interval+1;
    my_time_request_clock -> tr_time.tv_micro       = NULL;
    SetSignal(NULL,my_time_mask_clock);
    SendIO((struct IORequest *)my_time_request_clock);
}

ULONG snapSub(struct tm_sys_set *set, struct tm_data *data)
{
    struct lau_enty         *list;
    int                     i;
    struct IntuiMessage     *m;

    while((m=(struct IntuiMessage *)GetMsg( data->win->UserPort ))) ReplyMsg( (struct Message *)m );
    data->win=(struct Window *) snapBackground(set,data);
				drawBackground(set,data);
    for(i=NULL;i<data->num_of_gaug;i++)
    {
	if(data->gdg[i])
	{
	    GetAttr(LAU_List,data->gdg[i],(ULONG *)&list);
	    if(list) AddGList(data->win,data->gdg[i],0,1,NULL);
	    else     AddGList(data->win,data->gdg[i],-1,1,NULL);
	    SetAttrs(data->gdg[i],GA_Width, data->gauge_x_size, NULL);
	}
    }
    RefreshGList(data->win->FirstGadget,data->win,NULL,-1);
    return((ULONG)1L << data->win->UserPort->mp_SigBit);
}

void setBase(struct tm_data *data)
{
    int                 i;
    ULONG               cur;
    for(i=NULL;i<data->num_of_gaug;i++)
    {
	if(data->gdg[i])
	{
	    GetAttr(GAU_Current,data->gdg[i],&cur);
	    SetAttrs(data->gdg[i],GAU_Current,cur,GAU_Base,cur,TAG_DONE);
	}
    }
    RefreshGList(data->win->FirstGadget,data->win,NULL,-1);
}

void handle_launcher(struct tm_data *data, WORD ID, struct Gadget *obj,struct WBArg *wbarg, ULONG numarg)
{
    struct  Window          *lwin;
    struct  RastPort        *rp,
			    tmpras;
    BOOL                    foo=TRUE,
			    start=FALSE;
    struct  lau_entry       *entry,
			    *foobar;
    LONG                    dummy,
			    height,
			    width;
    LONG                    x,
			    y,
			    selected,
			    sigs,
			    lastsel;
    ULONG                   pen_bg,
			    pen_bright,
			    pen_dark,
			    pen_cur,
			    pen_entry,
			    window_mask,
			    lwindow_mask,
			    down,trans;
    UWORD                   entryheight,
			    iw=NULL,
			    y_pos;
    struct IntuiMessage     *m;
    struct BitMapHeader     *bmhd;
    struct MsgPort          *appport;
    struct AppWindow        *appwin;
    ULONG                    appwinsig;

    GetAttr(LAU_ColEntry     ,obj,(ULONG *)&pen_entry);
    GetAttr(LAU_ColBrightEdg ,obj,(ULONG *)&pen_bright);
    GetAttr(LAU_ColDarkEdg   ,obj,(ULONG *)&pen_dark);
    GetAttr(LAU_ColBackground,obj,(ULONG *)&pen_bg);
    GetAttr(LAU_ColCursor    ,obj,(ULONG *)&pen_cur);
    GetAttr(LAU_List         ,obj,(ULONG *)&entry);
    GetAttr(LAU_Down         ,obj,(ULONG *)&down);
    GetAttr(LAU_Transparent  ,obj,(ULONG *)&trans);
    if((foobar=entry)&&(ID>-1))
    {
	InitRastPort(&tmpras);
	SetFont(&tmpras,data->Font[ID]);
	dummy=NULL;
	entryheight=data->Font[ID]->tf_YSize;
	width=data->gdg[ID]->Width+2;
	do
	{
	    if(foobar->img)
	    {
		GetDTAttrs(foobar->img,PDTA_BitMapHeader,(ULONG *)&bmhd,TAG_DONE);
		if(bmhd)
		{
		    entryheight=MAX(entryheight,bmhd->bmh_Height+2);
		    iw=MAX(iw,bmhd->bmh_Width+6);
		}
	    }
	    foobar->width=TextLength(&tmpras,foobar->lau_lbl,my_strlen(foobar->lau_lbl));
	    width=MAX(width,foobar->width+12+iw);
	    dummy++;
	}
	while(foobar=foobar->next);

	y_pos=((entryheight-((data->Font[ID]->tf_Baseline+data->Font[ID]->tf_YSize)>>1))>>1);
	if(data->Font[ID]->tf_Baseline<data->Font[ID]->tf_YSize)
	{
	    y_pos+=data->Font[ID]->tf_Baseline-1;
	    if(y_pos<data->Font[ID]->tf_Baseline)y_pos=data->Font[ID]->tf_Baseline;
	}
	else
	{
	    y_pos+=data->Font[ID]->tf_YSize-1;
	    if(y_pos<data->Font[ID]->tf_YSize)   y_pos=data->Font[ID]->tf_YSize;
	}

	height=(entryheight*dummy)+2;
	y=data->gdg[ID]->TopEdge+data->win->TopEdge-( down==lau_up ? height : ( down== lau_down ? -data->gdg[ID]->Height : height>>1 ));
	if((lwin=(struct Window *)OpenWindowTags(NULL,
	    WA_Left,            data->gdg[ID]->LeftEdge+data->win->LeftEdge-1,
	    WA_Top,             y,
	    WA_Width,           width,
	    WA_Height,          height,
	    WA_Flags,           WFLG_BORDERLESS|WFLG_REPORTMOUSE|WFLG_RMBTRAP|WFLG_ACTIVATE,
	    WA_PubScreen,       data->scr,
	    WA_IDCMP,           IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE,
	    TAG_END)))
	{
	    if(appport=(struct MsgPort *)CreateMsgPort())
	    {
		appwin=(struct AppWindow *)AddAppWindow(0L, 0L, lwin, appport , 0L);
		appwinsig= 1L << appport->mp_SigBit;
	    }
	    selected     =-1;
	    lastsel      =-1;
	    window_mask  = 1L << data->win->UserPort->mp_SigBit;
	    lwindow_mask = 1L << lwin->UserPort->mp_SigBit;

	    SetFont(rp=lwin->RPort,data->Font[ID]);
	    SetAPen(rp,pen_bg); RectFill(rp,0,0,width-1,height-1);
	    draw_border_new(rp,0,0,width,height,pen_bright,pen_dark);
	    SetAPen(rp,pen_entry);
	    SetDrMd(rp,JAM1);
	    foobar=entry;
	    dummy=0;
	    do
	    {
		if(foobar->img)
		{
		    GetDTAttrs(foobar->img,PDTA_BitMapHeader,&bmhd,TAG_DONE);
		    DrawDTObject(foobar->img,0,0,rp,2+((iw-bmhd->bmh_Width)>>1),(dummy*entryheight)+1+((entryheight-bmhd->bmh_Height)>>1),-1,-1,trans);
		}
		Move(rp,iw+7,((dummy++)*entryheight)+y_pos+1);
		Text(rp,foobar->lau_lbl,my_strlen(foobar->lau_lbl));
	    }
	    while(foobar=foobar->next);
	    while(foo)
	    {
		sigs=Wait( window_mask | lwindow_mask | appwinsig );
		if(sigs & appwinsig)
		{
		    struct AppMessage *apm;
		    while(apm=(struct AppMessage *)GetMsg(appport))
		    {
			selected=(apm->am_MouseY-1)/entryheight;
			for(foobar=entry,dummy=0;dummy<selected;dummy++)foobar=foobar->next;
			if(apm->am_Type==AMTYPE_APPWINDOW)
			{
			    RunFile(foobar,data,apm->am_ArgList,apm->am_NumArgs);
			}
			ReplyMsg((struct Message *)apm);
		    }
		}
		if(sigs & window_mask)
		{
		    while(m=(struct IntuiMessage *)GetMsg(data->win->UserPort))
		    {
			switch (m->Class)
			{
			    case    IDCMP_GADGETDOWN:
				    foo=FALSE;
				    break;
			}
			ReplyMsg((struct Message *)m);
		    }
		}
		if(sigs & lwindow_mask)
		{
		    while(m=(struct IntuiMessage *)GetMsg(lwin->UserPort))
		    {
			switch (m->Class)
			{
			    case    IDCMP_MOUSEBUTTONS:
				    if((m->Code&15)==8)
				    {
					selected=(m->MouseY-1)/entryheight;
					foo=FALSE;
					start=TRUE;
				    }
				    break;
			    case    IDCMP_MOUSEMOVE:
				    x=m->MouseX;
				    y=m->MouseY;
				    if((x>0)&&(y>0)&&(x<(width-1))&&(y<(height-1)))
				    {
					selected=(y-1)/entryheight;
					if(selected!=lastsel)
					{
					    if(lastsel!=-1)
					    {
						SetAPen(rp,pen_bg);
						RectFill(rp,iw+3,1+(lastsel*entryheight),width-4,((lastsel+1)*entryheight));
						SetAPen(rp,pen_entry);
						for(foobar=entry,dummy=0;dummy<lastsel;dummy++)foobar=foobar->next;
						Move(rp,iw+7,(lastsel*entryheight)+y_pos+1);
						Text(rp,foobar->lau_lbl,my_strlen(foobar->lau_lbl));
					    }
					    SetAPen(rp,pen_cur);
					    RectFill(rp,iw+3,1+(selected*entryheight),width-4,((selected+1)*entryheight));
					    SetAPen(rp,pen_entry);
					    for(foobar=entry,dummy=0;dummy<selected;dummy++)foobar=foobar->next;
					    Move(rp,iw+7,(selected*entryheight)+y_pos+1);
					    Text(rp,foobar->lau_lbl,my_strlen(foobar->lau_lbl));
					}
					lastsel=selected;
				    }
				    else
				    {
					if(lastsel!=-1)
					{
					    SetAPen(rp,pen_bg);
					    RectFill(rp,iw+1,1+(lastsel*entryheight),width-2,((lastsel+1)*entryheight));
					    SetAPen(rp,pen_entry);
					    for(foobar=entry,dummy=0;dummy<lastsel;dummy++)foobar=foobar->next;
					    Move(rp,iw+7,(lastsel*entryheight)+y_pos+1);
					    Text(rp,foobar->lau_lbl,my_strlen(foobar->lau_lbl));
					}
					selected=-1;
					lastsel=-1;
				    }
				    break;
			}
			ReplyMsg((struct Message *)m);
		    }
		}
	    }
	    while(m=(struct IntuiMessage *)GetMsg(data->win->UserPort))ReplyMsg((struct Message *)m);
	    while(m=(struct IntuiMessage *)GetMsg(lwin->UserPort))     ReplyMsg((struct Message *)m);

	    if(appwin)  RemoveAppWindow(appwin);
	    if(appport) DeletePort(appport);

	    CloseWindow(lwin);
	    if(start&&(selected>-1))
	    {
		for(foobar=entry,dummy=0;dummy<selected;dummy++)foobar=foobar->next;
		RunFile(foobar,data,wbarg,numarg);
	    }
	}
	else DisplayBeep(0);
    }
}

struct tm_sys_set *handler(struct tm_sys_set *set, struct tm_data *data, struct MsgPort *broker_mp, CxObj *broker, ULONG cxsigflag, Class *gclass, Class *lclass)
{
    BOOL                        running = TRUE;

    ULONG                       mem_val=0,
				vol_val=0,
				sigs,
				window_mask,
				my_time_mask_clock,
				my_test_port_mask,
				my_noti_port_mask=0L,
				my_app_port_mask =0L,
				my_handler;

    struct MsgPort             *my_time_port_clock,
			       *my_test_port,
			       *my_noti_port;

    struct timerequest         *my_time_request_clock;

    struct NotifyRequest       *notifyrequest;
    LONG                        not_sig;
    BOOL                        closed=FALSE;

    struct IntuiMessage        *m;
    int                         i;
    struct TestMessage         *test_msg;
    struct tm_gau_set          *many,*next;
    BOOL                        first_run=TRUE,doit;
    UWORD                       do_what;

    if(data->scrnot)
    {
	my_noti_port        = (struct MsgPort *)CreateMsgPort();
	my_handler          = ((!data->on_public)|(!strcmp(&set->pub_name[0],"Workbench"))) ? (ULONG)AddWorkbenchClient(my_noti_port,0) : (ULONG)AddCloseScreenClient(data->scr,my_noti_port,0);
	my_noti_port_mask   = 1L << my_noti_port->mp_SigBit;
    }

    if(data->appwin) my_app_port_mask    = 1L << data->appport->mp_SigBit;

    window_mask  = 1L << data->win->UserPort->mp_SigBit;

    if(my_test_port=(struct MsgPort *)CreatePort("TinyMeter",0))
    {
	my_test_port_mask = 1L << (my_test_port->mp_SigBit);
	if(my_time_port_clock=(struct MsgPort *)CreateMsgPort())
	{
	    my_time_mask_clock    = 1L << (my_time_port_clock->mp_SigBit);
	    if(my_time_request_clock = (struct timerequest *)CreateIORequest(my_time_port_clock,sizeof(struct timerequest)))
	    {
		if(!OpenDevice("timer.device",UNIT_WAITUNTIL,(struct IORequest *)my_time_request_clock,NULL))
		{
		    if(notifyrequest = (struct NotifyRequest *)pAllocVec(sizeof(struct NotifyRequest)))
		    {
			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)
			    {
				init_time_request(my_time_request_clock,my_time_mask_clock);
				while(running)
				{
				    sigs = Wait( my_noti_port_mask | my_test_port_mask | window_mask | my_time_mask_clock | (1L << not_sig) | cxsigflag | my_app_port_mask );
				    if(!closed)
				    {
					if (sigs & my_time_mask_clock)
					{
					    WaitIO((struct IORequest *)my_time_request_clock);
					    init_time_request(my_time_request_clock,my_time_mask_clock);
					    do_what=do_clock;
					    mem_val++;
					    if(mem_val>=set->mem_refresh)
					    {
						mem_val=0;
						do_what=do_mem;
					    }
					    vol_val++;
					    if(vol_val>=set->vol_refresh)
					    {
						vol_val=0;
						do_what=do_vol;
					    }
					    for(i=0,many=data->list;i<data->num_of_gaug;i++,many=many->next)
					    {
						doit=FALSE;
						if(data->gdg[i])                                     
						switch (do_what)
						{
						    case    do_vol:
							    if(many->type==typ_volume) { doit=TRUE; break; }
						    case    do_mem:
							    if((many->type!=typ_none)&&(many->type!=typ_iconlauncher)&&(many->type!=typ_simplelauncher)&&(many->type!=typ_volume)) { doit=TRUE; break; }
						    default:
							    if(many->type==typ_clock_) doit=TRUE;
							    break;
						}                                                                
						if(doit) DoMethod((Object *)data->gdg[i],MY_REFRESH,data->win,NULL);
					    }
					    if(first_run){setBase(data);first_run=FALSE;}
					    if(set->win_backfront==win_front) if(data->win->WLayer!=data->scr->LayerInfo.top_layer) WindowToFront(data->win);
					}
					if (sigs & my_app_port_mask)
					{
					    struct AppMessage *appmsg;
					    while(appmsg=(struct AppMessage *)GetMsg( data->appport))
					    {
						if(appmsg->am_Type=AMTYPE_APPWINDOW)
						{
						    for(i=0,many=data->list;i<data->num_of_gaug;i++,many=many->next)
						    {
							if((many->type==typ_simplelauncher)||(many->type==typ_iconlauncher))
							if(data->gdg[i])
							{
							    if((data->gdg[i]->TopEdge <appmsg->am_MouseY)&&((data->gdg[i]->TopEdge +data->gdg[i]->Height)>appmsg->am_MouseY)&&
							       (data->gdg[i]->LeftEdge<appmsg->am_MouseX)&&((data->gdg[i]->LeftEdge+data->gdg[i]->Width) >appmsg->am_MouseX)
							    )
							    {
								if(data->gdg[i]->GadgetID<0xFFF0)
								{
								    struct lau_entry    *entry;
								    GetAttr(LAU_List,(Object *)data->gdg[i],(ULONG *)&entry);
								    if(many->type==typ_simplelauncher)
								    {
									if(entry->next) handle_launcher (data,(UWORD)data->gdg[i]->GadgetID,(struct Gadget *)data->gdg[i],appmsg->am_ArgList,appmsg->am_NumArgs);
									else            RunFile         (entry,data,appmsg->am_ArgList,appmsg->am_NumArgs);
								    }
								    else
								    {
									ULONG               fullness;
									struct BitMapHeader *bmhd;
									WORD                x=appmsg->am_MouseX-data->gdg[i]->LeftEdge;
									GetAttr(LAU_XPos,(Object *)data->gdg[i],&fullness);
									if(entry)
									{
									    do
									    {
										if(entry->img)
										{
										    GetDTAttrs(entry->img,PDTA_BitMapHeader,&bmhd,TAG_DONE);
										    if(bmhd)
										    {
											if(((fullness+bmhd->bmh_Width)>x)&&(fullness<x)) break;
											fullness+=bmhd->bmh_Width;
										    }
										}
									    }
									    while(entry=entry->next);
									    RunFile(entry,data,appmsg->am_ArgList,appmsg->am_NumArgs);
									}
								    }
								}
							    }
							}
						    }
						}
						ReplyMsg((struct Message *)appmsg);
					    }
					}
					if (sigs & window_mask)
					{
					    while(m=(struct IntuiMessage *)GetMsg( data->win->UserPort ))
					    {
						switch ( m->Class )
						{
						    case    IDCMP_GADGETDOWN:
							    {
								WORD    x;
								struct Gadget *g=((struct Gadget *)(m->IAddress));
								x=m->MouseX-g->LeftEdge;
								ReplyMsg((struct Message *)m);
								if(g->GadgetID<0xFFF0)
								{
								    struct lau_entry    *entry;
								    ULONG               type;
								    GetAttr(LAU_List,(Object *)g,(ULONG *)&entry);
								    GetAttr(LAU_Type,g,&type);
								    if(type==typ_iconlauncher)
								    {
									ULONG   fullness;
									struct  BitMapHeader *bmhd;
									GetAttr(LAU_XPos,(Object *)g,&fullness);
									if(entry)
									{
									    do
									    {
										if(entry->img)
										{
										    GetDTAttrs(entry->img,PDTA_BitMapHeader,&bmhd,TAG_DONE);
										    if(bmhd)
										    {
											if((x<(fullness+bmhd->bmh_Width))&&(x>fullness)) break;
											fullness+=bmhd->bmh_Width;
										    }
										}
									    }
									    while(entry=entry->next);
									    RunFile(entry,data,NULL,NULL);
									}
								    }
								    else if(entry->next)  handle_launcher(data,(UWORD)g->GadgetID,(struct Gadget *)g,NULL,NULL);
								    else                  RunFile(entry,data,NULL,NULL);
								}
							    }
							    break;
						    case    IDCMP_CHANGEWINDOW:
							    ReplyMsg((struct Message *)m);
							    if(set->bg_type==bg_snap) window_mask=snapSub(set,data);
							    break;
						    case    IDCMP_CLOSEWINDOW:
							    running=FALSE;
							    ReplyMsg((struct Message *)m);
							    break;
						    case    IDCMP_NEWSIZE:
							    ReplyMsg((struct Message *)m);
							    new_window_size(set,data);
							    set->x_siz=data->win->Width;
							    data->gauge_x_size=(set->x_siz-(set->win_border_x<<1)-((set->colums-1)*set->win_space_x))/set->colums;
							    if(set->bg_type==bg_file) fileBackground(set,data);
							    drawBackground(set,data);
							    for(i=0;i<data->num_of_gaug;i++) if(data->gdg[i]) SetAttrs(data->gdg[i],GA_Left,set->win_border_x+((i)%set->colums)*data->gauge_x_size+((i)%set->colums)*set->win_space_x,GA_Width,data->gauge_x_size,TAG_DONE);
							    if(set->bg_type!=bg_snap)RefreshGList(data->win->FirstGadget,data->win,NULL,-1);
							    if(set->bg_type==bg_snap)window_mask=snapSub(set,data);
							    break;
						    case    IDCMP_VANILLAKEY:
							    {
								int Code=m->Code;
								ReplyMsg((struct Message *)m);
								switch(Code)
								{
								    case    'S':
								    case    's':
									    {
										BPTR my_file,my_file1;
										set->x_pos=data->win->LeftEdge;
										set->y_pos=data->win->TopEdge;
										set->x_siz=data->win->Width;
										my_file= (BPTR)Open("ENV:TinyMeter",   MODE_NEWFILE);
										my_file1=(BPTR)Open("ENVARC:TinyMeter",MODE_NEWFILE);
										if(my_file) Write(my_file, set,(ULONG) sizeof(struct tm_sys_set));
										if(my_file1)Write(my_file1,set,(ULONG) sizeof(struct tm_sys_set));
										many=data->list;
										for(i=0;i<data->num_of_gaug;i++)
										{
										    if(my_file) Write(my_file, many,(ULONG) sizeof(struct tm_gau_set));
										    if(my_file1)Write(my_file1,many,(ULONG) sizeof(struct tm_gau_set));
										    many=many->next;
										}
										if(my_file) Close(my_file1);
										if(my_file1)Close(my_file);
									    }
									    break;
								    case    'F':
								    case    'f':
									    {
										void *my_mem;
										Forbid();
										my_mem=AllocVec(2000000000L,MEMF_PUBLIC);
										if(my_mem)FreeVec((APTR)my_mem);
										Permit();
									    }
									    break;
								    case    'Q':
								    case    'q':
									    running=FALSE;
									    break;
								    case    'b':
								    case    'B':
									    if(set->bg_type==bg_snap)window_mask=snapSub(set,data);
									    break;
								}
							    }
							    break;
						    case    IDCMP_MOUSEBUTTONS:
							    if((m->Code&129)==1) setBase(data);
						    default :
							    ReplyMsg((struct Message *)m);
							    break;
						}
					    }
					}
					if (sigs & (1L << not_sig))
					{
					    Delay(100L);
					    if(set->bg_type==bg_snap) window_mask=snapSub(set,data);
					}
				    }
				    else if (sigs & my_time_mask_clock) init_time_request(my_time_request_clock,my_time_mask_clock);

				    if (sigs & cxsigflag)
				    {
					CxMsg *msg;
					ULONG msgid, msgtype;

					while(msg = (CxMsg *)GetMsg(broker_mp))
					{
					    msgid   = CxMsgID(msg);
					    msgtype = CxMsgType(msg);
					    ReplyMsg((struct Message *)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_KILL:
							    running=FALSE;
						    case    CXCMD_ENABLE:
							    ActivateCxObj(broker, 1L);
						    default:
							    break;
						}
					    }
					}
				    }
				    if ((sigs & my_test_port_mask)&&(!closed))
				    {
					while(test_msg=(struct TestMessage *)GetMsg(my_test_port))
					{
					    switch (test_msg->MethodID)
					    {
						case    test_test:
							if(test_msg->set && test_msg->list)
							{
							    struct tm_gau_set *manyn,*nextn;
							    closeWindow(set,data);
							    first_run=TRUE;
							    pFreeVec((ULONG *)set);
							    many=data->list;
							    do
							    {
								next=many->next;
								pFreeVec((ULONG *)many);
							    }
							    while(many=next);

							    if(set=(struct tm_sys_set *)pAllocVec(sizeof(struct tm_sys_set)))
							    {
								CopyMem(test_msg->set,set,sizeof(struct tm_sys_set));
							    }
							    else running=FALSE;

							    data->num_of_gaug   = getNum(test_msg->list);
							    many                = test_msg->list;
							    if(!(nextn=(struct tm_gau_set *)pAllocVec(sizeof(struct tm_gau_set)))){return(set);}
							    data->list          = nextn;

							    for(i=0;i<data->num_of_gaug;i++)
							    {
								manyn=nextn;
								if(!(nextn=(struct tm_gau_set *)pAllocVec(sizeof(struct tm_gau_set)))){return(set);}
								CopyMem(many,manyn,sizeof(struct tm_gau_set));
								manyn->next=nextn;
								many=many->next;
							    }
							    pFreeVec((ULONG *)nextn);
							    manyn->next=NULL;
							    if(openWindow(set,data,gclass,lclass))
							    {
								window_mask  = 1L << data->win->UserPort->mp_SigBit;
							    }
							    else return(set);
							    setBase(data);
							}
							break;
						case    test_getwin:
							test_msg->posx=data->win->LeftEdge;
							test_msg->posy=data->win->TopEdge;
							test_msg->sizx=data->win->Width;
							break;
					    }
					    ReplyMsg((struct Message *)test_msg);
					}
				    }
				    if(data->scrnot)
				    {
					if (sigs & my_noti_port_mask)
					{
					    struct ScreenNotifyMessage  *snm;
					    while(snm = (struct ScreenNotifyMessage *) GetMsg(my_noti_port))
					    {
						switch(snm->snm_Type)
						{
						    case    SCREENNOTIFY_TYPE_CLOSESCREEN:
							    running=FALSE;
							    break;
						    case    SCREENNOTIFY_TYPE_WORKBENCH:
							    if((ULONG)snm->snm_Value)
							    {
								if(closed)
								{
								    Delay(50L);
								    if(openWindow(set,data,gclass,lclass))
								    {
									window_mask  = 1L << data->win->UserPort->mp_SigBit;
									closed=FALSE;
								    }
								    else running=FALSE;
								    setBase(data);
								}
							    }
							    else
							    {
								if(!closed)
								{
								    closeWindow(set,data);
								    closed=TRUE;
								}
								first_run=TRUE;
							    }
							    break;
						}
						ReplyMsg((struct Message *) snm);
					    }
					}
				    }
				}
				EndNotify(notifyrequest);
			    }
			    else show(err_nosta);
			    FreeSignal(not_sig);
			}
			else show(err_nosta);
			pFreeVec((ULONG *)notifyrequest);
		    }
		    else show(err_nomem);
		    if(!CheckIO((struct IORequest *)my_time_request_clock))
			AbortIO((struct IORequest *)my_time_request_clock);
		    WaitIO((struct IORequest *)my_time_request_clock);
		    CloseDevice((struct IORequest *)my_time_request_clock);
		}
		else show(err_nodev);
		DeleteIORequest((struct IORequest *)my_time_request_clock);
	    }
	    else show(err_nopor);
	    DeleteMsgPort((struct MsgPort *)my_time_port_clock);
	}
	else show(err_nopor);
	DeletePort(my_test_port);
    }
    else show(err_nopor);
    if(data->scrnot)
    {
	if((!data->on_public)|(!strcmp(&set->pub_name[0],"Workbench")))
	    while(!RemWorkbenchClient((APTR)my_handler)) Delay(10);
	else
	    while(!RemCloseScreenClient((APTR)my_handler)) Delay(10);
	DeleteMsgPort(my_noti_port);
    }
    return(set);
}

