#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/commodities.h>
#include <stdio.h>

#include <proto/exec.h>
#include <proto/commodities.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/gadtools.h>
#include <proto/dos.h>
#include <clib/alib_protos.h>

#include "/include/server.h"

#define MUST_RETRY 0
#define MUST_BLANK 1

extern struct List ClientsList;

extern UWORD fonth, wleft, wtop, DefaultClient, delaySecs, delayEvents;
extern UBYTE briLevel;
extern BOOL Blanking, RandomClient, CommodityActive, StayCool, BlankStatus;
extern struct Gadget *glist, *random_gdg, *modeid_gdg, *list_gdg;
extern CxObj *broker;

extern struct Screen *WBS;
extern struct VisualInfo *vi;
extern struct TextAttr topazFont;

extern BOOL SetUpGadgets(void);
extern void RemoveGadgets(void);

extern void AskFiles( void );

extern void ClearPendingMessages( struct MsgPort * );

extern void StartBlanking( void );
extern void RemoveClient( UWORD, char * );
extern void SendCommandToClient( ULONG );

extern void GetDisplayIDFromNode( UWORD );
extern struct ModeNode *DisplayNode;
extern ULONG DisplayID;

extern char *msg_timeout, *msg_random, *key_random,
     *msg_hide, *key_hide, *msg_quit, *key_quit, *msg_blank, *key_blank,
     *msg_killsel, *key_killsel, *msg_addcli, *key_addcli;

extern BOOL stop_on_mouse, stop_on_disk;

extern struct NewBroker newbroker;

 /***************
 *              *
 * WINDOW STUFF *
 *              *
 ***************/

struct NewMenu bservernewmenus[] = {
	{ NM_TITLE, NULL,         0, 0, 0, 0 },
	{ NM_ITEM,  NULL,         0, 0, 0, (APTR)MENUID_ABOUT },
	{ NM_ITEM,  NULL,         0, 0, 0, (APTR)MENUID_HIDE },
	{ NM_ITEM,  NULL,	      0, 0, 0, (APTR)MENUID_QUIT },
	{ NM_TITLE, NULL,         0, 0, 0, 0 },
	{ NM_ITEM,  NULL,         0, CHECKIT|MENUTOGGLE, 0, (APTR)MENUID_RAWMOUSE },
	{ NM_ITEM,  NULL,         0, CHECKIT|MENUTOGGLE, 0, (APTR)MENUID_DISK },
	{ NM_END,   NULL,         0, 0, 0, 0 } };

struct EasyStruct easyabout = {
	sizeof(struct EasyStruct), 0, "BServer", NULL, NULL };

struct Window *window;
char wname[100];
ULONG windowSignal = NULL;
UWORD wwidth, wheight;
struct Menu *bsmenus;
struct Screen *wbs;


void DetachGadgets( void )
{
GT_SetGadgetAttrs( list_gdg, window, NULL, GTLV_Labels, ~0, TAG_END );
}


void AttachGadgets( void )
{
GT_SetGadgetAttrs( list_gdg, window, NULL, GTLV_Labels, &ClientsList, GTLV_Selected, DefaultClient,	TAG_END );
}


BOOL PopUpWindow( void )
{
if ( window )
	{
	ActivateWindow( window );
	WindowToFront( window );
	return( TRUE );
	}

if ( wbs = LockPubScreen( NULL ) )
	{
	if ( SetUpGadgets() )
		{
		if ( window = OpenWindowTags( NULL,
						WA_Width, wwidth,
						WA_Height, wheight,
						WA_Left, wleft,
						WA_Top, wtop,
						WA_Gadgets, glist,
						WA_Title, wname,
						WA_ScreenTitle, newbroker.nb_Title,
						WA_IDCMP, IDCMP_VANILLAKEY | IDCMP_GADGETUP | IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | INTEGERIDCMP | LISTVIEWIDCMP | BUTTONIDCMP | CHECKBOXIDCMP,
						WA_Flags, WFLG_DEPTHGADGET | WFLG_DRAGBAR | WFLG_CLOSEGADGET | WFLG_ACTIVATE,
						TAG_END ) )
			{
			if ( bsmenus = CreateMenus( bservernewmenus, TAG_END ) )
				{
				if ( LayoutMenus( bsmenus, vi, TAG_END ) )
					{
					if ( SetMenuStrip( window, bsmenus ) )
						{
						GT_RefreshWindow( window, NULL );
						AttachGadgets();
						windowSignal = 1L << window->UserPort->mp_SigBit;
						return( TRUE );
						}
					}
				FreeMenus( bsmenus );
				}
			CloseWindow( window );
			}
		RemoveGadgets();
		}
	UnlockPubScreen( NULL, wbs );
	}
DisplayBeep( NULL );
return( FALSE );
}


