/* Programmname                                                               */

/*----------------------------------------------------------------------------*/
/* System Includes                                                            */
/*----------------------------------------------------------------------------*/

	#include <proto/exec.h>
	#include <proto/dos.h>
	#include <proto/intuition.h>
	#include <proto/graphics.h>
	#include <proto/gadtools.h>
	#include <proto/icon.h>
	#include <proto/wb.h>
	#include <string.h>

/*----------------------------------------------------------------------------*/
/* Konstanten & Makros                                                        */
/*----------------------------------------------------------------------------*/

	#define GID_ICONIFY  4711
	#define GID_QUIT     4712
	#define GID_LOAD     4713
	#define GID_SAVE     4714

/*----------------------------------------------------------------------------*/
/* Typdefinitionen                                                            */
/*----------------------------------------------------------------------------*/

	struct gui {
		struct Screen *scr;
		struct Window *win;
		APTR visualinfo;
		struct Gadget *glist;
		struct MsgPort *appport;
		struct AppIcon *appicon;
		struct DiskObject *diskobj;
		ULONG shading;
		struct Gadget *shadinggad;
		ULONG quality;
		struct Gadget *qualitygad;
		ULONG view;
		struct Gadget *viewgad;
		char server[256];
		struct Gadget *servergad;
		char path[256];
		struct Gadget *pathgad;
		char imgpath[256];
		struct Gadget *imgpathgad;
		ULONG delay;
		struct Gadget *delaygad;
		char hotkey1[256];
		struct Gadget *hotkey1gad;
		char hotkey2[256];
		struct Gadget *hotkey2gad;
		};

/*----------------------------------------------------------------------------*/
/* String mit maximaler Länge kopieren                                        */
/*----------------------------------------------------------------------------*/

	size_t strlcpy (char *dst,const char *src,size_t siz)

	{
	char *d = dst;
	const char *s = src;
	size_t n = siz;

	if (n != 0)
		{
		while (--n != 0)
			{
			if ((*d++ = *s++) == '\0')
				break;
			}
		}

	if (n == 0)
		{
		if (siz != 0)
			*d = '\0';
		while (*s++);
		}

	return(s - src - 1);
	}

/*----------------------------------------------------------------------------*/
/* Fenster schließen                                                          */
/*----------------------------------------------------------------------------*/

	void close_window (struct gui *g)

	{
	if (g->glist && g->win)
		{
		char *text;
		GT_GetGadgetAttrs (g->shadinggad,g->win,NULL,GTCY_Active,&g->shading,TAG_END);
		GT_GetGadgetAttrs (g->qualitygad,g->win,NULL,GTCY_Active,&g->quality,TAG_END);
		GT_GetGadgetAttrs (g->viewgad   ,g->win,NULL,GTCY_Active,&g->view   ,TAG_END);
		GT_GetGadgetAttrs (g->servergad ,g->win,NULL,GTST_String,&text      ,TAG_END);
		strlcpy (g->server,text,256);
		GT_GetGadgetAttrs (g->pathgad   ,g->win,NULL,GTST_String,&text      ,TAG_END);
		strlcpy (g->path,text,256);
		GT_GetGadgetAttrs (g->imgpathgad,g->win,NULL,GTST_String,&text      ,TAG_END);
		strlcpy (g->imgpath,text,256);
		GT_GetGadgetAttrs (g->delaygad  ,g->win,NULL,GTIN_Number,&g->delay  ,TAG_END);
		GT_GetGadgetAttrs (g->hotkey1gad,g->win,NULL,GTST_String,&text      ,TAG_END);
		strlcpy (g->hotkey1,text,256);
		GT_GetGadgetAttrs (g->hotkey2gad,g->win,NULL,GTST_String,&text      ,TAG_END);
		strlcpy (g->hotkey2,text,256);
		}

	if (g->win)
		{
		CloseWindow (g->win);
		g->win = NULL;
		}

	if (g->glist)
		{
		FreeGadgets (g->glist);
		g->glist = NULL;
		}

	if (g->visualinfo)
		{
		FreeVisualInfo (g->visualinfo);
		g->visualinfo = NULL;
		}

	if (g->scr)
		{
		UnlockPubScreen (NULL,g->scr);
		g->scr = NULL;
		}
	}

