/*-----------------------------------------------------------------------

	Wega 1.00 - Demonstrationsprogramm   (c) 1991/92 by D. Rabich
	==================================   Alle Rechte vorbehalten!

	Das Demonstrationsprogramm demonstriert F„higkeiten der Bibliothek
	Wega. Die Bibliothek ist in erster Linie als einfache Untersttzung
	fr GEM-Programme gedacht. Es erweitert die Objekttypen u. a. um

		-	fette Texte
		-	unterstrichene Texte
		-	Groupboxen (Rahmen mit Titel)
		-	Radiobuttons (runde Kn”pfe, Text auch w„hlbar)
		-	Selectbuttons (Kreuzchen, Text auch w„hlbar)
		-	einheitliche Titel
		-	verschiebbare Dialogboxen
		-	eigene Hintergrundrestaurierung
		-	PopUp-Mens
		-	Cyclebuttons
		-	Arrows

	Ferner sorgt eine eigene form_do()-Routine fr komfortablere
	Editfelder (z.B. <Control/Shift>+<Cursor links/rechts> sowie
	<Shift>+<Tab>) und die M”glichkeit, eine Tastatursteuerung
	zu implementierten (hier im Demo <Alternate>+<1/2/C>, <Help>,
	<F7> und <F8>).

	Das Wega-Developer Kit wird nach dem Sharewareprinzip weiter-
	gegeben. Eine Nutzung zu Testzwecken ist bis zu 21 Tage nach
	der Installation gestattet. Bei einer weitergehenden Nutzung
	ist der Sharewareobolus in H”he von 100 DM zu entrichten.

	Mit Wega entwickelte Programme mssen die GEM-Richtlinien wie sie
	im Atari ST/STE/TT-Profibuch aufgefhrt sind einhalten. Ferner sind
	die zus„tzlichen Wega-Richtlinien zu bercksichtigen. Dem Autor von
	Wega ist ein kostenloses Belegexemplar zu bersenden.

	Autor von Wega bzw. Wega Developer Kit ist

	Dietmar Rabich,
	Tel. & Fax +49 2594 86103,
	Koppelbusch 37, D-W4408 Dlmen-Hausdlmen.


											Dlmen, im Januar 1993.

-----------------------------------------------------------------------*/

/* Standardbibliotheken */
#include <stddef.h>
#include <stdio.h>

/* Wegabibliothek */
#include <wega.h>

/* Resourcemakros */
#include "resource.h"
#include "flydemo.h"

#include "..\handling\handling.h"


/* Name des Programms */
#define	FULLAPPNAME	"Wegaflydemo"
#define	APPNAME		"WEGAFDMO"
#define	INFAME		APPNAME ".INF"

/* Alertboxen und Texte */
#define	NOACC		"[3][ Das Accessory |"		\
						" " FULLAPPNAME " |"	\
						" konnte nicht|"		\
						" angemeldet werden.|"	\
						" ][ OK ]"
#define	NOVDI		"[3][ |"					\
						" Initialisierung |"	\
						" der Workstation |"	\
						" erfolglos!!|"			\
						" ][ OK ]"
#define	NOAES		"Initialisierung von " FULLAPPNAME " erfolglos!\a"
#define NOAUTO		"Das Programm " FULLAPPNAME " kann nicht\n"	\
					"aus dem AUTO-Ordner gestartet werden!\a"

/* Accessoryname */
#define	ACCNAME		"  " FULLAPPNAME "..."

/* Anzahl der Eintr„ge im PopUp-Men */
#define	NMB_ENTRIES		3
#define	NMB_ENTRIES2	4


/* Funktionsmakros */
#define	TuneHorizontalSlider(tree, full, back, left, right)			\
						{											\
							GListInit(tree, full);					\
							tree[right].ob_x	=					\
								tree[full].ob_width -				\
								tree[right].ob_width;				\
							tree[back].ob_x		=					\
								tree[left].ob_width - 1;			\
							tree[back].ob_width	=					\
								tree[full].ob_width -				\
								tree[left].ob_width -				\
								tree[right].ob_width + 2;			\
						}
