/*
**	ScreenPanel.c
**
**	Editing panel for screen configuration
**
**	Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
**		All Rights Reserved
*/

#include "termGlobal.h"

enum	{	GAD_MODES,GAD_MODE,GAD_NEWMODE,GAD_COLOUR,GAD_PALETTE,GAD_RED,GAD_GREEN,GAD_BLUE,GAD_STANDARD,
		GAD_CURRENTFONT,GAD_NEWFONT,GAD_MAKEPUBLIC,GAD_SHANGHAI,GAD_BLINKING,GAD_FASTER_LAYOUT,
		GAD_TITLEBAR,GAD_STATUS_LINE,GAD_USE,GAD_CANCEL };

struct ModeNode
{
	struct Node	VanillaNode;
	ULONG		DisplayID;
};

STATIC STRPTR	StatusType[4],
		ColourType[5];

STATIC struct List	ModeList;
STATIC BYTE		ModeLimited;

#ifdef ASLSM_FilterFunc

STATIC ULONG __saveds __asm
ModeFilter(register __a1 ULONG ID)
{
	struct DimensionInfo DimensionInfo;

	if(GetDisplayInfoData(NULL,(APTR)&DimensionInfo,sizeof(struct DimensionInfo),DTAG_DIMS,ID))
	{
		if(DimensionInfo . TxtOScan . MaxX - DimensionInfo . TxtOScan . MinX + 1 >= 640)
		{
			if(ModeLimited)
				return((ULONG)ModeOkay(ID));
			else
				return(TRUE);
		}
	}

	return(FALSE);
}

STATIC BYTE __regargs
SelectDisplayMode(struct Window *Window,ULONG *Mode)
{
	struct ScreenModeRequester	*Request;
	struct Hook			 FilterHook;
	BYTE				 Result = FALSE;

	FilterHook . h_Entry	= ModeFilter;
	FilterHook . h_SubEntry	= NULL;
	FilterHook . h_Data	= NULL;

	if(Request = (struct ScreenModeRequester *)AllocAslRequestTags(ASL_ScreenModeRequest,
		ASLSM_Window,		Window,
		ASLSM_InitialDisplayID,	*Mode,
		ASLSM_FilterFunc,	&FilterHook,
		ASLSM_PrivateIDCMP,	TRUE,
	TAG_DONE))
	{
		if(AslRequestTags(Request,TAG_DONE))
		{
			*Mode = Request -> sm_DisplayID;

			Result = TRUE;
		}

		FreeAslRequest(Request);
	}

	return(Result);
}

#endif	/* ASLSM_FilterFunc */

STATIC struct Gadget *
CreateAllGadgets(LONG *NumModes,struct Configuration *LocalConfig,struct Gadget **GadgetArray,struct Gadget **GadgetList,BYTE WrongMode)
{
	struct Gadget		*Gadget;
	struct NewGadget	 NewGadget;
	UWORD			 Counter = 0;
	LONG			 Mode;

	LocalizeString(StatusType,MSG_SCREENPANEL_STATUS_DISABLED_TXT,MSG_SCREENPANEL_STATUS_COMPACT_TXT);
	LocalizeString(ColourType,MSG_SCREENPANEL_COLOUR_AMIGA_TXT,MSG_SCREENPANEL_COLOUR_MONO_TXT);

	SZ_SizeSetup(Screen,&UserFont,TRUE);

	memset(&NewGadget,0,sizeof(struct NewGadget));

	if(Gadget = CreateContext(GadgetList))
	{
		NewList(&ModeList);

		if(LocalConfig -> ScreenConfig . ColourMode == COLOUR_EIGHT || LocalConfig -> ScreenConfig . ColourMode == COLOUR_SIXTEEN)
			ModeLimited = TRUE;
		else
			ModeLimited = FALSE;

		SZ_ResetMaxWidth();

		SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_SELECT_NEW_DISPLAY_MODE_TXT),0,NULL);
		SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_SCREENPANEL_USE_DEFAULT_TXT),0,NULL);
		SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_SCREENPANEL_SELECT_NEW_FONT_TXT),0,NULL);
		SZ_UpdateMaxWidth(CYCLE_KIND,NULL,0,ColourType);

#ifdef ASLSM_FilterFunc
		if(AslBase -> lib_Version < 38)