/*----------------------------------------------------------------------------*/
/* Rahmen mit Überschrift zeichnen                                            */
/*----------------------------------------------------------------------------*/

	void draw_group_frame (struct RastPort *rp,long x,long y,long w,long h,char *text,APTR vi)

	{
	DrawBevelBox (rp,x,y,w,h,GTBB_FrameType,BBFT_RIDGE,GTBB_Recessed,TRUE,GT_VisualInfo,vi,TAG_END);

	if (text)
		{
		long len = strlen(text);
		long tx = x + (w - TextLength(rp,text,len)) / 2;
		long ty = y - (rp->TxHeight - 2) / 2 + rp->TxBaseline;
		SetABPenDrMd (rp,1,0,JAM2);
		Move (rp,tx+1,ty+1);
		Text (rp,text,len);
		SetABPenDrMd (rp,2,0,JAM1);
		Move (rp,tx,ty);
		Text (rp,text,len);
		}
	}

/*----------------------------------------------------------------------------*/
/* Fenster öffnen                                                             */
/*----------------------------------------------------------------------------*/

	BOOL open_window (struct gui *g)

	{
	struct Gadget *gad;
	struct NewGadget ng = {0};
	long fontw,fonth;
	long winw,winh;
	static STRPTR labels1[] = {"Maske","Vorgabe","Einfach","Gut","Sehr gut",NULL};
	static STRPTR labels2[] = {"Maske","Vorgabe","Piktogramm","Bild","Exakt",NULL};
	static STRPTR labels3[] = {"Maske","Kacheln","Zentrieren","Angepaßt","Gut angep.",NULL};
	WORD bevel1_x,bevel1_y,bevel1_w,bevel1_h;
	WORD bevel2_x,bevel2_y,bevel2_w,bevel2_h;
	WORD bevel3_x,bevel3_y,bevel3_w,bevel3_h;

	if (g->win)
		return (TRUE);

	if (g->scr = LockPubScreen (NULL))
		{
		g->visualinfo = GetVisualInfo (g->scr,TAG_END);

		fontw = g->scr->RastPort.TxWidth;
		fonth = g->scr->RastPort.TxHeight;

		gad = CreateContext (&g->glist);

		bevel1_x = g->scr->WBorLeft + 4;
		bevel1_y = g->scr->WBorTop + fonth * 3 / 2 + 3;

		ng.ng_VisualInfo  = g->visualinfo;
		ng.ng_TextAttr    = g->scr->Font;
		ng.ng_LeftEdge    = bevel1_x + 8 + 13 * fontw;
		ng.ng_TopEdge     = bevel1_y + 6 + fonth / 2;
		ng.ng_Width       = 15 * fontw;
		ng.ng_Height      = fonth + 6;
		ng.ng_GadgetText  = "Schattierung";
		gad = CreateGadget (CYCLE_KIND,gad,&ng,GTCY_Labels,labels1,GTCY_Active,g->shading,TAG_END);
		g->shadinggad = gad;

		ng.ng_TopEdge    += ng.ng_Height + 4;
		ng.ng_GadgetText  = "Farbqualität";
		gad = CreateGadget (CYCLE_KIND,gad,&ng,GTCY_Labels,labels2,GTCY_Active,g->quality,TAG_END);
		g->qualitygad = gad;

		ng.ng_TopEdge    += ng.ng_Height + 4;
		ng.ng_GadgetText  = "Darstellung";
		gad = CreateGadget (CYCLE_KIND,gad,&ng,GTCY_Labels,labels3,GTCY_Active,g->view,TAG_END);
		g->viewgad = gad;

		bevel1_w = ng.ng_LeftEdge + ng.ng_Width + 8 - bevel1_x;
		bevel1_h = ng.ng_TopEdge + ng.ng_Height + 6 - bevel1_y;

		bevel2_x = bevel1_x + bevel1_w + 4;
		bevel2_y = bevel1_y;

		ng.ng_LeftEdge    = bevel2_x + 8 + 9 * fontw;
		ng.ng_TopEdge     = bevel2_y + 6 + fonth / 2;
		ng.ng_Width       = 21 * fontw;
		ng.ng_GadgetText  = "Server";
		gad = CreateGadget (STRING_KIND,gad,&ng,GTST_String,g->server,TAG_END);
		g->servergad = gad;

		ng.ng_TopEdge    += ng.ng_Height + 4;
		ng.ng_GadgetText  = "Pfad";
		gad = CreateGadget (STRING_KIND,gad,&ng,GTST_String,g->path,TAG_END);
		g->pathgad = gad;

		ng.ng_TopEdge    += ng.ng_Height + 4;
		ng.ng_GadgetText  = "Bildpfad";
		gad = CreateGadget (STRING_KIND,gad,&ng,GTST_String,g->imgpath,TAG_END);
		g->imgpathgad = gad;

		bevel2_w = ng.ng_LeftEdge + ng.ng_Width + 8 - bevel2_x;
		bevel2_h = ng.ng_TopEdge + ng.ng_Height + 6 - bevel2_y;

		bevel3_x = bevel1_x;
		bevel3_y = bevel1_y + bevel1_h + 4 + fonth / 2;

		ng.ng_LeftEdge    = bevel3_x + 8 + 24 * fontw + 20;
		ng.ng_TopEdge     = bevel3_y + 6 + fonth / 2;
		ng.ng_Width       = 22 * fontw;
		ng.ng_GadgetText  = "Zeitverzögerung";
		gad = CreateGadget (INTEGER_KIND,gad,&ng,GTIN_Number,g->delay,STRINGA_Justification,STRINGCENTER,TAG_END);
		g->delaygad = gad;

		ng.ng_TopEdge    += ng.ng_Height + 4;
		ng.ng_GadgetText  = "Hotkey Abbruch";
		gad = CreateGadget (STRING_KIND,gad,&ng,GTST_String,g->hotkey1,STRINGA_Justification,STRINGCENTER,TAG_END);
		g->hotkey1gad = gad;

		ng.ng_TopEdge    += ng.ng_Height + 4;
		ng.ng_GadgetText  = "Hotkey Aktualisieren";
		gad = CreateGadget (STRING_KIND,gad,&ng,GTST_String,g->hotkey2,STRINGA_Justification,STRINGCENTER,TAG_END);
		g->hotkey2gad = gad;

		bevel3_w = ng.ng_LeftEdge + ng.ng_Width + 8 - bevel3_x + 12 * fontw;
		bevel3_h = ng.ng_TopEdge + ng.ng_Height + 6 - bevel3_y;

		ng.ng_LeftEdge    = bevel3_x;
		ng.ng_TopEdge     = bevel3_y + bevel3_h + 4;
		ng.ng_Width       = (bevel3_w - 12 + 2) / 4;
		ng.ng_GadgetText  = "Beenden";
		ng.ng_GadgetID    = GID_QUIT;
		gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END);

		ng.ng_LeftEdge   += ng.ng_Width + 4;
		ng.ng_GadgetText  = "Sichern";
		ng.ng_GadgetID    = GID_SAVE;
		gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END);

		ng.ng_LeftEdge   += ng.ng_Width + 4;
		ng.ng_GadgetText  = "Laden";
		ng.ng_GadgetID    = GID_LOAD;
		gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END);

		ng.ng_LeftEdge   += ng.ng_Width + 4;
		ng.ng_GadgetText  = "Hintergrund";
		ng.ng_GadgetID    = GID_ICONIFY;
		gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END);

		if (gad)
			{

			winw = ng.ng_LeftEdge + ng.ng_Width + 4 + g->scr->WBorRight;
			winh = ng.ng_TopEdge + ng.ng_Height + 4 + g->scr->WBorBottom;

			if (g->win = OpenWindowTags (NULL,
					WA_Left,(g->scr->Width - winw) / 2,
					WA_Top,(g->scr->Height - winh) / 2,
					WA_Width,winw,
					WA_Height,winh,
					WA_Title,"WebGround Prefs",
					WA_Flags,WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_ACTIVATE,
					WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_REFRESHWINDOW | CYCLEIDCMP | STRINGIDCMP | BUTTONIDCMP,
					WA_Gadgets,g->glist,
					TAG_END))
				{
				GT_RefreshWindow (g->win,NULL);

				SetFont (g->win->RPort,g->scr->RastPort.Font);

				draw_group_frame (g->win->RPort,bevel1_x,bevel1_y,bevel1_w,bevel1_h," Hintergrundbild ",ng.ng_VisualInfo);
				draw_group_frame (g->win->RPort,bevel2_x,bevel2_y,bevel2_w,bevel2_h," Netzwerk ",ng.ng_VisualInfo);
				draw_group_frame (g->win->RPort,bevel3_x,bevel3_y,bevel3_w,bevel3_h," Optionen ",ng.ng_VisualInfo);

				return (TRUE);
				}
			}
		}

	close_window (g);
	return (FALSE);
	}