#define	TuneVerticalSlider(tree, full, back, up, down)				\
						{											\
							GListInit(tree, full);					\
							tree[down].ob_y	=						\
								tree[full].ob_height -				\
								tree[down].ob_height;				\
							tree[back].ob_y		=					\
								tree[up].ob_height - 1;				\
							tree[back].ob_height	=				\
								tree[full].ob_height -				\
								tree[up].ob_height -				\
								tree[down].ob_height + 2;			\
						}
#define	max(x, y)		(((x) < (y)) ? (y) : (x))
#define	min(x, y)		(((x) > (y)) ? (y) : (x))


/* Typen */
typedef struct
{
	WORD	popsret[2];
	CHAR	field1[10];
	CHAR	field2[10];
	CHAR	field3[18];
	WORD	slidepos;
	struct
	{
		UWORD	checked	: 1;
		UWORD	radio	: 1;
	}	bits;
}	PARAMETER;


/* Parameter */
static PARAMETER	parameter =
					{
						{0, 0},
						"Dieses",
						"sind die",
						"Editfelder.",
						5,
						{0, 1}
					};					/* globale Parameter	*/

/* Texte fr PopUp-Men */
static CHAR		*entries[] =
				{
					"grožartig",
					"prima",
					"erstklassig"
				},
				*entries2[] =
				{
					"gut",
					"besser",
					"noch besser",
					"am besten"
				};

/* Eintr„ge fr Slider */
static CHAR		*months[]	=
				{
					"Jan.",
					"Feb.",
					"M„rz",
					"Apr.",
					"Mai",
					"Juni",
					"Juli",
					"Aug.",
					"Sep.",
					"Okt.",
					"Nov.",
					"Dez."
				};

/* Objektb„ume */
OBJECT			*demodial,			/* Demo-Objektbaum					*/
				*helpdial;			/* Hilfe-Objektbaum					*/
static DLGINFO	demodlginfo,		/* Dialoginformation				*/
				helpdlginfo;		/* Hilfeinformation					*/
WORD			colors		= 0;	/* verfgbare Farben				*/
static WORD		helpcolor	= RED;	/* Farbe fr Hilfsdialogtext		*/
static BOOLEAN	rsc_initialized	= FALSE,	/* Resourceintialisierung	*/
				wega_init	= FALSE;		/* Wega-Initialisierung		*/


/* Prototypen */
static BOOLEAN	openvwk(VOID);
static VOID		closevwk(VOID);
static VOID		do_undo(PARAMETER*);
static BOOLEAN	whichradio(OBJECT*, WORD, VOID*);
static VOID		slidedraw(SLIDERINFO*);
static LONG		timerinfo(VOID*);
static WORD		translate(KEY*, VOID*);
static VOID		prepare(VOID);
static VOID		release(VOID);
static VOID		do_it(VOID);
static BOOLEAN	init_resources(VOID);
WORD			main(VOID);

static SLIDERINFO	sli	=
					{
						0,
						11,
						1,
						3,	/* in der Regel = visible - 1 */
						0,
						0,
						NULL,
						GSLIDER,
						SLBACK,
						SLIDER,
						SLLEFT,
						SLRIGHT,
						(VOID(*)(WORD, VOID*))0L,
						slidedraw,
						(VOID*)months
					};


/* virtuelle Workstation ”ffnen */
static BOOLEAN openvwk(VOID)
{
	wega_init	= GWegaInit();

	if(!wega_init)
	{
		form_alert(1, NOVDI);
		if(ACCESSORY)
			for(;;)
			{
				WORD	msg[8];

				evnt_mesag(msg);
			}
		return(FALSE);
	}

	if(!rsc_initialized)
	{
		if(init_resources())
			rsc_initialized	= TRUE;
		else
			return(FALSE);
	}

	return(TRUE);
}