#endif	/* ASLSM_FilterFunc */
		{
			ULONG			 SomeMode = INVALID_ID;
			struct DisplayInfo	 DisplayInfo;
			LONG			 Len,Max = 0;

			*NumModes = Mode = 0;

			while((SomeMode = NextDisplayInfo(SomeMode)) != INVALID_ID)
			{
				if(ModeLimited)
				{
					if(!ModeOkay(SomeMode))
						continue;
				}

				if(GetDisplayInfoData(NULL,(APTR)&DisplayInfo,sizeof(struct DisplayInfo),DTAG_DISP,SomeMode))
				{
					if(DisplayInfo . PropertyFlags & DIPF_IS_WB)
					{
						struct ModeNode	*Node;
						STRPTR		 Name;

						Name = GetModeName(SomeMode);

						if((Len = strlen(Name)) > Max)
							Max = Len;

						if(Node = (struct ModeNode *)AllocVec(sizeof(struct ModeNode) + Len + 1,MEMF_ANY | MEMF_CLEAR))
						{
							Node -> VanillaNode . ln_Name	= (char *)(Node + 1);
							Node -> DisplayID		= SomeMode;

							strcpy(Node -> VanillaNode . ln_Name,Name);

							AddTail(&ModeList,&Node -> VanillaNode);

							if(LocalConfig -> ScreenConfig . DisplayMode == SomeMode)
								Mode = *NumModes;

							*NumModes = *NumModes + 1;
						}
					}
				}
			}

			SZ_UpdateMaxWidth(LISTVIEW_KIND,NULL,Max,NULL);
			SZ_SetWidth(SZ_ResetMaxWidth());

			SZ_AddLeftOffset(SZ_LeftOffsetN(MSG_SCREENPANEL_AVAILABLE_DISPLAY_MODES_GAD,MSG_SCREENPANEL_COLOUR_GAD,MSG_SCREENPANEL_EDIT_SCREEN_PALETTE_GAD,MSG_SCREENPANEL_RED_GAD,MSG_SCREENPANEL_GREEN_GAD,MSG_SCREENPANEL_BLUE_GAD,MSG_SCREENPANEL_SCREEN_FONT_GAD,-1));

			NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_AVAILABLE_DISPLAY_MODES_GAD);
			NewGadget . ng_GadgetID		= Counter;
			NewGadget . ng_Flags		= PLACETEXT_LEFT;

			GadgetArray[Counter] = Gadget = CreateGadget(LISTVIEW_KIND,Gadget,&NewGadget,
				SZ_Adjust,		TRUE,
				SZ_AutoWidth,		TRUE,
				SZ_Lines,		5,

				GTLV_Labels,		&ModeList,
				GTLV_ShowSelected,	NULL,
				GTLV_Selected,		Mode,
				GTLV_Top,		Mode,
			TAG_DONE);
		}
#ifdef ASLSM_FilterFunc
		else
		{
			ULONG			 SomeMode = INVALID_ID;
			struct DisplayInfo	 DisplayInfo;
			LONG			 Len,Max = 0;

			while((SomeMode = NextDisplayInfo(SomeMode)) != INVALID_ID)
			{
				if(ModeLimited)
				{
					if(!ModeOkay(SomeMode))
						continue;
				}

				if(GetDisplayInfoData(NULL,(APTR)&DisplayInfo,sizeof(struct DisplayInfo),DTAG_DISP,SomeMode))
				{
					if(DisplayInfo . PropertyFlags & DIPF_IS_WB)
					{
						if((Len = strlen(GetModeName(SomeMode))) > Max)
							Max = Len;
					}
				}
			}

			SZ_UpdateMaxWidth(TEXT_KIND,NULL,Max,NULL);

			SZ_SetWidth(SZ_ResetMaxWidth());

			SZ_AddLeftOffset(SZ_LeftOffsetN(MSG_SCREENPANEL_CURRENT_DISPLAY_MODE_GAD,MSG_SCREENPANEL_COLOUR_GAD,MSG_SCREENPANEL_EDIT_SCREEN_PALETTE_GAD,MSG_SCREENPANEL_RED_GAD,MSG_SCREENPANEL_GREEN_GAD,MSG_SCREENPANEL_BLUE_GAD,MSG_SCREENPANEL_SCREEN_FONT_GAD,-1));

			Counter = GAD_MODE;

			NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_CURRENT_DISPLAY_MODE_GAD);
			NewGadget . ng_GadgetID		= Counter;
			NewGadget . ng_Flags		= PLACETEXT_LEFT;

			if(ModeNotAvailable(LocalConfig -> ScreenConfig . DisplayMode))
				LocalConfig -> ScreenConfig . DisplayMode = HIRES_KEY;

			GadgetArray[Counter++] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget,
				SZ_Adjust,	TRUE,
				SZ_AutoWidth,	TRUE,

				GTTX_Text,	GetModeName(LocalConfig -> ScreenConfig . DisplayMode),
				GTTX_Border,	TRUE,
			TAG_DONE);

			NewGadget . ng_GadgetText	= LocaleString(MSG_GLOBAL_SELECT_NEW_DISPLAY_MODE_TXT);
			NewGadget . ng_GadgetID		= Counter;
			NewGadget . ng_Flags		= 0;

			GadgetArray[Counter] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
				SZ_Adjust,	TRUE,
				SZ_AutoWidth,	TRUE,
			TAG_DONE);
		}