void ShutWindow( void )
{
if ( window )
	{
	ClearMenuStrip( window );
	FreeMenus( bsmenus );
	ClearPendingMessages( window->UserPort );
	wleft = window->LeftEdge;
	wtop = window->TopEdge;
	CloseWindow( window );
	window = NULL;
	windowSignal = NULL;
	RemoveGadgets();
	UnlockPubScreen( NULL, wbs );
	}
}


void HandleWindowMessages( void )
{
struct IntuiMessage *imsg;
ULONG class;
UWORD code;
ULONG addr;
ULONG menuid;

while( window && StayCool && ( imsg = GT_GetIMsg( window->UserPort ) ) )
	{
	class = imsg->Class;
	code = imsg->Code;
	addr = (ULONG)imsg->IAddress;
	GT_ReplyIMsg( imsg );

	switch( class )
		{
		case IDCMP_MENUPICK:
			if ( code != MENUNULL )
				{
				menuid = (ULONG)GTMENUITEM_USERDATA( ItemAddress( bsmenus, code ) );
				switch ( menuid )
					{
					case MENUID_ABOUT:
						EasyRequestArgs( window, &easyabout, NULL, NULL );
						break;
					case MENUID_HIDE:
						ShutWindow();
						break;
					case MENUID_QUIT:
						StayCool = FALSE;
						break;
					case MENUID_RAWMOUSE:
						stop_on_mouse ^= TRUE;
						break;
					case MENUID_DISK:
						stop_on_disk ^= TRUE;
						break;
					}
				}
			break;

		case IDCMP_VANILLAKEY:
				code ^= 32;
				if ( code == *key_random )
					{
					RandomClient ^= TRUE;
					GT_SetGadgetAttrs( random_gdg, window, NULL, GTCB_Checked, RandomClient, TAG_END );
					}
				else if ( code == *key_hide )
					ShutWindow();
				else if ( code == *key_quit )
					StayCool = FALSE;
				else if ( code == *key_blank )
					{
					if ( CommodityActive && !Blanking && BlankStatus != MUST_BLANK )
						{
						Delay( 10 );
						BlankStatus = MUST_BLANK;
						StartBlanking();
						}
					}
				else if ( code == *key_addcli )
					AskFiles();
				else if ( code == *key_killsel )
					RemoveClient( DefaultClient, NULL );
			break;

		case IDCMP_REFRESHWINDOW:
			GT_BeginRefresh( window );
			GT_EndRefresh( window, TRUE );
			break;

		case IDCMP_CLOSEWINDOW:
			ShutWindow();
			break;

		case IDCMP_GADGETUP:
			switch( ((struct Gadget *)addr)->GadgetID )
				{
				case TIMEOUT_GDG:
					delaySecs = ((struct StringInfo *)((struct Gadget *)addr)->SpecialInfo)->LongInt;
					delayEvents = delaySecs * 10;
					break;
				case RANDOM_GDG:
					RandomClient ^= TRUE;
					break;
				case HIDE_GDG:
					ShutWindow();
					break;
				case QUIT_GDG:
					StayCool = FALSE;
					break;
				case BLANK_GDG:
					if ( CommodityActive && !Blanking && BlankStatus != MUST_BLANK )
						{
						Delay( 10 );
						BlankStatus = MUST_BLANK;
						StartBlanking();
						}
					break;
				case MODEID_GDG:
					GetDisplayIDFromNode( code );
					break;
				case ADDCLIENTS_GDG:
					AskFiles();
					break;
				case KILL_GDG:
					RemoveClient( DefaultClient, NULL );
					break;
				case LIST_GDG:
					DefaultClient = code;
					break;
				case BRILEVEL_GDG:
					briLevel = ((struct StringInfo *)((struct Gadget *)addr)->SpecialInfo)->LongInt;
					if ( briLevel < 0 || briLevel > 100 )
						{
						briLevel = 100;
						GT_SetGadgetAttrs( (struct Gadget *)addr, window, NULL, GTIN_Number, 100, TAG_END );
						}
					break;
				}

		default:
			break;
		}
	}
}