/* virtuelle Workstation schliežen */
static VOID closevwk(VOID)
{
	/* VDI-Workstation von Wega schliežen */
	if(wega_init)
		GWegaDone();

	wega_init	= FALSE;
}


/* Einstellungen rckg„ngig machen */
static VOID do_undo(PARAMETER *lp)
{
	*lp	= parameter;
	prepare();

	GObjcDraw(demodial, ROOT);
}


/* Suche nachgew„hltem Radiobutton */
static BOOLEAN whichradio(OBJECT *tree, WORD obj, VOID *data)
{
	WORD	*wradio;

	wradio	= (WORD*)data;

	if((tree[obj].ob_flags & RBUTTON) &&
		(tree[obj].ob_state & SELECTED))
	{
		*wradio	= obj;
		return(TRUE);
	}

	return(FALSE);
}


/* Sliderausgabe */
static VOID slidedraw(SLIDERINFO *sli)
{
	/* passenden Text setzen */
	GSetText(MakeObj(demodial, SLSHOW),
				"%-4s",
				((CHAR**)sli->data)[sli->current]);

	/* Objekt neu ausgeben */
	GObjcDraw(demodial, SLSHOW);
}


/* Timer-Funktion fr Hilfedialog */
#pragma warn -par
static LONG timerinfo(VOID* data)
{
	if(colors < 4)
		helpcolor = (helpcolor == WHITE) ? BLACK : WHITE;
	else
	{
		helpcolor++;
		if(helpcolor >= min(colors, 16))
			helpcolor	= RED;
	}

	helpdial[QUESTION].ob_spec.tedinfo->te_color	&= 0xF0FF;
	helpdial[QUESTION].ob_spec.tedinfo->te_color	|= helpcolor << 8;

	GObjcDraw(helpdial, QUESTION);

	return(500L);
}
#pragma warn .par


/* Tastenbersetzung fr Hauptdialog */
#pragma warn -par
static WORD translate(KEY *k, VOID *data)
{
	if(k->state.scancode)
		switch(k->key)
		{
			case KEY_F7:
				return(SLLEFT);

			case KEY_F8:
				return(SLRIGHT);

			case KEY_HELP:
				return(BHELP);

			case KEY_UNDO:
				return(BUNDO);
		}

	return(-1);
}
#pragma warn .par


/* Vorbereitungen */
static VOID prepare(VOID)
{
	/* Text fr PopUp setzen */
	GSetText(MakeObj(demodial, POPUP1), entries[parameter.popsret[0]]);
	GSetText(MakeObj(demodial, POPUP2), entries2[parameter.popsret[1]]);

	/* Editfelder vorbelegen */
	GSetText(MakeObj(demodial, EDFIELD1), parameter.field1);
	GSetText(MakeObj(demodial, EDFIELD2), parameter.field2);
	GSetText(MakeObj(demodial, EDFIELD3), parameter.field3);

	/* Text fr Slideranzeige */
	sli.current	= parameter.slidepos;
	GSetText(MakeObj(demodial, SLSHOW),
				"%-4s",
				((CHAR**)sli.data)[sli.current]);
	hdle_slider(&sli, INITIAL);

	/* Checkbutton */
	GChgState(MakeObj(demodial, CHECK), SELECTED,
				parameter.bits.checked ? MODE_SET : MODE_DELETE);

	/* Radiobutton */
	GChgState(MakeObj(demodial, RADIO1), SELECTED,
				parameter.bits.radio ? MODE_SET : MODE_DELETE);
	GChgState(MakeObj(demodial, RADIO2), SELECTED,
				parameter.bits.radio ? MODE_DELETE : MODE_SET);
}