#endif	/* ASLSM_FilterFunc */

		Counter = GAD_COLOUR;

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_COLOUR_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(CYCLE_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,

			GTCY_Labels,	ColourType,
			GTCY_Active,	LocalConfig -> ScreenConfig . ColourMode,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_EDIT_SCREEN_PALETTE_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(PALETTE_KIND,Gadget,&NewGadget,
			SZ_Adjust,		TRUE,
			SZ_AutoWidth,		TRUE,
			SZ_AlignExtra,		TRUE,

			GTPA_Depth,		Config . ScreenConfig . ColourMode == COLOUR_EIGHT ? 3 : Screen -> RastPort . BitMap -> Depth,
			GTPA_Color,		0,
			GA_Disabled,		WrongMode,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_RED_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
			SZ_Adjust,		TRUE,
			SZ_AutoWidth,		TRUE,

			GTSL_Min,		0,
			GTSL_Max,		15,
			GTSL_Level,		0,
			GTSL_LevelFormat,	"%2ld",
			GTSL_MaxLevelLen,	2,
			GA_Disabled,		WrongMode,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_GREEN_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
			SZ_Adjust,		TRUE,
			SZ_AutoWidth,		TRUE,

			GTSL_Min,		0,
			GTSL_Max,		15,
			GTSL_Level,		0,
			GTSL_LevelFormat,	"%2ld",
			GTSL_MaxLevelLen,	2,
			GA_Disabled,		WrongMode,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_BLUE_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
			SZ_Adjust,		TRUE,
			SZ_AutoWidth,		TRUE,

			GTSL_Min,		0,
			GTSL_Max,		15,
			GTSL_Level,		0,
			GTSL_LevelFormat,	"%2ld",
			GTSL_MaxLevelLen,	2,
			GA_Disabled,		WrongMode,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_USE_DEFAULT_TXT);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_Flags		= 0;

		GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,

			GA_Disabled,	WrongMode,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_SCREEN_FONT_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,
			SZ_AlignExtra,	TRUE,

			GTTX_Border,	TRUE,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_SELECT_NEW_FONT_TXT);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_Flags		= 0;

		GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,
		TAG_DONE);

		SZ_AddLeftOffset(SZ_LeftOffsetDelta(MSG_SCREENPANEL_MAKE_SCREEN_PUBLIC_GAD,MSG_SCREENPANEL_STATUS_LINE_GAD));

		SZ_ResetMaxWidth();

		SZ_UpdateMaxWidth(CYCLE_KIND,NULL,0,StatusType);

		SZ_SetWidth(SZ_ResetMaxWidth());

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_MAKE_SCREEN_PUBLIC_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,
			SZ_NewColumn,	TRUE,

			GTCB_Checked,	LocalConfig -> ScreenConfig . MakeScreenPublic,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_SHANGHAI_WINDOWS_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,

			GTCB_Checked,	LocalConfig -> ScreenConfig . ShanghaiWindows,
			GA_Disabled,	LocalConfig -> ScreenConfig . MakeScreenPublic ? FALSE : TRUE,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_BLINKING_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,
			SZ_AlignExtra,	TRUE,

			GTCB_Checked,	LocalConfig -> ScreenConfig . Blinking,
			GA_Disabled,	LocalConfig -> ScreenConfig . ColourMode == COLOUR_MONO || LocalConfig -> ScreenConfig . ColourMode == COLOUR_SIXTEEN,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_FASTER_LAYOUT_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,

			GTCB_Checked,	LocalConfig -> ScreenConfig . FasterLayout,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_SCREEN_TITLE_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,

			GTCB_Checked,	LocalConfig -> ScreenConfig . TitleBar,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_SCREENPANEL_STATUS_LINE_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter++] = Gadget = CreateGadget(CYCLE_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,

			GTCY_Labels,	StatusType,
			GTCY_Active,	LocalConfig -> ScreenConfig . StatusLine,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_GLOBAL_USE_GAD);
		NewGadget . ng_GadgetID		= Counter;
		NewGadget . ng_Flags		= 0;

		SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_USE_GAD),0,NULL);
		SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_CANCEL_GAD),0,NULL);

		SZ_SetWidth(SZ_ResetMaxWidth());

		GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,
			SZ_AlignExtra,	TRUE,
			SZ_AlignLeft,	TRUE,
			SZ_AlignBottom,	TRUE,
		TAG_DONE);

		NewGadget . ng_GadgetText	= LocaleString(MSG_GLOBAL_CANCEL_GAD);
		NewGadget . ng_GadgetID		= Counter;

		GadgetArray[Counter] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
			SZ_Adjust,	TRUE,
			SZ_AutoWidth,	TRUE,
			SZ_AlignRight,	TRUE,
		TAG_DONE);
	}

	return(Gadget);
}