/*----------------------------------------------------------------------------*/
/* AppIcon entfernen                                                          */
/*----------------------------------------------------------------------------*/

	void delete_appicon (struct gui *g)

	{
	struct Message *msg;

	if (g->appicon)
		{
		while (!RemoveAppIcon (g->appicon))
			{
			while (msg = GetMsg (g->appport))
				ReplyMsg (msg);
			Delay (1);
			}
		g->appicon = NULL;
		}

	if (g->appport)
		{
		while (msg = GetMsg (g->appport))
			ReplyMsg (msg);
		DeleteMsgPort (g->appport);
		g->appport = NULL;
		}

	if (g->diskobj)
		{
		FreeDiskObject (g->diskobj);
		g->diskobj = NULL;
		}
	}

/*----------------------------------------------------------------------------*/
/* AppIcon anlegen                                                            */
/*----------------------------------------------------------------------------*/

	BOOL create_appicon (struct gui *g)

	{
	if (g->appport = CreateMsgPort())
		{
		if (g->diskobj = GetDiskObjectNew ("iconify"))
			{
			g->diskobj->do_CurrentX = NO_ICON_POSITION;
			g->diskobj->do_CurrentY = NO_ICON_POSITION;
			if (g->appicon = AddAppIcon (0,0,"Iconify",g->appport,(BPTR)0,g->diskobj,TAG_END))
				{
				return (TRUE);
				}
			}
		}

	delete_appicon (g);
	return (FALSE);
	}