/* Nachbereitungen */
static VOID release(VOID)
{
	GGetText(MakeObj(demodial, EDFIELD1), parameter.field1);
	GGetText(MakeObj(demodial, EDFIELD2), parameter.field2);
	GGetText(MakeObj(demodial, EDFIELD3), parameter.field3);

	{
		WORD	wradio;

		wradio	= -1;
		GChildWalk(demodial, GROUP, whichradio, &wradio);
		switch(wradio)
		{
			case RADIO1:
				parameter.bits.radio	= 1;
				break;

			case RADIO2:
				parameter.bits.radio	= 0;
				break;
		}
	}

	parameter.bits.checked	= (demodial[CHECK].ob_state & SELECTED) ? 1 : 0;

	parameter.slidepos	= sli.current;
}


/* Demoaktion */
static VOID do_it(VOID)
{
	WORD		ret;						/* Return-Button				*/
	LONG		edit		= (LONG)ROOT,	/* Start fr Editfelder			*/
				edithelp	= (LONG)ROOT;	/* Start fr Editfelder (Help)	*/
	BOOLEAN		doppel;						/* Doppelklick					*/
	PARAMETER	lpara;						/* lokale Parameter				*/

	/* Dialog zentrieren (bezglich Bildschirm) */
	GDialCenter(&demodlginfo, CNTR_AUTO, NULL);

	/* Dialog vorbereiten und ausgeben */
	lpara	= parameter;
	prepare();

	do
	{
		GDialPrepare(&demodlginfo);

		/* Schleife, bis OK, Abbruch oder Hilfe gew„hlt wurde */
		for(;;)
		{
			/* Dialog durchfhren */
			ret	= GFormDo(&demodlginfo,
							&edit,
							&doppel,
							translate,
							(LONG(*)(VOID*))0L,
							NULL,
							NULL);

			/* Status SELECTED zurcksetzen. */
			/* OK oder Abbruch? Dann raus... */
			{
				BOOLEAN	finish	= FALSE;

				switch(ret)
				{
					case BOK:
					case BCANCEL:
					case BHELP:
						finish	= TRUE;

					case BUNDO:
						GChgState(MakeObj(demodial, ret),
									SELECTED,
									MODE_DELETE);
						break;
				}

				if(finish)
					break;
			}

			/* Was anderes angeklickt? */
			switch(ret)
			{
				/* Undo? */
				case BUNDO:
					do_undo(&lpara);
					break;

				/* PopUp-Men? (1) */
				case POPUP1:
					if(!hdle_popup(demodial, ret, entries,
									NMB_ENTRIES, &(lpara.popsret[0])))
						hdle_cycle(demodial, ret, ret, entries,
									NMB_ENTRIES, &(lpara.popsret[0]),
									FALSE);
					break;

				/* PopUp-Men? (2) */
				case POPUP2:
					if(hdle_popup(demodial, ret, entries2,
									NMB_ENTRIES2, &(lpara.popsret[1])))
						break;

				/* Cyclebutton (bezogen auf PopUp 2) */
				case CYCLE:
					hdle_cycle(demodial, CYCLE, POPUP2, entries2,
								NMB_ENTRIES2, &(lpara.popsret[1]), doppel);
					break;

				/* Slider? */
				case SLIDER:
					hdle_slider(&sli, VARIOUS);
					break;

				case SLLEFT:
					hdle_slider(&sli, doppel ? MINIMUM : SINGLEUPLEFT);
					break;

				case SLRIGHT:
					hdle_slider(&sli, doppel ? MAXIMUM : SINGLEDOWNRIGHT);
					break;

				case SLBACK:
					{
						WORD	mx, ox, dummy;

						graf_mkstate(&mx, &dummy, &dummy, &dummy);
						objc_offset(demodial, SLIDER, &ox, &dummy);

						hdle_slider(&sli,
									(mx < ox) ? PAGEUPLEFT : PAGEDOWNRIGHT);
					}
					break;
			}
		}

		/* OK? Dann sichern... */
		if(ret == BOK)
		{
			parameter	= lpara;
			release();
		}

		/* Dialog verlassen, Hintergrund restaurieren */
		GDialFinish(&demodlginfo);

		/* Hilfe durchfhren */
		if(ret == BHELP)
		{
			WORD	ret_help;

			GDialCenter(&helpdlginfo, CNTR_AUTO, NULL);
			GDialPrepare(&helpdlginfo);
			ret_help	= GFormDo(&helpdlginfo,
									&edithelp,
									&doppel,
									(WORD(*)(KEY*, VOID*))0L,
									timerinfo,
									NULL,
									NULL);
			GChgState(MakeObj(helpdial, ret_help), SELECTED, MODE_DELETE);
			GDialFinish(&helpdlginfo);
		}

	} while(ret == BHELP);
}