STATIC BYTE
IsWrongMode(struct Configuration *MyConfig,WORD OriginalMode)
{
	if(Config . ScreenConfig . ColourMode != OriginalMode)
		return(TRUE);
	else
	{
		switch(MyConfig -> ScreenConfig . ColourMode)
		{
			case COLOUR_AMIGA:	if(Screen -> RastPort . BitMap -> Depth < 2)
							return(TRUE);

						break;

			case COLOUR_EIGHT:	if(Screen -> RastPort . BitMap -> Depth < 3)
							return(TRUE);

						break;

			case COLOUR_SIXTEEN:	if(Screen -> RastPort . BitMap -> Depth < 4)
							return(TRUE);

						break;

			case COLOUR_MONO:	if(Screen -> RastPort . BitMap -> Depth > 1)
							return(TRUE);

						break;
		}

		return(FALSE);
	}
}

BYTE
ScreenPanel(struct Configuration *MyConfig)
{
	struct Window	*PanelWindow;
	struct Gadget	*GadgetList = NULL;
	struct Gadget	*GadgetArray[GAD_CANCEL + 1];
	LONG		 NumModes;

	BYTE		 WrongMode;
	WORD		 i;
	struct ModeNode	*Node,*Next;

	CopyMem(MyConfig,&PrivateConfig,sizeof(struct Configuration));

	WrongMode = IsWrongMode(MyConfig,PrivateConfig . ScreenConfig . ColourMode);

	if(CreateAllGadgets(&NumModes,MyConfig,GadgetArray,&GadgetList,WrongMode))
	{
		if(PanelWindow = OpenWindowTags(NULL,
			WA_Left,	(Screen -> Width	- SZ_GetWindowWidth())	/ 2,
			WA_Top,		(Screen -> Height	- SZ_GetWindowHeight())	/ 2,
			WA_Width,	SZ_GetWindowWidth(),
			WA_Height,	SZ_GetWindowHeight(),

			WA_Activate,	TRUE,
			WA_DragBar,	TRUE,
			WA_DepthGadget,	TRUE,
			WA_RMBTrap,	TRUE,
			WA_DepthGadget,	TRUE,
			WA_CloseGadget,	TRUE,
			WA_CustomScreen,Screen,

			WA_IDCMP,	IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | SLIDERIDCMP | CHECKBOXIDCMP | LISTVIEWIDCMP | PALETTEIDCMP | BUTTONIDCMP | CYCLEIDCMP,

			WA_Title,	LocaleString(MSG_SCREENPANEL_SCREEN_PREFERENCES_TXT),
		TAG_DONE))
		{
			struct IntuiMessage	*Massage;
			ULONG			 Class,Code;
			struct Gadget		*Gadget;
			BYTE			 Terminated = FALSE;

			LONG			 ColourNumber = 0;
			BYTE			 Red,Green,Blue;

			PushWindow(PanelWindow);

			AddGList(PanelWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
			RefreshGList(GadgetList,PanelWindow,NULL,(UWORD)-1);
			GT_RefreshWindow(PanelWindow,NULL);

			if(!WrongMode)
			{
				Red	= (MyConfig -> ScreenConfig . Colours[ColourNumber] >> 8) & 0xF;
				Green	= (MyConfig -> ScreenConfig . Colours[ColourNumber] >> 4) & 0xF;
				Blue	= (MyConfig -> ScreenConfig . Colours[ColourNumber]     ) & 0xF;

				GT_SetGadgetAttrs(GadgetArray[GAD_RED],PanelWindow,NULL,
					GTSL_Level,Red,
				TAG_DONE);

				GT_SetGadgetAttrs(GadgetArray[GAD_GREEN],PanelWindow,NULL,
					GTSL_Level,Green,
				TAG_DONE);

				GT_SetGadgetAttrs(GadgetArray[GAD_BLUE],PanelWindow,NULL,
					GTSL_Level,Blue,
				TAG_DONE);
			}

			SPrintf(SharedBuffer,"%s %ld",MyConfig -> ScreenConfig . FontName,MyConfig -> ScreenConfig . FontHeight);

			GT_SetGadgetAttrs(GadgetArray[GAD_CURRENTFONT],PanelWindow,NULL,
				GTTX_Text,	SharedBuffer,
			TAG_DONE);

			if(!WrongMode)
				LoadRGB4(VPort,MyConfig -> ScreenConfig . Colours,16);

			while(!Terminated)
			{
				WaitPort(PanelWindow -> UserPort);

				while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort)))
				{
					Class	= Massage -> Class;
					Code	= Massage -> Code;
					Gadget	= (struct Gadget *)Massage -> IAddress;

					GT_ReplyIMsg(Massage);

					if(Class == IDCMP_VANILLAKEY)
						KeySelect(GadgetArray,GAD_CANCEL,Code,PanelWindow,&Gadget,&Class,&Code);

					if(Class == IDCMP_CLOSEWINDOW)
					{
						CopyMem(&PrivateConfig,MyConfig,sizeof(struct Configuration));

						if(!memcmp(Config . ScreenConfig . Colours,MyConfig -> ScreenConfig . Colours,sizeof(UWORD) * 16))
							LoadRGB4(VPort,MyConfig -> ScreenConfig . Colours,16);
						else
							LoadRGB4(VPort,Config . ScreenConfig . Colours,16);

						Terminated = TRUE;
					}

					if(Class == IDCMP_MOUSEMOVE)
					{
						switch(Gadget -> GadgetID)
						{
							case GAD_RED:		Red = Code;

										MyConfig -> ScreenConfig . Colours[ColourNumber] = (Red << 8) | (Green << 4) | (Blue);

										LoadRGB4(VPort,MyConfig -> ScreenConfig . Colours,1 << (Screen -> RastPort . BitMap -> Depth));

										break;

							case GAD_GREEN:		Green = Code;

										MyConfig -> ScreenConfig . Colours[ColourNumber] = (Red << 8) | (Green << 4) | (Blue);

										LoadRGB4(VPort,MyConfig -> ScreenConfig . Colours,1 << (Screen -> RastPort . BitMap -> Depth));

										break;

							case GAD_BLUE:		Blue = Code;

										MyConfig -> ScreenConfig . Colours[ColourNumber] = (Red << 8) | (Green << 4) | (Blue);

										LoadRGB4(VPort,MyConfig -> ScreenConfig . Colours,1 << (Screen -> RastPort . BitMap -> Depth));

										break;

							default:		break;
						}
					}

					if(Class == IDCMP_GADGETUP)
					{
						switch(Gadget -> GadgetID)
						{
							case GAD_STATUS_LINE:	MyConfig -> ScreenConfig . StatusLine = Code;
										break;

							case GAD_COLOUR:	MyConfig -> ScreenConfig . ColourMode = Code;

										if(!ModeOkay(MyConfig -> ScreenConfig . DisplayMode) && MyConfig -> ScreenConfig . ColourMode > COLOUR_AMIGA)
										{
											MyConfig -> ScreenConfig . ColourMode = COLOUR_MONO;

											GT_SetGadgetAttrs(GadgetArray[GAD_COLOUR],PanelWindow,NULL,
												GTCY_Active,COLOUR_MONO,
											TAG_DONE);
										}

										WrongMode = IsWrongMode(MyConfig,PrivateConfig . ScreenConfig . ColourMode);

										GT_SetGadgetAttrs(GadgetArray[GAD_PALETTE],PanelWindow,NULL,
											GA_Disabled,WrongMode,
										TAG_DONE);

										GT_SetGadgetAttrs(GadgetArray[GAD_RED],PanelWindow,NULL,
											GA_Disabled,WrongMode,
										TAG_DONE);

										GT_SetGadgetAttrs(GadgetArray[GAD_GREEN],PanelWindow,NULL,
											GA_Disabled,WrongMode,
										TAG_DONE);

										GT_SetGadgetAttrs(GadgetArray[GAD_BLUE],PanelWindow,NULL,
											GA_Disabled,WrongMode,
										TAG_DONE);

										GT_SetGadgetAttrs(GadgetArray[GAD_STANDARD],PanelWindow,NULL,
											GA_Disabled,WrongMode,
										TAG_DONE);

										GT_SetGadgetAttrs(GadgetArray[GAD_BLINKING],PanelWindow,NULL,
											GA_Disabled,MyConfig -> ScreenConfig . ColourMode == COLOUR_MONO || MyConfig -> ScreenConfig . ColourMode == COLOUR_SIXTEEN,
										TAG_DONE);

										break;

							case GAD_RED:		Red = Code;

										MyConfig -> ScreenConfig . Colours[ColourNumber] = (Red << 8) | (Green << 4) | (Blue);

										LoadRGB4(VPort,MyConfig -> ScreenConfig . Colours,1 << (Screen -> RastPort . BitMap -> Depth));

										break;

							case GAD_GREEN:		Green = Code;

										MyConfig -> ScreenConfig . Colours[ColourNumber] = (Red << 8) | (Green << 4) | (Blue);

										LoadRGB4(VPort,MyConfig -> ScreenConfig . Colours,1 << (Screen -> RastPort . BitMap -> Depth));

										break;

							case GAD_BLUE:		Blue = Code;

										MyConfig -> ScreenConfig . Colours[ColourNumber] = (Red << 8) | (Green << 4) | (Blue);

										LoadRGB4(VPort,MyConfig -> ScreenConfig . Colours,1 << (Screen -> RastPort . BitMap -> Depth));

										break;

							case GAD_STANDARD:	switch(MyConfig -> ScreenConfig . ColourMode)
										{
											case COLOUR_AMIGA:	CopyMem(DefaultColours,MyConfig -> ScreenConfig . Colours,16 * sizeof(UWORD));
														break;

											case COLOUR_EIGHT:	CopyMem(ANSIColours,MyConfig -> ScreenConfig . Colours,16 * sizeof(UWORD));
														break;

											case COLOUR_SIXTEEN:	CopyMem(EGAColours,MyConfig -> ScreenConfig . Colours,16 * sizeof(UWORD));
														break;

											case COLOUR_MONO:	CopyMem(AtomicColours,MyConfig -> ScreenConfig . Colours,16 * sizeof(UWORD));
														break;
										}

										Red	= (MyConfig -> ScreenConfig . Colours[ColourNumber] >> 8) & 0xF;
										Green	= (MyConfig -> ScreenConfig . Colours[ColourNumber] >> 4) & 0xF;
										Blue	= (MyConfig -> ScreenConfig . Colours[ColourNumber]     ) & 0xF;

										GT_SetGadgetAttrs(GadgetArray[GAD_RED],PanelWindow,NULL,
											GTSL_Level,Red,
										TAG_DONE);

										GT_SetGadgetAttrs(GadgetArray[GAD_GREEN],PanelWindow,NULL,
											GTSL_Level,Green,
										TAG_DONE);

										GT_SetGadgetAttrs(GadgetArray[GAD_BLUE],PanelWindow,NULL,
											GTSL_Level,Blue,
										TAG_DONE);

										LoadRGB4(VPort,MyConfig -> ScreenConfig . Colours,1 << (Screen -> RastPort . BitMap -> Depth));

										break;

							case GAD_MAKEPUBLIC:	if(!SZ_GetChecked(Gadget))
										{
											GT_SetGadgetAttrs(GadgetArray[GAD_SHANGHAI],PanelWindow,NULL,
												GTCB_Checked,	FALSE,
												GA_Disabled,	TRUE,
											TAG_DONE);
										}
										else
										{
											GT_SetGadgetAttrs(GadgetArray[GAD_SHANGHAI],PanelWindow,NULL,
												GA_Disabled,	FALSE,
											TAG_DONE);
										}

										break;

							case GAD_MODES:		if(Node = (struct ModeNode *)GetListNode(Code,&ModeList))
										{
											MyConfig -> ScreenConfig . DisplayMode = Node -> DisplayID;

											if(!ModeOkay(MyConfig -> ScreenConfig . DisplayMode) && MyConfig -> ScreenConfig . ColourMode > COLOUR_AMIGA)
											{
												MyConfig -> ScreenConfig . ColourMode = COLOUR_AMIGA;

												GT_SetGadgetAttrs(GadgetArray[GAD_COLOUR],PanelWindow,NULL,
													GTCY_Active,COLOUR_AMIGA,
												TAG_DONE);
											}
										}

										break;
#ifdef ASLSM_FilterFunc
							case GAD_NEWMODE:	BlockWindow(PanelWindow);

										if(SelectDisplayMode(PanelWindow,&MyConfig -> ScreenConfig . DisplayMode))
										{
											GT_SetGadgetAttrs(GadgetArray[GAD_MODE],PanelWindow,NULL,
												GTTX_Text,	GetModeName(MyConfig -> ScreenConfig . DisplayMode),
											TAG_DONE);

											if(!ModeOkay(MyConfig -> ScreenConfig . DisplayMode) && MyConfig -> ScreenConfig . ColourMode > COLOUR_AMIGA)
											{
												MyConfig -> ScreenConfig . ColourMode = COLOUR_AMIGA;

												GT_SetGadgetAttrs(GadgetArray[GAD_COLOUR],PanelWindow,NULL,
													GTCY_Active,COLOUR_AMIGA,
												TAG_DONE);
											}
										}

										ReleaseWindow(PanelWindow);

										break;
#endif	/* ASLSM_FilterFunc */
							case GAD_PALETTE:	ColourNumber = Code;

SetPalette:									Red	= (MyConfig -> ScreenConfig . Colours[ColourNumber] >> 8) & 0xF;
										Green	= (MyConfig -> ScreenConfig . Colours[ColourNumber] >> 4) & 0xF;
										Blue	= (MyConfig -> ScreenConfig . Colours[ColourNumber]     ) & 0xF;

										GT_SetGadgetAttrs(GadgetArray[GAD_RED],PanelWindow,NULL,
											GTSL_Level,Red,
										TAG_DONE);

										GT_SetGadgetAttrs(GadgetArray[GAD_GREEN],PanelWindow,NULL,
											GTSL_Level,Green,
										TAG_DONE);

										GT_SetGadgetAttrs(GadgetArray[GAD_BLUE],PanelWindow,NULL,
											GTSL_Level,Blue,
										TAG_DONE);

										break;

							case GAD_NEWFONT:	BlockWindow(PanelWindow);

										if(PickFont(PanelWindow,MyConfig -> ScreenConfig . FontName,&MyConfig -> ScreenConfig . FontHeight,GadToolsBase -> lib_Version < 39))
										{
											SPrintf(SharedBuffer,"%s %ld",MyConfig -> ScreenConfig . FontName,MyConfig -> ScreenConfig . FontHeight);

											GT_SetGadgetAttrs(GadgetArray[GAD_CURRENTFONT],PanelWindow,NULL,
												GTTX_Text,	SharedBuffer,
											TAG_DONE);
										}

										ReleaseWindow(PanelWindow);

										break;

							case GAD_USE:		Terminated = TRUE;

										if(!WrongMode)
										{
											CopyMem(MyConfig -> ScreenConfig . Colours,BlinkColours,sizeof(UWORD) * 16);

											switch(MyConfig -> ScreenConfig . ColourMode)
											{
												case COLOUR_EIGHT:	CopyMem(MyConfig -> ScreenConfig . Colours,ANSIColours,16 * sizeof(UWORD));

															for(i = 0 ; i < 8 ; i++)
																BlinkColours[i + 8] = BlinkColours[0];

															break;

												case COLOUR_SIXTEEN:	CopyMem(MyConfig -> ScreenConfig . Colours,EGAColours,16 * sizeof(UWORD));
															break;

												case COLOUR_AMIGA:	CopyMem(MyConfig -> ScreenConfig . Colours,DefaultColours,16 * sizeof(UWORD));

															BlinkColours[3] = BlinkColours[0];

															break;

												case COLOUR_MONO:	CopyMem(MyConfig -> ScreenConfig . Colours,AtomicColours,16 * sizeof(UWORD));
															break;
											}
										}
										else
										{
											if(MyConfig -> ScreenConfig . ColourMode != PrivateConfig . ScreenConfig . ColourMode)
											{
												switch(MyConfig -> ScreenConfig . ColourMode)
												{
													case COLOUR_EIGHT:	CopyMem(ANSIColours,MyConfig -> ScreenConfig . Colours,16 * sizeof(UWORD));
																break;

													case COLOUR_SIXTEEN:	CopyMem(EGAColours,MyConfig -> ScreenConfig . Colours,16 * sizeof(UWORD));
																break;

													case COLOUR_AMIGA:	CopyMem(DefaultColours,MyConfig -> ScreenConfig . Colours,16 * sizeof(UWORD));
																break;

													case COLOUR_MONO:	CopyMem(AtomicColours,MyConfig -> ScreenConfig . Colours,16 * sizeof(UWORD));
																break;
												}
											}
										}

										MyConfig -> ScreenConfig . MakeScreenPublic	= SZ_GetChecked(GadgetArray[GAD_MAKEPUBLIC]);
										MyConfig -> ScreenConfig . ShanghaiWindows	= SZ_GetChecked(GadgetArray[GAD_SHANGHAI]);
										MyConfig -> ScreenConfig . Blinking		= SZ_GetChecked(GadgetArray[GAD_BLINKING]);
										MyConfig -> ScreenConfig . FasterLayout		= SZ_GetChecked(GadgetArray[GAD_FASTER_LAYOUT]);
										MyConfig -> ScreenConfig . TitleBar		= SZ_GetChecked(GadgetArray[GAD_TITLEBAR]);

										break;

							case GAD_CANCEL:	Terminated = TRUE;

										CopyMem(&PrivateConfig,MyConfig,sizeof(struct Configuration));

										if(!memcmp(Config . ScreenConfig . Colours,MyConfig -> ScreenConfig . Colours,sizeof(UWORD) * 16))
											LoadRGB4(VPort,MyConfig -> ScreenConfig . Colours,16);
										else
											LoadRGB4(VPort,Config . ScreenConfig . Colours,16);

										break;

							default:		break;
						}
					}
				}
			}

			RemoveGList(PanelWindow,GadgetList,(UWORD)-1);

			PopWindow();

			CloseWindow(PanelWindow);
		}
	}

	FreeGadgets(GadgetList);

	Node = (struct ModeNode *)ModeList . lh_Head;

	while(Next = (struct ModeNode *)Node -> VanillaNode . ln_Succ)
	{
		FreeVec(Node);

		Node = Next;
	}

	if(PrivateConfig . ScreenConfig . DisplayMode != MyConfig -> ScreenConfig . DisplayMode || Stricmp(PrivateConfig . ScreenConfig . FontName,MyConfig -> ScreenConfig . FontName) || PrivateConfig . ScreenConfig . FontHeight != MyConfig -> ScreenConfig . FontHeight || PrivateConfig . ScreenConfig . ColourMode != MyConfig -> ScreenConfig . ColourMode)
		return(TRUE);

	if(PrivateConfig . ScreenConfig . MakeScreenPublic != MyConfig -> ScreenConfig . MakeScreenPublic || PrivateConfig . ScreenConfig . ShanghaiWindows != MyConfig -> ScreenConfig . ShanghaiWindows)
		return(TRUE);

	if(PrivateConfig . ScreenConfig . Blinking != MyConfig -> ScreenConfig . Blinking && MyConfig -> ScreenConfig . ColourMode == COLOUR_EIGHT)
		return(TRUE);

	if(PrivateConfig . ScreenConfig . FasterLayout != MyConfig -> ScreenConfig . FasterLayout && MyConfig -> ScreenConfig . ColourMode != COLOUR_MONO)
		return(TRUE);

	if(PrivateConfig . ScreenConfig . TitleBar != MyConfig -> ScreenConfig . TitleBar || PrivateConfig . ScreenConfig . StatusLine != MyConfig -> ScreenConfig . StatusLine)
		return(TRUE);

	return(FALSE);
}