/*----------------------------------------------------------------------------*/
/* Hauptprogramm                                                              */
/*----------------------------------------------------------------------------*/

	int main (void)

	{
	struct gui g = {0};

	g.shading = 2;
	g.quality = 3;
	g.view    = 3;
	g.delay   = 30;

	if (open_window (&g))
		{
		BOOL cont = TRUE;
		do	{
			ULONG appsig = g.appport ? 1L << g.appport->mp_SigBit : 0;
			ULONG winsig = g.win ? 1L << g.win->UserPort->mp_SigBit : 0;

			ULONG sigs = Wait (winsig | appsig | SIGBREAKF_CTRL_C);

			if (sigs & SIGBREAKF_CTRL_C)
				cont = FALSE;

			if (sigs & winsig)
				{
				struct IntuiMessage *imsg;
				BOOL iconify = FALSE;

				while (imsg = GT_GetIMsg (g.win->UserPort))
					{
					switch (imsg->Class)
						{
					case IDCMP_GADGETUP:
						switch (((struct Gadget *)imsg->IAddress)->GadgetID)
							{
						case GID_ICONIFY:
							iconify = TRUE;
							break;
						case GID_QUIT:
							cont = FALSE;
							break;
							}
					case IDCMP_REFRESHWINDOW:
						GT_BeginRefresh (g.win);
						GT_EndRefresh (g.win,TRUE);
						break;
					case IDCMP_VANILLAKEY:
						if (imsg->Code == 0x1b)
							cont = FALSE;
						break;
					case IDCMP_CLOSEWINDOW:
						cont = FALSE;
						break;
						}
					GT_ReplyIMsg (imsg);
					}

				if (iconify)
					{
					if (create_appicon (&g))
						close_window (&g);
					else
						DisplayBeep (NULL);
					}
				}

			if (sigs & appsig)
				{
				struct AppMessage *appmsg;
				BOOL uniconify = FALSE;

				while (appmsg = (struct AppMessage *) GetMsg (g.appport))
					{
					uniconify = TRUE;
					ReplyMsg ((struct Message *)appmsg);
					}

				if (uniconify)
					{
					if (open_window (&g))
						delete_appicon (&g);
					else
						DisplayBeep (NULL);
					}
				}
			}
		while (cont);
		}
	else
		Printf ("cannot open window\n");

	close_window (&g);
	delete_appicon (&g);

	return (RETURN_OK);
	}

/*----------------------------------------------------------------------------*/
/* Ende des Quelltextes                                                       */
/*----------------------------------------------------------------------------*/