/* Resourcen vorbereiten */
static BOOLEAN init_resources(VOID)
{
	/* Resourcen */
	if(!rsc_init())
		return(FALSE);

	{
		GRECT		gr_start;	/* Rechteck fr Rechtecke		*/

		/* Startrechteck ermitteln */
		wind_get(0, WF_WORKXYWH,
				 &(gr_start.g_x), &(gr_start.g_y),
				 &(gr_start.g_w), &(gr_start.g_h));
		gr_start.g_x = gr_start.g_x + gr_start.g_w / 2 - 8;
		gr_start.g_y = gr_start.g_y + gr_start.g_h / 2 - 8;
		gr_start.g_w =
		gr_start.g_h = 16;

		/* Dialog vorbereiten (nur einmal!!!) */
		GDialInit(demodial, &gr_start, NULL, &demodlginfo);
		GDialInit(helpdial, &gr_start, NULL, &helpdlginfo);

		/* Slider vorbereiten */
		TuneHorizontalSlider(demodial, GSLIDER, SLBACK, SLLEFT, SLRIGHT);

		/* Sliderinformation vorbereiten */
		sli.tree	= demodial;
	}
	return(TRUE);
}

/* Hauptprogramm */
WORD main(VOID)
{
	WORD		applid,				/* Application-ID				*/
				menuid,				/* Men-ID (Accessory)			*/
				msg[8];				/* Messagebuffer				*/

	/* Applikation-ID ermitteln */
	GEM_VERSION	= 0;
	applid		= appl_init();

	/* Existiert GEM-Versionnummer? */
	if(!GEM_VERSION)
	{
		puts(NOAUTO);
		return(-1);
	}

	if(applid < 0)
	{
		puts(NOAES);
		return(-1);
	}

	if(ACCESSORY)
	{
		menuid	= menu_register(applid, ACCNAME);
		if(menuid < 0)
		{
			form_alert(1, NOACC);
			for(;;)
				evnt_mesag(msg);
		}
	}

	/* Demoaktion */
	if(APPLICATION)
	{
		if(openvwk())
		{
			do_it();
			closevwk();
		}
		else
		{
			appl_exit();
			return(-2);
		}
	}
	else
		{
			for(;;)
			{
				/* Auf Nachricht warten! */
				evnt_mesag(msg);

				switch(msg[0])
				{
					/* Accessory wurde ge”ffnet. 			*/
					/* Also: ggf. VDI-Workstation ”ffnen,	*/
					/*       ggf. Resourcen initialisieren.	*/
					case AC_OPEN	:
						if(msg[4] == menuid)
						{
							openvwk();
							do_it();
							closevwk();
						}
						break;

					/* Accessory wurde geschlossen,					*/
					/* die Hauptapplikation hat sich verabschiedet.	*/
					case AC_CLOSE	:
						break;
				}
			}
		}

	/* die folgenden Zeilen erreicht ein Accessory nie */

	/* Applikation abmelden */
	appl_exit();

	/* fertig!!! */
	return(0);
}