#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>
#include <libraries/commodities.h>
#include <string.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"

extern struct List ClientsList;

extern UWORD fonth, wleft, wtop, DefaultClient, TotalClients, delaySecs, delayEvents, changeSecs, changeEvents;
extern UBYTE briLevel, sndLevel, BlankStatus;
extern BOOL RandomClient, CommodityActive, StayCool;
extern struct Gadget *glist, *random_gdg, *list_gdg, *args_gdg, *time_gdg, *tchange_gdg, *bri_gdg, *snd_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 Quit( void );

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

extern char *msg_timeout, *key_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,
     *key_changetime, *key_brilevel, *key_sndlevel;

extern BOOL stop_on_mouse, stop_on_disk;

extern UWORD zoomdims[4];

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;
UWORD wwidth, wheight;
ULONG windowSignal = NULL;
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 );
GT_SetGadgetAttrs( args_gdg, window, NULL, GTST_String, FindClientNode( DefaultClient )->cn_ClientArgs, 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, PROGRAMNAME" "PROGRAMVERSION,
			WA_ScreenTitle, newbroker.nb_Title,
			WA_IDCMP, IDCMP_CHANGEWINDOW /*| IDCMP_NEWSIZE*/ | IDCMP_VANILLAKEY | IDCMP_RAWKEY | IDCMP_GADGETUP | IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | INTEGERIDCMP | LISTVIEWIDCMP | BUTTONIDCMP | CHECKBOXIDCMP,
			WA_Flags, WFLG_DEPTHGADGET | WFLG_DRAGBAR | WFLG_CLOSEGADGET | WFLG_ACTIVATE,
			WA_Zoom, zoomdims,
			TAG_END ) )
			{
			if ( bsmenus = CreateMenus( bservernewmenus, TAG_END ) )
				{
				if ( LayoutMenus( bsmenus, vi, TAG_END ) )
					{
					if ( SetMenuStrip( window, bsmenus ) )
						{
						GT_RefreshWindow( window, NULL );
						windowSignal = 1L << window->UserPort->mp_SigBit;
						ScreenToFront( wbs );
						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;
struct MenuItem *item;
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_CHANGEWINDOW:
			GT_BeginRefresh( window );
			GT_EndRefresh( window, TRUE );
			break;

		case IDCMP_MENUPICK:
			while ( window && StayCool && code != MENUNULL )
				{
				item = ItemAddress( bsmenus, code );
				menuid = (ULONG)GTMENUITEM_USERDATA( ItemAddress( bsmenus, code ) );
				switch ( menuid )
					{
					case MENUID_ABOUT:
						if ( IntuitionBase->LibNode.lib_Version >= 39 )
							SetWindowPointer( window, WA_BusyPointer, TRUE, TAG_END );
						EasyRequestArgs( window, &easyabout, NULL, NULL );
						if ( IntuitionBase->LibNode.lib_Version >= 39 )
							SetWindowPointer( window, TAG_END );
						break;
					case MENUID_HIDE:
						ShutWindow();
						break;
					case MENUID_QUIT:
						Quit();
						break;
					case MENUID_RAWMOUSE:
						stop_on_mouse = item->Flags & CHECKED ? TRUE : FALSE;
						break;
					case MENUID_DISK:
						stop_on_disk = item->Flags & CHECKED ? TRUE : FALSE;
						break;
					}
				code = item->NextSelect;
				}
			break;

		case IDCMP_RAWKEY:
				if ( code == 77 )
					{
					if ( DefaultClient < TotalClients )
						{
						DefaultClient++;
						GT_SetGadgetAttrs( args_gdg, window, NULL, GTST_String, FindClientNode( DefaultClient )->cn_ClientArgs, TAG_END );
						GT_SetGadgetAttrs( list_gdg, window, NULL, GTLV_Selected, DefaultClient, GTLV_Top, DefaultClient, TAG_END );
						}
					}
				else if ( code == 76 )
					{
					if ( DefaultClient > 0 )
						{
						DefaultClient--;
						GT_SetGadgetAttrs( args_gdg, window, NULL, GTST_String, FindClientNode( DefaultClient )->cn_ClientArgs, TAG_END );
						GT_SetGadgetAttrs( list_gdg, window, NULL, GTLV_Selected, DefaultClient, GTLV_Top, DefaultClient, TAG_END );
						}
					}
				break;

		case IDCMP_VANILLAKEY:
				code ^= 32;
				if ( code == *key_timeout )
					ActivateGadget( time_gdg, window, NULL );
				else if ( code == *key_changetime )
					ActivateGadget( tchange_gdg, window, NULL );
				else if ( code == *key_brilevel )
					ActivateGadget( bri_gdg, window, NULL );
				else if ( code == *key_sndlevel )
					ActivateGadget( snd_gdg, window, NULL );
				else 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 )
					Quit();
				else if ( code == *key_blank )
					{
					if ( CommodityActive && BlankStatus == IDLE )
						{
						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;
					if ( (WORD)delaySecs < 0 )
						{
						delaySecs = 60;
						GT_SetGadgetAttrs( (struct Gadget *)addr, window, NULL, GTIN_Number, 60, TAG_END );
						}
					delayEvents = delaySecs * 10;
					break;
				case CHANGETIME_GDG:
					changeSecs = ((struct StringInfo *)((struct Gadget *)addr)->SpecialInfo)->LongInt;
					if ( (WORD)changeSecs < 0 )
						{
						changeSecs = 0;
						GT_SetGadgetAttrs( (struct Gadget *)addr, window, NULL, GTIN_Number, 0, TAG_END );
						}
					changeEvents = changeSecs * 10;
					break;
				case RANDOM_GDG:
					GT_SetGadgetAttrs( tchange_gdg, window, NULL, GA_Disabled, RandomClient, TAG_END );
					RandomClient ^= TRUE;
					break;
				case HIDE_GDG:
					ShutWindow();
					break;
				case QUIT_GDG:
					Quit();
					break;
				case BLANK_GDG:
					if ( CommodityActive && BlankStatus == IDLE )
						{
						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 CLIENTARGS_GDG:
					strcpy( FindClientNode( DefaultClient )->cn_ClientArgs, ((struct StringInfo *)args_gdg->SpecialInfo)->Buffer );
					break;
				case LIST_GDG:
					DefaultClient = code;
					GT_SetGadgetAttrs( args_gdg, window, NULL, GTST_String, FindClientNode( DefaultClient )->cn_ClientArgs, TAG_END );
					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;
				case SNDLEVEL_GDG:
					sndLevel = ((struct StringInfo *)((struct Gadget *)addr)->SpecialInfo)->LongInt;
					if ( sndLevel < 0 || sndLevel > 100 )
						{
						sndLevel = 100;
						GT_SetGadgetAttrs( (struct Gadget *)addr, window, NULL, GTIN_Number, 100, TAG_END );
						}
					break;
				}

		default:
			break;
		}
	}
}
