/***************************************************************************
 IsTec
***************************************************************************/

//#define	BETA	1

#define	PRGNAME		"UFT-ISTEC"
#define	PRGVERSION	"1.3beta6"
#include "ENV:ADate.h"

static	char	Version[] = "$VER: "PRGNAME" "PRGVERSION" ("__AMIGADATE__")";
/* Für allgemeine Supportfunktionen soll die GUI benutzt werden */
#define	USEGUI

#define	MaxICLen	256
#define	Byte0(x)		((x >> 24) & 0xFF)
#define	Byte1(x)		((x >> 16) & 0xFF)
#define	Byte2(x)		((x >>  8) & 0xFF)
#define	Byte3(x)		((x >>  0) & 0xFF)
#define	Bytex(x, y)	((x >> (24-(8*y))) & 0xFF)

#define	EXITMAINSTART	 1
#define	EXITMAINSERIAL	10
#define	EXITMAINEND		20

#include "support.h"

void ICUpdateDevConfig(struct IC_BaseConfig *baseconfig, struct IC_DevConfig *config, int DevNumber, int Charge, int ChargeType);
struct	IC_RufConfig	*ICGetRufConfig(struct IC_RufConfig *IC_RufConfig, int Number, BOOL UpdateGUI);
void WaitTime(ULONG ms);
char *GetAliasName(char *Number);

#define	SERIAL_TIMEOUT_ERROR	429942
/* Die Systemgagets, die von dem Hauptprogramm verwaltet werden */
enum	{GAD_Gadgets = 1,
		GAD_Status, GAD_Save, GAD_Load, GAD_Use, GAD_Cancel, GAD_SaveQuit,

		GAD_BaseConfig_MIN,
		GAD_BaseConfig_Connection, GAD_BaseConfig_DevCount, GAD_BaseConfig_Protocol,
		GAD_BaseConfig_Version, GAD_BaseConfig_IntS0, GAD_BaseConfig_ExtS0,
		GAD_BaseConfig_Land_Popup, GAD_BaseConfig_Land_Nr, GAD_BaseConfig_TagNacht,
		GAD_BaseConfig_MSN0, GAD_BaseConfig_MSN1,
		GAD_BaseConfig_MSN2, GAD_BaseConfig_MSN3,
		GAD_BaseConfig_MSN4, GAD_BaseConfig_MSN5,
		GAD_BaseConfig_MSN6, GAD_BaseConfig_MSN7,
		GAD_BaseConfig_MSN8, GAD_BaseConfig_MSN9,
		GAD_BaseConfig_MSN0_Call, GAD_BaseConfig_MSN1_Call,
		GAD_BaseConfig_MSN2_Call, GAD_BaseConfig_MSN3_Call,
		GAD_BaseConfig_MSN4_Call, GAD_BaseConfig_MSN5_Call,
		GAD_BaseConfig_MSN6_Call, GAD_BaseConfig_MSN7_Call,
		GAD_BaseConfig_MSN8_Call, GAD_BaseConfig_MSN9_Call,
		GAD_BaseConfig_TFE_MainPage, GAD_BaseConfig_TFE_Select,
		GAD_BaseConfig_TFE_E,
		GAD_BaseConfig_TFE_T,
		GAD_BaseConfig_TFE_T_21, GAD_BaseConfig_TFE_T_22, GAD_BaseConfig_TFE_T_23, GAD_BaseConfig_TFE_T_24, GAD_BaseConfig_TFE_T_25, GAD_BaseConfig_TFE_T_26, GAD_BaseConfig_TFE_T_27, GAD_BaseConfig_TFE_T_28,
		GAD_BaseConfig_TFE_A,
		GAD_BaseConfig_MusicOnHold,
		GAD_BaseConfig_MAX,

		GAD_DevConfig_MIN,
		GAD_DevConfig_Page0,
		GAD_DevConfig_MSN0, GAD_DevConfig_MSN1, GAD_DevConfig_MSN2, GAD_DevConfig_MSN3, GAD_DevConfig_MSN4, GAD_DevConfig_MSN5, GAD_DevConfig_MSN6, GAD_DevConfig_MSN7, GAD_DevConfig_MSN8, GAD_DevConfig_MSN9,
		GAD_DevConfig_MSN0_Call, GAD_DevConfig_MSN1_Call, GAD_DevConfig_MSN2_Call, GAD_DevConfig_MSN3_Call, GAD_DevConfig_MSN4_Call, GAD_DevConfig_MSN5_Call, GAD_DevConfig_MSN6_Call, GAD_DevConfig_MSN7_Call, GAD_DevConfig_MSN8_Call, GAD_DevConfig_MSN9_Call,
		GAD_DevConfig_PIN, GAD_DevConfig_DialCaps, GAD_DevConfig_Service, GAD_DevConfig_ChargePulse, GAD_DevConfig_TerminalMode,
		GAD_DevConfig_Device, GAD_DevConfig_ChargeType, GAD_DevConfig_Charge, GAD_DevConfig_ChargeReset,
		GAD_DevConfig_Reroute, GAD_DevConfig_ExtNum, GAD_DevConfig_RerouteIfBusy, GAD_DevConfig_RingsUntilReroute, GAD_DevConfig_RerouteDelayed,
		GAD_DevConfig_EKnock0, GAD_DevConfig_EKnock1, GAD_DevConfig_EKnock2, GAD_DevConfig_EKnock3, GAD_DevConfig_EKnock4, GAD_DevConfig_EKnock5, GAD_DevConfig_EKnock6, GAD_DevConfig_EKnock7, GAD_DevConfig_EKnock8, GAD_DevConfig_EKnock9, 
		GAD_DevConfig_IKnock0, GAD_DevConfig_IKnock1, GAD_DevConfig_IKnock2, GAD_DevConfig_IKnock3, GAD_DevConfig_IKnock4, GAD_DevConfig_IKnock5, GAD_DevConfig_IKnock6, GAD_DevConfig_IKnock7, GAD_DevConfig_TKnock,
		GAD_DevConfig_MAX,

		GAD_RufConfig_MIN,
		GAD_RufConfig_LV, GAD_RufConfig_Number, GAD_RufConfig_Type, GAD_RufConfig_Call, GAD_RufConfig_K_S,
		GAD_RufConfig_Dev21, GAD_RufConfig_Dev22, GAD_RufConfig_Dev23, GAD_RufConfig_Dev24, GAD_RufConfig_Dev25, GAD_RufConfig_Dev26, GAD_RufConfig_Dev27, GAD_RufConfig_Dev28,
		GAD_RufConfig_MAX,

		GAD_MAINPAGE, GAD_PAGE0, GAD_PAGE1, GAD_PAGE2, GAD_PAGE3, GAD_PAGE4,
		GAD_LastGadget,

/* Die Systemmenues, die von dem Hauptprogramm verwaltet werden */
		MENU_Menus,
		MENU_Load, MENU_Save, MENU_Print, MENU_Version, MENU_Quit,
		MENU_Charge, MENU_ChargeReset,
		MENU_PrgConfig,
		MENU_ConfigReset, MENU_Reset,
		MENU_ReloadBase, MENU_ReloadDev, MENU_ReloadCharge, MENU_ReloadRuf,
		MENU_LastMenu};

#define  IE_UNDEFINED -1
#define  IE_PROTOKOLL 0x1300
#define  IE_ISTEC_TYP 0x1301
#define  IE_TRANSPORT 0x1302
#define  IE_INVALDATA 0x1303

/**************************************************************************/
/* Wichtige Include-Dateien */
#include "support_c"

/**************************************************************************/
/* Globale Vaiablen */
struct	LayoutHandle	*Handle;
struct	LayoutHandle	*MainHandle;
struct	Hook				 Handle_Locale;
struct	Window			*MainWindow;
struct	DiskObject		*diskobj;
struct	Keyfile			*Key;

struct	PrgConfig
{
	UWORD	UnitCost;
	char	DMname[10];
	BOOL	LoadAll;
	char	AliasListeName[100];
	char	ParseFile[256];
} PrgConfig;

/* Die Strukturen, die fuer die Istec-Konfiguration benoetigt
 * werden
 */

struct	IC_RufConfig
{
	struct	Node	Node;
	char				Number[50];
	UBYTE				ReadIn[100];
};

struct	IC_Changed
{
	BOOL	BaseConfig;
	BOOL	DevConfig[8];
	BOOL	Charge;
	BOOL	RufConfig[60];

} IC_Changed;

struct	IC_Loaded
{
	BOOL	DevConfig;
	BOOL	Charge;
	BOOL	RufConfig;
} IC_Loaded;

struct	List				IC_ShortList;
struct	IC_RufConfig	IC_RufConfig[60];
struct	IC_BaseConfig	IC_BaseConfig;
struct	IC_DevConfig	IC_DevConfig[8];
struct	IC_Charge		IC_Charge;
BOOL							IC_DayNight;
int							IC_Alarm;
struct	IC_DeviceNames
{
	char	Names[8][12];
	APTR	Dummy;
} IC_DeviceNames;
STRPTR						GAD_BaseConfig_MusicOnHold_Labels[11];
STRPTR						GAD_DevConfig_Device_Labels[9];
STRPTR						GAD_DevConfig_Reroute_Labels[11];
STRPTR						GAD_DevConfig_RerouteIfBusy_Labels[10];

struct	List				IC_AliasList;
struct	IC_Alias
{
	struct	Node	Node;
	char				Text[45];
	char				Name[22];
	char				Number[22];
};

/* Fuer die diversen Gadgets die Puffer */
char		gad_Status[256];
/* Allgemeines */
char		gad_Version[10];
char		gad_DevCount[4];
char		gad_IntS0[4];
char		gad_ExtS0[4];
char		gad_MSN[bcMSNCount][12];
/* Geräte */
char		gad_PIN[10];
char		gad_Charge[10];
char		gad_ExtNum[22];
/* Kurzwahlen */
char		gad_RufNummer[22];


enum	{BELGIEN = 32, FRANKREICH = 33, SPANIEN = 34, GROSSBRITANNIEN = 44, DEUTSCHLAND = 49};
enum	{PU_UNKNOWN = 0, PU_BELGIEN, PU_FRANKREICH, PU_SPANIEN, PU_GROSSBRITANNIEN, PU_DEUTSCHLAND};
STRPTR	LandesKennung_Labels[] = {"Unbekannt", "Belgien", "Frankreich", "Spanien", "Großbritannien", "Deutschland", NULL};
int		LandesKennung[] = {0, 32, 33, 34, 44, 49};

/**************************************************************************/

/* BCD2String
 * Wandelt eine BCD-Zahl in einen String um
 * String => Zeiger auf einen Speicherbereich, in den geschrieben werden soll
 * BCD    => Zeiger auf die BCD-Zahl
 * Count  => Anzahl Stellen, es wird bei Anzahl Stellen, bzw. beim Auftreten von $F abgebrochen
 * Type   => 0=Obere Nibble zuerst, 1=Untere Nibble
 */
void	BCD2String(char *String, UBYTE *BCD, WORD Count, int Type)
{
int	n;
	for(n = 0 ; n < Count ; n++)
	{
		String[n] = ((BCD[n/2] >> ((n%2) ? ((Type) ? 4 : 0) : ((Type ? 0 : 4))) ) & 0x0F) + '0';
		if(String[n] == (0x0F + '0')) break;
	}
	String[n] = 0x00;
}

/* String2BCD
 * Wandelt eine String in einen BCD-Zahl um
 * String => Zeiger auf einen Speicherbereich
 * BCD    => Zeiger auf die BCD-Zahl, in die geschrieben werden soll
 * Count  => Anzahl BCD-Bytes, es wird bei Anzahl Bytes abgebrochen
 * Type   => 0=Obere Nibble zuerst, 1=Untere Nibble
 */
void	String2BCD(UBYTE *BCD, char *String, WORD Count, int Type)
{
int	n;
char	new[100];
	strcpy(new, String);
	for(n = strlen(new) ; n < (2*Count + 1) ; n++)
		new[n] = '0' + 0x0F;
	for(n = 0 ; n < Count ; n++)
	{
		BCD[n] = (((new[n*2 + (Type ? 1 : 0)] - '0') & 0x0F) << 4) + ((new[n*2 + (Type ? 0 : 1)] - '0') & 0x0F);
	}
}


#include "Istec_Support_c"

struct Window *OpenMainWindow(void)
{
	Key = GetKeyfile();
	if(Handle = LT_CreateHandleTags(NULL, LH_AutoActivate, FALSE, TAG_DONE))
	{
	struct	Window	*Window;

		MainHandle = Handle;

		LT_New(Handle,
					LA_Type,				VERTICAL_KIND,
					TAG_DONE);
		{
		static	STRPTR	Labels[] = {"Allgemeines", "Anlage", "Geräte", "Kurzwahl", NULL};
			LT_New(Handle,
						LA_Type,				TAB_KIND,
						LA_ID,				GAD_MAINPAGE,
						LATB_Labels,		Labels,
						LATB_Active,		0,
						TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,						VERTICAL_KIND,
					LA_ID,						GAD_PAGE0,
					LAGR_ActivePage,			0,
					LAGR_SameSize,				TRUE,
					TAG_DONE);
				{
					/* Allgemeines */
					LT_New(Handle,
						LA_Type,						VERTICAL_KIND,
						TAG_DONE);
					{
					static   STRPTR   Lines[12];
					static	char		Name[40];
						Lines[0] = PRGNAME;
						Lines[1] = "Mit diesem Programm können die ISTEC100x_Telefonanlagen";
						Lines[2] = "konfiguriert werden. Es werden auch die neuen Features";
						Lines[3] = "der Firmware 2.x unterstützt!";
						Lines[4] = "";
						if((Key == (struct Keyfile *)-1) ||
							(Key == NULL))
							Lines[5] = "Dieses Programm ist Shareware!";
						else
							sprintf(Name, "Registriert auf %s %s", Key->Vorname, Key->Name), Lines[5] = Name;
						Lines[6] = "";
						Lines[7] = "Version "PRGVERSION;
						Lines[8] = "©1997-99 Swen K. Stullich";
						Lines[9] = "-= United Forces Tools =-";
						Lines[10] = "EMAIL: Stullich@gmx.de";

					   LT_New(Handle,
   				      LA_Type,                BOX_KIND,
   				      LABX_Lines,					Lines,
					      LABX_AlignText,         ALIGNTEXT_CENTERED,
					      LABX_DrawBox,           TRUE,
					      TAG_DONE);
					}
					LT_EndGroup(Handle);
					/* BaseConfig */
					LT_New(Handle,
						LA_Type,						VERTICAL_KIND,
						TAG_DONE);
						#include "BaseConfigPage_c"
					LT_EndGroup(Handle);
					/* Geräte */
					LT_New(Handle,
						LA_Type,						VERTICAL_KIND,
						TAG_DONE);
						#include "DevConfigPage_c"
					LT_EndGroup(Handle);
					/* Kurzwahl/Sperre */
					LT_New(Handle,
						LA_Type,						VERTICAL_KIND,
						TAG_DONE);
						#include "RufConfigPage_c"
					LT_EndGroup(Handle);
				}
				LT_EndGroup(Handle);
			}
			LT_New(Handle, LA_Type, XBAR_KIND, LAXB_FullSize, TRUE, TAG_DONE);
			LT_New(Handle, LA_Type, VERTICAL_KIND, TAG_DONE);
				LT_New(Handle,
					LA_Type,					TEXT_KIND,
					LA_ID,					GAD_Status,
					LA_LabelText,			"Status:",
					LA_Chars,				4*LT_LabelChars(Handle, "MMMMMMMMMM"),
					GTTX_Border,			TRUE,
					TAG_DONE);
			LT_EndGroup(Handle);
			if(Key)
			{
				LT_New(Handle, LA_Type, XBAR_KIND, LAXB_FullSize, TRUE, TAG_DONE);
				LT_New(Handle, LA_Type, HORIZONTAL_KIND, LAGR_Spread, TRUE, LAGR_SameSize, TRUE, TAG_DONE);
				{
					LT_New(Handle,
						LA_Type,					BUTTON_KIND,
						LA_ID,					GAD_Save,
						LA_LabelText,			"Speichern",
						LA_ExtraFat,			TRUE,
						TAG_DONE);
					LT_New(Handle,
						LA_Type,					BUTTON_KIND,
						LA_ID,					GAD_Cancel,
						LA_LabelText,			"Beenden",
						LA_ExtraFat,			TRUE,
						TAG_DONE);
				}
				LT_EndGroup(Handle);
			}
		}
		LT_EndGroup(Handle);

		if(Window = LT_Build(Handle,
									LAWN_Title,			PRGNAME, //GS(MSG_MAIN_TITLE),
									LAWN_IDCMP,			IDCMP_CLOSEWINDOW|IDCMP_GADGETDOWN|IDCMP_GADGETUP|IDCMP_MENUPICK|IDCMP_RAWKEY|IDCMP_REFRESHWINDOW,
									LAWN_Zoom,			TRUE,
									LAWN_SmartZoom,	TRUE,
//										LAWN_Left,			0,
//										LAWN_Top,			11,
//									LAWN_Show,			FALSE,
									WA_CloseGadget,	TRUE,
									WA_DragBar,			TRUE,
									WA_Activate,		TRUE,
									WA_DepthGadget,	TRUE,
									WA_NewLookMenus,	TRUE,
									TAG_DONE))
			return(Window);

		LT_DeleteHandle(Handle);
	}
	return(NULL);
}


/* Menu_ChangePrgConfig */
#include "SetConfig_c"
#include "Menu_Support_c"



/* SelectAlias
 * Laesst den Benutzer einen der Aliase auswaehlen
 * und gibt den entsprechenden Eintrag zurueck, bzw.
 * NULL bei Abbruch/Fehler
 */
struct IC_Alias *SelectAlias(void)
{
struct	LayoutHandle	*Handle;
struct	IC_Alias			*al = NULL;

	if((!IsListEmpty(&IC_AliasList))	&&
		(Handle = LT_CreateHandleTags(NULL, TAG_DONE)))
	{
	struct	Window	*Window;
	BOOL					 done = FALSE;
	char					 WinTitle[] = PRGNAME ": Alias auswählen";

		LT_New(Handle, LA_Type, VERTICAL_KIND, TAG_DONE);
			LT_New(Handle, LA_Type, LISTVIEW_KIND, LA_ID, 42, LALV_Lines, 10, LALV_MinLines, 10, GTLV_Labels, &IC_AliasList, LALV_ResizeY, TRUE, LA_Chars, 39, GTLV_ShowSelected, NULL, TAG_DONE);
		LT_EndGroup(Handle);

		if(Window = LT_Build(Handle,
									LAWN_Title,			WinTitle,
									LAWN_IDCMP,			IDCMP_CLOSEWINDOW|IDCMP_GADGETDOWN|IDCMP_GADGETUP|IDCMP_RAWKEY|IDCMP_REFRESHWINDOW,
									LAWN_Zoom,			TRUE,
									LAWN_SmartZoom,	TRUE,
									WA_CloseGadget,	TRUE,
									WA_DragBar,			TRUE,
									WA_Activate,		TRUE,
									WA_DepthGadget,	TRUE,
									TAG_DONE))
		do
		{
			WaitPort(Window -> UserPort);
			while(Message = GT_GetIMsg(Window->UserPort))
			{
				MsgClass			= Message->Class;
				MsgCode			= Message->Code;
				MsgQualifier	= Message->Qualifier;
				MsgGadget		= Message->IAddress;

				GT_ReplyIMsg(Message);
				LT_HandleInput(Handle, MsgQualifier, &MsgClass, &MsgCode, &MsgGadget);

				switch(MsgClass)
				{
					case	IDCMP_CLOSEWINDOW:
						done = TRUE;
						break;
					case	IDCMP_GADGETUP:
						switch(MsgGadget->GadgetID)
						{
							case	42:
								{
								int	n = LT_GetAttributes(Handle, 42, TAG_DONE);
									al = (struct IC_Alias *)IC_AliasList.lh_Head;
									while(n--)
										al = (struct IC_Alias *)al->Node.ln_Succ;
								}
								done = TRUE;
							break;
						}
						break;
				}
			}
		}
		while(!done);

		LT_DeleteHandle(Handle);
	}
	return(al);
}

/* GetAliasName
 * Vergleicht die Nummer mit der Rufnummernliste
 * und gibt entweder den gefundenen Namen zurück,
 * oder die Nummer
 * Number => Zeichenkette mit der Rufnummer
 * Rückgabewert => Zeichenkette auf Aliasnamen oder Übergabeparameter
 */
char *GetAliasName(char *Number)
{
	if(!IsListEmpty(&IC_AliasList))
	{
	struct	IC_Alias	*al = (struct IC_Alias *)&IC_AliasList;

		while(al = (struct IC_Alias *)al->Node.ln_Succ)
			if(!strcmp(Number, al->Number))
				return(al->Name);
	}
	return(Number);
}




struct	ParseStruct
{
	/* Parameter auf die ParseZeile */
	BPTR		infh;
	STRPTR	ParseText;
	STRPTR	ParseTextCopy;
	ULONG		ParseLen;
	/* Parameter auf einen Hilfspuffer */
	STRPTR	Buffer;
	ULONG		BufferLen;

	ULONG		ParseError;

	/* Individuelle Parameter, die waehrend der Auswertung veraendert werden koennen */

	ULONG		UseDev;				/* Geraet, das gerade verwendet wird */
	ULONG		UseKWV;				/* Kurzwahlnr. die gerade verwendet wird */

	ULONG		PrintMask;			/* Daten die gedruckt werden sollen */
	ULONG		PrintVal;			/* Aktuelle Ebene (z.B. DEV_21_START, ...) **/

	LONG		LoopPos;				/* Position, ab der geloopt werden soll */
	ULONG		LoopCount;			/* Aktueller Wert fuer Loop */
	ULONG		LoopEnd;				/* Endwert fuer Loop */
};
enum {PARSE_ERROR_BRACKET = 42, PARSE_ERROR_NOVAR, PARSE_ERROR_WRONG_VALUE, PARSE_ERROR_LARGE_TEXT, PARSE_ERROR_LINETERM};
#define	PS_BAS		  1
#define	PS_DEV		  2
#define	PS_DEV21		  4
#define	PS_DEV22		  8
#define	PS_DEV23		 16
#define	PS_DEV24		 32
#define	PS_DEV25		 64
#define	PS_DEV26		128
#define	PS_DEV27		256
#define	PS_DEV28		512
#define	PS_CHA	  1024
#define	PS_KWV	  2048


enum		{PAR_TIME = 0, PAR_DATE, PAR_NL, PAR_TAB,
	PAR_PRG_NAME, PAR_PRG_VERSION,

	PAR_LOOP, PAR_LOOP_START, PAR_LOOP_NEXT,

	PAR_BAS_START, PAR_BAS_END, 
	PAR_DEV_START, PAR_DEV_END, PAR_DEV21_START, PAR_DEV21_END, PAR_DEV22_START, PAR_DEV22_END, PAR_DEV23_START, PAR_DEV23_END, PAR_DEV24_START, PAR_DEV24_END, PAR_DEV25_START, PAR_DEV25_END, PAR_DEV26_START, PAR_DEV26_END, PAR_DEV27_START, PAR_DEV27_END, PAR_DEV28_START, PAR_DEV28_END,
	PAR_CHA_START, PAR_CHA_END, PAR_KWV_START, PAR_KWV_END,

	PAR_BAS_PROTOCOL, PAR_BAS_CONNECTION, PAR_BAS_VERSION, PAR_BAS_DEVCOUNT, PAR_BAS_INTS0, PAR_BAS_EXTS0,
	PAR_BAS_COUNTRYCODE, PAR_BAS_COUNTRY, PAR_BAS_DAYNIGHT,
	PAR_BAS_MSN0, PAR_BAS_MSN1, PAR_BAS_MSN2, PAR_BAS_MSN3, PAR_BAS_MSN4, PAR_BAS_MSN5, PAR_BAS_MSN6, PAR_BAS_MSN7, PAR_BAS_MSN8, PAR_BAS_MSN9,
	PAR_BAS_MSN0_STAT, PAR_BAS_MSN1_STAT, PAR_BAS_MSN2_STAT, PAR_BAS_MSN3_STAT, PAR_BAS_MSN4_STAT, PAR_BAS_MSN5_STAT, PAR_BAS_MSN6_STAT, PAR_BAS_MSN7_STAT, PAR_BAS_MSN8_STAT, PAR_BAS_MSN9_STAT,
	PAR_BAS_MOH,
	PAR_BAS_TFE_TYP, PAR_BAS_TFE_EMMERICH, PAR_BAS_TFE_ALARM,
	PAR_BAS_TFE_T1_21, PAR_BAS_TFE_T1_22, PAR_BAS_TFE_T1_23, PAR_BAS_TFE_T1_24, PAR_BAS_TFE_T1_25, PAR_BAS_TFE_T1_26, PAR_BAS_TFE_T1_27, PAR_BAS_TFE_T1_28,
	PAR_BAS_TFE_T2_21, PAR_BAS_TFE_T2_22, PAR_BAS_TFE_T2_23, PAR_BAS_TFE_T2_24, PAR_BAS_TFE_T2_25, PAR_BAS_TFE_T2_26, PAR_BAS_TFE_T2_27, PAR_BAS_TFE_T2_28,
	PAR_BAS_TFE_T3_21, PAR_BAS_TFE_T3_22, PAR_BAS_TFE_T3_23, PAR_BAS_TFE_T3_24, PAR_BAS_TFE_T3_25, PAR_BAS_TFE_T3_26, PAR_BAS_TFE_T3_27, PAR_BAS_TFE_T3_28,
	PAR_BAS_TFE_T4_21, PAR_BAS_TFE_T4_22, PAR_BAS_TFE_T4_23, PAR_BAS_TFE_T4_24, PAR_BAS_TFE_T4_25, PAR_BAS_TFE_T4_26, PAR_BAS_TFE_T4_27, PAR_BAS_TFE_T4_28,

	PAR_DEV_21_NAME, PAR_DEV_22_NAME, PAR_DEV_23_NAME, PAR_DEV_24_NAME, PAR_DEV_25_NAME, PAR_DEV_26_NAME, PAR_DEV_27_NAME, PAR_DEV_28_NAME,
	PAR_DEV_NAME,
	PAR_DEV_MSN0, PAR_DEV_MSN1, PAR_DEV_MSN2, PAR_DEV_MSN3, PAR_DEV_MSN4, PAR_DEV_MSN5, PAR_DEV_MSN6, PAR_DEV_MSN7, PAR_DEV_MSN8, PAR_DEV_MSN9,
	PAR_DEV_PIN, PAR_DEV_SERVICE, PAR_DEV_CAPS, PAR_DEV_MODE, PAR_DEV_PULSE,
	PAR_DEV_REROUTE, PAR_DEV_REROUTENO, PAR_DEV_REROUTEBUSY, PAR_DEV_REROUTEDELAY, PAR_DEV_REROUTERINGS,
	PAR_DEV_KNOCKMSN0, PAR_DEV_KNOCKMSN1, PAR_DEV_KNOCKMSN2, PAR_DEV_KNOCKMSN3, PAR_DEV_KNOCKMSN4, PAR_DEV_KNOCKMSN5, PAR_DEV_KNOCKMSN6, PAR_DEV_KNOCKMSN7, PAR_DEV_KNOCKMSN8, PAR_DEV_KNOCKMSN9,
	PAR_DEV_KNOCKDEV21, PAR_DEV_KNOCKDEV22, PAR_DEV_KNOCKDEV23, PAR_DEV_KNOCKDEV24, PAR_DEV_KNOCKDEV25, PAR_DEV_KNOCKDEV26, PAR_DEV_KNOCKDEV27, PAR_DEV_KNOCKDEV28,
	PAR_DEV_KNOCKTFE,
	PAR_DEV_CHARGE_E, PAR_DEV_CHARGE_M,

	PAR_CHA_21_E, PAR_CHA_22_E, PAR_CHA_23_E, PAR_CHA_24_E, PAR_CHA_25_E, PAR_CHA_26_E, PAR_CHA_27_E, PAR_CHA_28_E,
	PAR_CHA_21_M, PAR_CHA_22_M, PAR_CHA_23_M, PAR_CHA_24_M, PAR_CHA_25_M, PAR_CHA_26_M, PAR_CHA_27_M, PAR_CHA_28_M,
	PAR_CHA_ALL_E, PAR_CHA_ALL_M,
	PAR_CHA_CURRENCY,

	PAR_KWV_NUMMER, PAR_KWV_STAT,
	PAR_KWV_21_STAT, PAR_KWV_22_STAT, PAR_KWV_23_STAT, PAR_KWV_24_STAT, PAR_KWV_25_STAT, PAR_KWV_26_STAT, PAR_KWV_27_STAT, PAR_KWV_28_STAT,
	PAR_KWV_SPEICHER,
	PAR_KWV_301_USE, PAR_KWV_302_USE, PAR_KWV_303_USE, PAR_KWV_304_USE, PAR_KWV_305_USE, PAR_KWV_306_USE, PAR_KWV_307_USE, PAR_KWV_308_USE, PAR_KWV_309_USE, PAR_KWV_310_USE,
	PAR_KWV_311_USE, PAR_KWV_312_USE, PAR_KWV_313_USE, PAR_KWV_314_USE, PAR_KWV_315_USE, PAR_KWV_316_USE, PAR_KWV_317_USE, PAR_KWV_318_USE, PAR_KWV_319_USE, PAR_KWV_320_USE,
	PAR_KWV_321_USE, PAR_KWV_322_USE, PAR_KWV_323_USE, PAR_KWV_324_USE, PAR_KWV_325_USE, PAR_KWV_326_USE, PAR_KWV_327_USE, PAR_KWV_328_USE, PAR_KWV_329_USE, PAR_KWV_330_USE,
	PAR_KWV_331_USE, PAR_KWV_332_USE, PAR_KWV_333_USE, PAR_KWV_334_USE, PAR_KWV_335_USE, PAR_KWV_336_USE, PAR_KWV_337_USE, PAR_KWV_338_USE, PAR_KWV_339_USE, PAR_KWV_340_USE,
	PAR_KWV_341_USE, PAR_KWV_342_USE, PAR_KWV_343_USE, PAR_KWV_344_USE, PAR_KWV_345_USE, PAR_KWV_346_USE, PAR_KWV_347_USE, PAR_KWV_348_USE, PAR_KWV_349_USE, PAR_KWV_350_USE,
	PAR_KWV_351_USE, PAR_KWV_352_USE, PAR_KWV_353_USE, PAR_KWV_354_USE, PAR_KWV_355_USE, PAR_KWV_356_USE, PAR_KWV_357_USE, PAR_KWV_358_USE, PAR_KWV_359_USE, PAR_KWV_360_USE,

	MAX_PARPAT};


STRPTR	PARPAT[] = {"TIME", "DATE", "NL", "TAB",
	"PRG_Name", "PRG_Version",

	"Loop", "Loop_Start", "Loop_Next",

	"BAS_START", "BAS_END",
	"DEV_START", "DEV_END", "DEV_21_START", "DEV_21_END", "DEV_22_START", "DEV_22_END", "DEV_23_START", "DEV_23_END", "DEV_24_START", "DEV_24_END", "DEV_25_START", "DEV_25_END", "DEV_26_START", "DEV_26_END", "DEV_27_START", "DEV_27_END", "DEV_28_START", "DEV_28_END",
	"CHA_START", "CHA_END", "KWV_START", "KWV_END",

	"BAS_Protocol", "BAS_Connection", "BAS_Version", "BAS_DevCount", "BAS_IntS0", "BAS_ExtS0",
	"BAS_Country_Code", "BAS_Country", "BAS_DayNight",
	"BAS_MSN0", "BAS_MSN1", "BAS_MSN2", "BAS_MSN3", "BAS_MSN4", "BAS_MSN5", "BAS_MSN6", "BAS_MSN7", "BAS_MSN8", "BAS_MSN9",
	"BAS_MSN0_Stat", "BAS_MSN1_Stat", "BAS_MSN2_Stat", "BAS_MSN3_Stat", "BAS_MSN4_Stat", "BAS_MSN5_Stat", "BAS_MSN6_Stat", "BAS_MSN7_Stat", "BAS_MSN8_Stat", "BAS_MSN9_Stat",
	"BAS_MOH",
	"BAS_TFE_Typ", "BAS_TFE_Emmerich", "BAS_TFE_Alarm",
	"BAS_TFE_T1_21", "BAS_TFE_T1_22", "BAS_TFE_T1_23", "BAS_TFE_T1_24", "BAS_TFE_T1_25", "BAS_TFE_T1_26", "BAS_TFE_T1_27", "BAS_TFE_T1_28",
	"BAS_TFE_T2_21", "BAS_TFE_T2_22", "BAS_TFE_T2_23", "BAS_TFE_T2_24", "BAS_TFE_T2_25", "BAS_TFE_T2_26", "BAS_TFE_T2_27", "BAS_TFE_T2_28",
	"BAS_TFE_T3_21", "BAS_TFE_T3_22", "BAS_TFE_T3_23", "BAS_TFE_T3_24", "BAS_TFE_T3_25", "BAS_TFE_T3_26", "BAS_TFE_T3_27", "BAS_TFE_T3_28",
	"BAS_TFE_T4_21", "BAS_TFE_T4_22", "BAS_TFE_T4_23", "BAS_TFE_T4_24", "BAS_TFE_T4_25", "BAS_TFE_T4_26", "BAS_TFE_T4_27", "BAS_TFE_T4_28",

	"DEV_21_Name", "DEV_22_Name", "DEV_23_Name", "DEV_24_Name", "DEV_25_Name", "DEV_26_Name", "DEV_27_Name", "DEV_28_Name",
	"DEV_Name",
	"DEV_MSN0", "DEV_MSN1", "DEV_MSN2", "DEV_MSN3", "DEV_MSN4", "DEV_MSN5", "DEV_MSN6", "DEV_MSN7", "DEV_MSN8", "DEV_MSN9",
	"DEV_PIN", "DEV_Service", "DEV_Caps", "DEV_Mode", "DEV_Pulse",
	"DEV_Reroute", "DEV_RerouteNo", "DEV_RerouteBusy", "DEV_RerouteDelay", "DEV_RerouteRings",
	"DEV_KnockMSN0", "DEV_KnockMSN1", "DEV_KnockMSN2", "DEV_KnockMSN3", "DEV_KnockMSN4", "DEV_KnockMSN5", "DEV_KnockMSN6", "DEV_KnockMSN7", "DEV_KnockMSN8", "DEV_KnockMSN9",
	"DEV_KnockDEV21", "DEV_KnockDEV22", "DEV_KnockDEV23", "DEV_KnockDEV24", "DEV_KnockDEV25", "DEV_KnockDEV26", "DEV_KnockDEV27", "DEV_KnockDEV28",
	"DEV_KnockTFE",
	"DEV_Charge_E", "DEV_Charge_M",

	"CHA_21_E", "CHA_22_E", "CHA_23_E", "CHA_24_E", "CHA_25_E", "CHA_26_E", "CHA_27_E", "CHA_28_E",
	"CHA_21_M", "CHA_22_M", "CHA_23_M", "CHA_24_M", "CHA_25_M", "CHA_26_M", "CHA_27_M", "CHA_28_M",
	"CHA_All_E", "CHA_All_M",
	"CHA_Currency",

	"KWV_Nummer", "KWV_Stat",
	"KWV_21_Stat", "KWV_22_Stat", "KWV_23_Stat", "KWV_24_Stat", "KWV_25_Stat", "KWV_26_Stat", "KWV_27_Stat", "KWV_28_Stat",
	"KWV_Speicher",
	"KWV_301_Use", "KWV_302_Use", "KWV_303_Use", "KWV_304_Use", "KWV_305_Use", "KWV_306_Use", "KWV_307_Use", "KWV_308_Use", "KWV_309_Use", "KWV_310_Use",
	"KWV_311_Use", "KWV_312_Use", "KWV_313_Use", "KWV_314_Use", "KWV_315_Use", "KWV_316_Use", "KWV_317_Use", "KWV_318_Use", "KWV_319_Use", "KWV_320_Use",
	"KWV_321_Use", "KWV_322_Use", "KWV_323_Use", "KWV_324_Use", "KWV_325_Use", "KWV_326_Use", "KWV_327_Use", "KWV_328_Use", "KWV_329_Use", "KWV_330_Use",
	"KWV_331_Use", "KWV_332_Use", "KWV_333_Use", "KWV_334_Use", "KWV_335_Use", "KWV_336_Use", "KWV_337_Use", "KWV_338_Use", "KWV_339_Use", "KWV_340_Use",
	"KWV_341_Use", "KWV_342_Use", "KWV_343_Use", "KWV_344_Use", "KWV_345_Use", "KWV_346_Use", "KWV_347_Use", "KWV_348_Use", "KWV_349_Use", "KWV_350_Use",
	"KWV_351_Use", "KWV_352_Use", "KWV_353_Use", "KWV_354_Use", "KWV_355_Use", "KWV_356_Use", "KWV_357_Use", "KWV_358_Use", "KWV_359_Use", "KWV_360_Use",

	NULL};

BOOL	Parse(struct ParseStruct *PS)
{
char	*ParseText = PS->ParseText;
ULONG	 len = PS->ParseLen;
char	*PT = ParseText;
char	*PE, *PA;	/* Start und Ende des Textes im Puffer */
long	 PLen = 0;	/* Laenge des Rueckgabetextes */
char	*BP , *BN;	/* Positivtext, Negativtext */
int	i;

	/* Ueberhaupt eine Variable? */
	i = 0;
	while((ParseText[i] != '{') && (ParseText[i] != 0x00))
		i++;
	if(ParseText[i] == 0x00) return(TRUE);

	/* Suche nach }-Zeichen */
	{
		while((*PT != '}') && (*PT != 0x00))
			PT++;
		if(*PT == 0x00)
		{
			PS->ParseError = PARSE_ERROR_BRACKET;
			return (FALSE);
		}
		/* EndePointer setzen */
		PE = PT;
		while(*PT != '{') PT--;
		/* StartPointer setzen */
		PA = PT;

		/* Leere Variable! */
		if(PA == (PE - 1))
		{
			PS->ParseError = PARSE_ERROR_NOVAR;
			return (FALSE);
		}
	}

	/* Kopiere den zu bearbeitenden Text */
	PT = PA + 1;
	i = 0;
	while(PT < PE) PS->Buffer[i++] = *PT++;
	PS->Buffer[i] = 0x00;

	/* Pruefe nach, ob eine Feldlaengenbegrenzung erfolgen soll */
	if((isdigit(PS->Buffer[0])) || (PS->Buffer[0] == '-'))
	{
	int	i = 0;
		if(PS->Buffer[0] == '-') i++;
		while((PS->Buffer[i] != 0x00) && (isdigit(PS->Buffer[i]))) i++;
		if(PS->Buffer[i] != '\\')
		{
			PS->ParseError = PARSE_ERROR_WRONG_VALUE;
			return(FALSE);
		}
		PLen = atol(PS->Buffer);
		strcpy(PS->Buffer, &PS->Buffer[i+1]);
	}

	/* Zerlege in Variablennamen, PositivText, NegativText */
	BP = BN = NULL;
	{
	int	i = 0;
		/* NegativText */
		while((PS->Buffer[i] != 0x00) && (PS->Buffer[i] != '\\')) i++;
		if(PS->Buffer[i] == '\\')
		{
			PS->Buffer[i++] = 0x00;
			BN = &PS->Buffer[i];
			/* PositivText */
			while((PS->Buffer[i] != 0x00) && (PS->Buffer[i] != '\\')) i++;
			if(PS->Buffer[i] == '\\')
			{
				PS->Buffer[i++] = 0x00;
				BP = &PS->Buffer[i];
			}
		}
	}
	/* Suche die Variable raus und setze den Wert in PS->Buffer ein */
	{
	int	ParseID;
	char	Buf[256];
		for(ParseID = 0 ; ParseID < MAX_PARPAT ; ParseID++)
			if(!stricmp(PS->Buffer, PARPAT[ParseID]))
				break;

		switch(ParseID)
		{
#define	PS_PTEXT(x)	if(BP) strcpy(PS->Buffer, BP); else strcpy(PS->Buffer, x)
#define	PS_NTEXT(x)	if(BN) strcpy(PS->Buffer, BN); else strcpy(PS->Buffer, x)
		/* Default Parse-Variablen */
			default:
				{
					sprintf(Buf, "»Unbekannte Variable: \"%s\"«", PS->Buffer);
					PS_PTEXT(Buf);
				}
				break;
			case	PAR_TIME:
				{
				struct	tm	*zeit;
				time_t	sec;
					time(&sec);
					zeit = localtime(&sec);
					sprintf(Buf, "%02ld:%02ld:%02ld", zeit->tm_hour, zeit->tm_min, zeit->tm_sec);
					PS_PTEXT(Buf);
				}
				break;
			case	PAR_DATE:
				{
				struct	tm	*zeit;
				time_t	sec;
					time(&sec);
					zeit = localtime(&sec);
					sprintf(Buf, "%02ld.%02ld.%02ld", zeit->tm_mday, zeit->tm_mon + 1, zeit->tm_year);
					PS_PTEXT(Buf);
				}
				break;
			case	PAR_NL:
				PS_PTEXT("\n");
				break;
			case	PAR_TAB:
				PS_PTEXT("\t");
				break;

		/* Ab hier kommem spezielle ParsePattern */
			case	PAR_LOOP:
				sprintf(Buf, "%ld", PS->LoopCount);
				PS_PTEXT(Buf);
				break;
			case	PAR_LOOP_START:
				PS->LoopCount = atoi(BN);
				PS->LoopEnd   = atoi(BP);
				PS->LoopPos   = Seek(PS->infh, 0, OFFSET_CURRENT);
				strcpy(PS->Buffer, "");
				break;
			case	PAR_LOOP_NEXT:
				if(atoi(BN))
					PS->LoopCount += atoi(BN);
				else
				{
					if(PS->LoopCount > PS->LoopEnd)
						PS->LoopCount--;
					if(PS->LoopCount < PS->LoopEnd)
						PS->LoopCount++;
				}
				if(PS->LoopCount != PS->LoopEnd)
					Seek(PS->infh, PS->LoopPos, OFFSET_BEGINNING);
				strcpy(PS->Buffer, "");
				if(PS->ParseText[strlen(PS->ParseText) - 1] == '\n')
					PS->ParseText[strlen(PS->ParseText) - 1] = 0x00;
				break;

			case	PAR_PRG_NAME:
				PS_PTEXT(PRGNAME);
				break;
			case	PAR_PRG_VERSION:
				PS_PTEXT(PRGVERSION);
				break;

		/* Ausgabesteuerung */
#define	PS_SETON(x)		PS->PrintVal |= x; PS_PTEXT(""); break;
#define	PS_SETOFF(x)	PS->PrintVal &= ~x; PS_PTEXT(""); break;
			case	PAR_BAS_START:
				PS_SETON(PS_BAS);
			case	PAR_BAS_END:
				PS_SETOFF(PS_BAS);
			case	PAR_DEV_START:
				PS_SETON(PS_DEV);
			case	PAR_DEV_END:
				PS_SETOFF(PS_DEV);
			case	PAR_DEV21_START:
				PS->UseDev = 0;
				PS_SETON(PS_DEV21);
			case	PAR_DEV21_END:
				PS_SETOFF(PS_DEV21);
			case	PAR_DEV22_START:
				PS->UseDev = 1;
				PS_SETON(PS_DEV22);
			case	PAR_DEV22_END:
				PS_SETOFF(PS_DEV22);
			case	PAR_DEV23_START:
				PS->UseDev = 2;
				PS_SETON(PS_DEV23);
			case	PAR_DEV23_END:
				PS_SETOFF(PS_DEV23);
			case	PAR_DEV24_START:
				PS->UseDev = 3;
				PS_SETON(PS_DEV24);
			case	PAR_DEV24_END:
				PS_SETOFF(PS_DEV24);
			case	PAR_DEV25_START:
				PS->UseDev = 4;
				PS_SETON(PS_DEV25);
			case	PAR_DEV25_END:
				PS_SETOFF(PS_DEV25);
			case	PAR_DEV26_START:
				PS->UseDev = 5;
				PS_SETON(PS_DEV26);
			case	PAR_DEV26_END:
				PS_SETOFF(PS_DEV26);
			case	PAR_DEV27_START:
				PS->UseDev = 6;
				PS_SETON(PS_DEV27);
			case	PAR_DEV27_END:
				PS_SETOFF(PS_DEV27);
			case	PAR_DEV28_START:
				PS->UseDev = 7;
				PS_SETON(PS_DEV28);
			case	PAR_DEV28_END:
				PS_SETOFF(PS_DEV28);
			case	PAR_CHA_START:
				PS_SETON(PS_CHA);
			case	PAR_CHA_END:
				PS_SETOFF(PS_CHA);
			case	PAR_KWV_START:
				PS_SETON(PS_KWV);
			case	PAR_KWV_END:
				PS_SETOFF(PS_KWV);

		/* Anlagenkonfig */
			case	PAR_BAS_PROTOCOL:
				PS_PTEXT("E-DSS1 (Euro)");
				break;
			case	PAR_BAS_CONNECTION:
				PS_PTEXT("Mehrgeräte");
				break;
			case	PAR_BAS_VERSION:
				sprintf(Buf, "%ld.%ld", IC_BaseConfig.VersionHigh, IC_BaseConfig.VersionLow);
				PS_PTEXT(Buf);
				break;
			case	PAR_BAS_DEVCOUNT:
				sprintf(Buf, "%ld", IC_BaseConfig.DevCount);
				PS_PTEXT(Buf);
				break;
			case	PAR_BAS_INTS0:
				sprintf(Buf, "%ld", IC_BaseConfig.IntS0);
				PS_PTEXT(Buf);
				break;
			case	PAR_BAS_EXTS0:
				sprintf(Buf, "%ld", IC_BaseConfig.ExtS0);
				PS_PTEXT(Buf);
				break;
			case	PAR_BAS_COUNTRYCODE:
				{
				int	Country = IC_BaseConfig.CountryCode[0];
					Country = Country << 8;
					Country = Country + (int)IC_BaseConfig.CountryCode[1];
					sprintf(Buf, "%04ld", Country);
					PS_PTEXT(Buf);
				}
				break;
			case	PAR_BAS_COUNTRY:
				{
				int	i;
				int	Country = IC_BaseConfig.CountryCode[0];
					Country = Country << 8;
					Country = Country + (int)IC_BaseConfig.CountryCode[1];
					for(i = 1 ; i < (sizeof(LandesKennung) / sizeof(STRPTR)) ; i++)
						if(Country == LandesKennung[i])
						{
							PS_PTEXT(LandesKennung_Labels[i]);
							i = 999;
						}
					if(i < 999)
						PS_NTEXT("Unbekannt");
				}
				break;
			case	PAR_BAS_DAYNIGHT:
				if(!IC_DayNight)
					PS_PTEXT("Tag");
				else
					PS_NTEXT("Nacht");
				break;
			case	PAR_BAS_MSN0:
			case	PAR_BAS_MSN1:
			case	PAR_BAS_MSN2:
			case	PAR_BAS_MSN3:
			case	PAR_BAS_MSN4:
			case	PAR_BAS_MSN5:
			case	PAR_BAS_MSN6:
			case	PAR_BAS_MSN7:
			case	PAR_BAS_MSN8:
			case	PAR_BAS_MSN9:
				if(strlen(gad_MSN[ParseID - PAR_BAS_MSN0]))
					PS_PTEXT(gad_MSN[ParseID - PAR_BAS_MSN0]);
				else
					PS_NTEXT("keine");
				break;
			case	PAR_BAS_MSN0_STAT:
			case	PAR_BAS_MSN1_STAT:
			case	PAR_BAS_MSN2_STAT:
			case	PAR_BAS_MSN3_STAT:
			case	PAR_BAS_MSN4_STAT:
			case	PAR_BAS_MSN5_STAT:
			case	PAR_BAS_MSN6_STAT:
			case	PAR_BAS_MSN7_STAT:
			case	PAR_BAS_MSN8_STAT:
			case	PAR_BAS_MSN9_STAT:
				{
				STRPTR	Signal[] = {"Normaler Ruf", "Sondersignal 1", "Sondersignal 2", "","Sondersignal 3"};
				int		i = ParseID - PAR_BAS_MSN0_STAT;
					if(IC_BaseConfig.Signaling[i] != 3)
						PS_PTEXT(Signal[IC_BaseConfig.Signaling[i]]);
					else
						PS_NTEXT("Abweisen");
				}
				break;
			case	PAR_BAS_MOH:
				if(IC_BaseConfig.MusicPort)
				{
					sprintf(Buf, "%ld", 20 + IC_BaseConfig.MusicPort);
					PS_PTEXT(Buf);
				}
				else
					if(IC_BaseConfig.Music)
						PS_PTEXT("an");
					else
						PS_NTEXT("aus");
				break;
			case	PAR_BAS_TFE_TYP:
				{
				int	i = LT_GetAttributes(Handle, GAD_BaseConfig_TFE_MainPage, TAG_DONE);
					switch(i)
					{
					case	0:	/* Emmerich */
						PS_PTEXT("Emmerich");
						break;
					case	1:	/* Telekom */
						PS_NTEXT("Telekom");
						break;
					case	2:	/* Alarm */
						PS_PTEXT("Alarm");
						break;
					}
				}
				break;
			case	PAR_BAS_TFE_EMMERICH:
				if(LT_GetAttributes(Handle, GAD_BaseConfig_TFE_MainPage, TAG_DONE) == 0)
				{
					sprintf(Buf, "%ld", IC_BaseConfig.TFEAssignment);
					PS_PTEXT(Buf);
				}
				else
					PS_NTEXT("aus");
				break;
			case	PAR_BAS_TFE_ALARM:
				if(LT_GetAttributes(Handle, GAD_BaseConfig_TFE_MainPage, TAG_DONE) == 2)
				{
					sprintf(Buf, "%ld", IC_Alarm + 20);
					PS_PTEXT(Buf);
				}
				else
					PS_NTEXT("aus");
				break;
			case	PAR_BAS_TFE_T1_21:
			case	PAR_BAS_TFE_T1_22:
			case	PAR_BAS_TFE_T1_23:
			case	PAR_BAS_TFE_T1_24:
			case	PAR_BAS_TFE_T1_25:
			case	PAR_BAS_TFE_T1_26:
			case	PAR_BAS_TFE_T1_27:
			case	PAR_BAS_TFE_T1_28:
			case	PAR_BAS_TFE_T2_21:
			case	PAR_BAS_TFE_T2_22:
			case	PAR_BAS_TFE_T2_23:
			case	PAR_BAS_TFE_T2_24:
			case	PAR_BAS_TFE_T2_25:
			case	PAR_BAS_TFE_T2_26:
			case	PAR_BAS_TFE_T2_27:
			case	PAR_BAS_TFE_T2_28:
			case	PAR_BAS_TFE_T3_21:
			case	PAR_BAS_TFE_T3_22:
			case	PAR_BAS_TFE_T3_23:
			case	PAR_BAS_TFE_T3_24:
			case	PAR_BAS_TFE_T3_25:
			case	PAR_BAS_TFE_T3_26:
			case	PAR_BAS_TFE_T3_27:
			case	PAR_BAS_TFE_T3_28:
			case	PAR_BAS_TFE_T4_21:
			case	PAR_BAS_TFE_T4_22:
			case	PAR_BAS_TFE_T4_23:
			case	PAR_BAS_TFE_T4_24:
			case	PAR_BAS_TFE_T4_25:
			case	PAR_BAS_TFE_T4_26:
			case	PAR_BAS_TFE_T4_27:
			case	PAR_BAS_TFE_T4_28:
				if(LT_GetAttributes(Handle, GAD_BaseConfig_TFE_MainPage, TAG_DONE) == 1)
				{
				int	i = ParseID - PAR_BAS_TFE_T1_21;
					if(IC_BaseConfig.TFELoc[i / 8] & (1 << (i%8)))
					{
						sprintf(Buf, "%ld", 21 + (i%8));
						PS_PTEXT(Buf);
					}
					else
						PS_NTEXT("aus");
				}
				else
					PS_NTEXT("aus");
				break;

		/* Endgeraetekonfig */
			case	PAR_DEV_21_NAME:
			case	PAR_DEV_22_NAME:
			case	PAR_DEV_23_NAME:
			case	PAR_DEV_24_NAME:
			case	PAR_DEV_25_NAME:
			case	PAR_DEV_26_NAME:
			case	PAR_DEV_27_NAME:
			case	PAR_DEV_28_NAME:
				PS_PTEXT(IC_DeviceNames.Names[ParseID - PAR_DEV_21_NAME]);
				break;
			case	PAR_DEV_NAME:
				PS_PTEXT(IC_DeviceNames.Names[PS->UseDev]);
				break;
			case	PAR_DEV_MSN0:
			case	PAR_DEV_MSN1:
			case	PAR_DEV_MSN2:
			case	PAR_DEV_MSN3:
			case	PAR_DEV_MSN4:
			case	PAR_DEV_MSN5:
			case	PAR_DEV_MSN6:
			case	PAR_DEV_MSN7:
			case	PAR_DEV_MSN8:
			case	PAR_DEV_MSN9:
				if(IC_BaseConfig.MSNGroups[ParseID - PAR_DEV_MSN0] & (1 << PS->UseDev))
					PS_PTEXT("an");
				else
					PS_NTEXT("aus");
				break;
			case	PAR_DEV_PIN:
				BCD2String(Buf, (UBYTE *)IC_DevConfig[PS->UseDev].PIN, 4, 1);
				PS_PTEXT(Buf);
				break;
			case	PAR_DEV_CAPS:
				{
				STRPTR	Caps[] = {"Inland", "Ort", "Halbamt", "Nichtamt"};
					if(IC_DevConfig[PS->UseDev].DialCaps != 0)
						PS_PTEXT(Caps[IC_DevConfig[PS->UseDev].DialCaps - 1]);
					else
						PS_NTEXT("keine");
				}
				break;
			case	PAR_DEV_SERVICE:
				{
				STRPTR	Service[] = {"Telefon", "Fax G3", "Modem", "Datex J", "Anrufbeantworter", "Kombi-Dienst"};
					PS_PTEXT(Service[IC_DevConfig[PS->UseDev].Service]);
				}
				break;
			case	PAR_DEV_MODE:
				if(IC_DevConfig[PS->UseDev].TerminalMode)
					PS_PTEXT("an");
				else
					PS_NTEXT("aus");
				break;
			case	PAR_DEV_PULSE:
				if(IC_DevConfig[PS->UseDev].ChargePulse)
					PS_PTEXT("an");
				else
					PS_NTEXT("aus");
				break;
			case	PAR_DEV_REROUTE:
				sprintf(Buf, "%ld", IC_DevConfig[PS->UseDev].Reroute);
				if((IC_DevConfig[PS->UseDev].Reroute >= 21) && (IC_DevConfig[PS->UseDev].Reroute <= 28))
					PS_PTEXT(Buf);
				else
				if(IC_DevConfig[PS->UseDev].Reroute == 1)
					PS_PTEXT("extern");
				else
					PS_NTEXT("aus");
				break;
			case	PAR_DEV_REROUTENO:
				BCD2String(Buf, IC_DevConfig[PS->UseDev].ExtNum, 10, 1);
				if(strlen(Buf))
					strcpy(Buf, &Buf[1]);
				if(IC_DevConfig[PS->UseDev].Reroute == 1)
					PS_PTEXT(Buf);
				else
					PS_NTEXT("aus");
				break;
			case	PAR_DEV_REROUTEBUSY:
				sprintf(Buf, "%ld", 20 + IC_DevConfig[PS->UseDev].RerouteIfBusy);
				if((IC_DevConfig[PS->UseDev].RerouteIfBusy != 0) &&
					(!IC_DevConfig[PS->UseDev].Reroute))
					PS_PTEXT(Buf);
				else
					PS_NTEXT("aus");
				break;
			case	PAR_DEV_REROUTEDELAY:
				sprintf(Buf, "%ld", 20 + IC_DevConfig[PS->UseDev].RerouteDelayed);
				if((IC_DevConfig[PS->UseDev].RerouteDelayed != 0) &&
					(!IC_DevConfig[PS->UseDev].Reroute))
					PS_PTEXT(Buf);
				else
					PS_NTEXT("aus");
				break;
			case	PAR_DEV_REROUTERINGS:
				sprintf(Buf, "%ld", IC_DevConfig[PS->UseDev].RingsUntilReroute);
				if(((IC_DevConfig[PS->UseDev].RingsUntilReroute >= 3) || (IC_DevConfig[PS->UseDev].RingsUntilReroute <= 10)) &&
					 (!IC_DevConfig[PS->UseDev].Reroute) && (IC_DevConfig[PS->UseDev].RerouteDelayed))
					PS_PTEXT(Buf);
				else
					PS_NTEXT("aus");
				break;
			case	PAR_DEV_KNOCKMSN0:
			case	PAR_DEV_KNOCKMSN1:
			case	PAR_DEV_KNOCKMSN2:
			case	PAR_DEV_KNOCKMSN3:
			case	PAR_DEV_KNOCKMSN4:
			case	PAR_DEV_KNOCKMSN5:
			case	PAR_DEV_KNOCKMSN6:
			case	PAR_DEV_KNOCKMSN7:
			case	PAR_DEV_KNOCKMSN8:
			case	PAR_DEV_KNOCKMSN9:
				{
				UWORD Flag = (IC_DevConfig[PS->UseDev].ExternalKnock[1] << 8) + IC_DevConfig[PS->UseDev].ExternalKnock[0];
					if(Flag & (1 << (ParseID - PAR_DEV_KNOCKMSN0)))
						PS_PTEXT("an");
					else
						PS_NTEXT("aus");
					break;
				}
			case	PAR_DEV_KNOCKTFE:
				if(IC_DevConfig[PS->UseDev].ExternalKnock[1] & (1<<3))
					PS_PTEXT("an");
				else
					PS_NTEXT("aus");
				break;
			case	PAR_DEV_KNOCKDEV21:
			case	PAR_DEV_KNOCKDEV22:
			case	PAR_DEV_KNOCKDEV23:
			case	PAR_DEV_KNOCKDEV24:
			case	PAR_DEV_KNOCKDEV25:
			case	PAR_DEV_KNOCKDEV26:
			case	PAR_DEV_KNOCKDEV27:
			case	PAR_DEV_KNOCKDEV28:
				if(IC_DevConfig[PS->UseDev].InternalKnock & (1 << (ParseID - PAR_DEV_KNOCKDEV21)))
					PS_PTEXT("an");
				else
					PS_NTEXT("aus");
				break;
			case	PAR_DEV_CHARGE_E:
				sprintf(Buf, "%ld", IC_Charge.Charge[PS->UseDev]);
				PS_PTEXT(Buf);
				break;
			case	PAR_DEV_CHARGE_M:
				{
				int	dm = IC_Charge.Charge[PS->UseDev] * PrgConfig.UnitCost;
					sprintf(Buf, "%ld.%02ld", dm/100, dm%100);
					PS_PTEXT(Buf);
				}
				break;

		/* Gebührenwerte */
			case	PAR_CHA_21_E:
			case	PAR_CHA_22_E:
			case	PAR_CHA_23_E:
			case	PAR_CHA_24_E:
			case	PAR_CHA_25_E:
			case	PAR_CHA_26_E:
			case	PAR_CHA_27_E:
			case	PAR_CHA_28_E:
				sprintf(Buf, "%ld", IC_Charge.Charge[ParseID - PAR_CHA_21_E]);
				PS_PTEXT(Buf);
				break;
			case	PAR_CHA_21_M:
			case	PAR_CHA_22_M:
			case	PAR_CHA_23_M:
			case	PAR_CHA_24_M:
			case	PAR_CHA_25_M:
			case	PAR_CHA_26_M:
			case	PAR_CHA_27_M:
			case	PAR_CHA_28_M:
				{
				int	dm = IC_Charge.Charge[ParseID - PAR_CHA_21_M] * PrgConfig.UnitCost;
					sprintf(Buf, "%ld.%02ld", dm/100, dm%100);
					PS_PTEXT(Buf);
				}
				break;
			case	PAR_CHA_ALL_E:
			case	PAR_CHA_ALL_M:
				{
				int	i, n = 0;
					for(i = 0 ; i < 8 ; i++)
						n += IC_Charge.Charge[i];
					sprintf(Buf, "%ld", n);
					if(ParseID == PAR_CHA_ALL_M)
					{
						n *= PrgConfig.UnitCost;
						sprintf(Buf, "%ld.%02ld", n/100, n%100);
					}
					PS_PTEXT(Buf);
				}
				break;
			case	PAR_CHA_CURRENCY:
				PS_PTEXT(PrgConfig.DMname);
				break;


			case	PAR_KWV_NUMMER:
				BCD2String(Buf, &(IC_RufConfig[PS->UseKWV].ReadIn[5]), IC_RufConfig[PS->UseKWV].ReadIn[4], 0);
				if(strlen(Buf))
					if(Buf[0] == '0')
						PS_PTEXT(Buf+1);
					else
						PS_PTEXT(Buf);
				else
					PS_NTEXT("keine");
				break;
			case	PAR_KWV_STAT:
				{
				int	i;
				STRPTR	Signal[] = {"Normaler Ruf", "Sondersignal 1", "Sondersignal 2", "Sondersignal 3"};
					i = ((IC_RufConfig[PS->UseKWV].ReadIn[(IC_RufConfig[PS->UseKWV].ReadIn[4] + 1)/2 + 5 + 2]) < 3) ? ((IC_RufConfig[PS->UseKWV].ReadIn[(IC_RufConfig[PS->UseKWV].ReadIn[4] + 1)/2 + 5 + 2])) : (((IC_RufConfig[PS->UseKWV].ReadIn[(IC_RufConfig[PS->UseKWV].ReadIn[4] + 1)/2 + 5 + 2]) == 3) ? 4 : 3);
					if(i != 4)
						PS_PTEXT(Signal[i]);
					else
						PS_NTEXT("Abweisen");
				}
				break;
			case	PAR_KWV_21_STAT:
			case	PAR_KWV_22_STAT:
			case	PAR_KWV_23_STAT:
			case	PAR_KWV_24_STAT:
			case	PAR_KWV_25_STAT:
			case	PAR_KWV_26_STAT:
			case	PAR_KWV_27_STAT:
			case	PAR_KWV_28_STAT:
				{
				int		i = ParseID - PAR_KWV_21_STAT;
				int		type = IC_RufConfig[PS->UseKWV].ReadIn[(IC_RufConfig[PS->UseKWV].ReadIn[4] + 1)/2 + 5 + 3];

					if(IC_RufConfig[PS->UseKWV].ReadIn[(IC_RufConfig[PS->UseKWV].ReadIn[4] + 1)/2 + 5 + 0] & (1<<i))
						PS_PTEXT("Babyruf");
					else
						if(IC_RufConfig[PS->UseKWV].ReadIn[(IC_RufConfig[PS->UseKWV].ReadIn[4] + 1)/2 + 5 + 1] & (1<<i))
							PS_PTEXT(type ? "Sperre" : "Kurzwahl");
						else
							PS_NTEXT("Inaktiv");
				}
				break;
			case	PAR_KWV_SPEICHER:
				sprintf(Buf, "%ld", PS->UseKWV + 301);
				PS_PTEXT(Buf);
				break;

			case PAR_KWV_301_USE: case	PAR_KWV_302_USE: case PAR_KWV_303_USE: case PAR_KWV_304_USE: case PAR_KWV_305_USE:
			case PAR_KWV_306_USE: case	PAR_KWV_307_USE: case PAR_KWV_308_USE: case PAR_KWV_309_USE: case PAR_KWV_310_USE:
			case PAR_KWV_311_USE: case	PAR_KWV_312_USE: case PAR_KWV_313_USE: case PAR_KWV_314_USE: case PAR_KWV_315_USE:
			case PAR_KWV_316_USE: case	PAR_KWV_317_USE: case PAR_KWV_318_USE: case PAR_KWV_319_USE: case PAR_KWV_320_USE:
			case PAR_KWV_321_USE: case	PAR_KWV_322_USE: case PAR_KWV_323_USE: case PAR_KWV_324_USE: case PAR_KWV_325_USE:
			case PAR_KWV_326_USE: case	PAR_KWV_327_USE: case PAR_KWV_328_USE: case PAR_KWV_329_USE: case PAR_KWV_330_USE:
			case PAR_KWV_331_USE: case	PAR_KWV_332_USE: case PAR_KWV_333_USE: case PAR_KWV_334_USE: case PAR_KWV_335_USE:
			case PAR_KWV_336_USE: case	PAR_KWV_337_USE: case PAR_KWV_338_USE: case PAR_KWV_339_USE: case PAR_KWV_340_USE:
			case PAR_KWV_341_USE: case	PAR_KWV_342_USE: case PAR_KWV_343_USE: case PAR_KWV_344_USE: case PAR_KWV_345_USE:
			case PAR_KWV_346_USE: case	PAR_KWV_347_USE: case PAR_KWV_348_USE: case PAR_KWV_349_USE: case PAR_KWV_350_USE:
			case PAR_KWV_351_USE: case	PAR_KWV_352_USE: case PAR_KWV_353_USE: case PAR_KWV_354_USE: case PAR_KWV_355_USE:
			case PAR_KWV_356_USE: case	PAR_KWV_357_USE: case PAR_KWV_358_USE: case PAR_KWV_359_USE: case PAR_KWV_360_USE:
				PS_PTEXT("");
				PS->UseKWV = ParseID - PAR_KWV_301_USE;
				break;
		}
		/* Kopiere den neuen Text in den Bereich der Variablen rein */
		{
			if(PLen != 0)
				if(strlen(PS->Buffer) > (abs(PLen)))
					PS->Buffer[abs(PLen)] = 0x00;
			if(PLen != 0)
				if((abs(PLen)) > strlen(PS->Buffer))
				{
				int	i = (abs(PLen)) - strlen(PS->Buffer);
					if((abs(PLen)) > (PS->BufferLen - 2))
					{
						PS->ParseError = PARSE_ERROR_LARGE_TEXT;
						return(FALSE);
					}
					if(PLen > 0)	/* Rechtsbuendig */
					{
						memmove(PS->Buffer + i, PS->Buffer, strlen(PS->Buffer) + 1);
						memset(PS->Buffer, ' ', i);
					}
					else
					{
						memset(PS->Buffer + strlen(PS->Buffer), ' ', i);
						PS->Buffer[abs(PLen)] = 0x00;
					}
				}
			if(strlen(PS->Buffer) >= (PE - PA + 1))
			{
				if((PA - ParseText + strlen(PS->Buffer) + strlen(PE) + 5) > (len - 2))
				{
					PS->ParseError = PARSE_ERROR_LARGE_TEXT;
					return(FALSE);
				}
				memmove(PA + strlen(PS->Buffer) + 5 , PE, strlen(PE) + 1);
				PE = PA + strlen(PS->Buffer) + 5;
			}
			strcpy(PA, PS->Buffer);
			strcpy(PA + strlen(PS->Buffer), PE+1);
		}
		return(Parse(PS));
	}
}

enum {PSID_All = 1, PSID_Cha, PSID_Base, PSID_Dev,
		PSID_Dev21, PSID_Dev22, PSID_Dev23, PSID_Dev24, PSID_Dev25, PSID_Dev26, PSID_Dev27, PSID_Dev28,
		PSID_Charge, PSID_Ruf,
		PSID_In, PSID_InDefault, PSID_Out, PSID_OutPrinter, PSID_OutWindow,
		PSID_Print, PSID_Cancel};

BOOL	PrintConfig(void)
{
struct	ParseStruct	PS;
BPTR	outfh = NULL;
struct	LayoutHandle	*SubHandle;
int	i;
char	OutName[256];
char	InName[256];
BOOL	PrintItReal = FALSE;

	PS.PrintMask = ~0;	/* Gebe ALLE Daten aus */

	if(SubHandle = LT_CreateHandleTags(NULL, TAG_DONE))
	{
	struct	Window	*Window;
	BOOL					 done = FALSE;
	char					 WinTitle[] = PRGNAME ": Drucken";

		LT_New(SubHandle, LA_Type, VERTICAL_KIND, TAG_DONE);
			LT_New(SubHandle, LA_Type, VERTICAL_KIND, LAGR_Frame, TRUE, LA_LabelText, "Druckauswahl", TAG_DONE);
				LT_New(SubHandle, LA_Type, HORIZONTAL_KIND, LAGR_Spread, TRUE, TAG_DONE);
					LT_New(SubHandle, LA_Type, BUTTON_KIND, LA_LabelText, "_Alles Drucken", LA_ID, PSID_All, TAG_DONE);
					LT_New(SubHandle, LA_Type, BUTTON_KIND, LA_LabelText, "_Gebühren drucken", LA_ID, PSID_Cha, TAG_DONE);
				LT_EndGroup(SubHandle);
				LT_New(SubHandle, LA_Type, VERTICAL_KIND, TAG_DONE);
					LT_New(SubHandle, LA_Type, VERTICAL_KIND, TAG_DONE);
						LT_New(SubHandle, LA_Type, CHECKBOX_KIND, LA_LabelText, "_Basiskonfiguration", LA_ID, PSID_Base, TAG_DONE);
					LT_EndGroup(SubHandle);
					LT_New(SubHandle, LA_Type, VERTICAL_KIND, LAGR_Frame, TRUE, TAG_DONE);
						LT_New(SubHandle, LA_Type, VERTICAL_KIND, TAG_DONE);
							LT_New(SubHandle, LA_Type, CHECKBOX_KIND, LA_LabelText, "_Endgerätekonfiguration", LA_ID, PSID_Dev, LA_ExtraSpace, TRUE, TAG_DONE);
							LT_New(SubHandle, LA_Type, XBAR_KIND, TAG_DONE);
						LT_EndGroup(SubHandle);
						LT_New(SubHandle, LA_Type, VERTICAL_KIND, TAG_DONE);
							for(i = 0 ; i < 4 ; i++)
							{
								LT_New(SubHandle, LA_Type, HORIZONTAL_KIND, LAGR_SameSize, TRUE, i == 0 ? TAG_IGNORE : LAGR_LastAttributes, TRUE, TAG_DONE);
									LT_New(SubHandle, LA_Type, CHECKBOX_KIND, LA_LabelText, IC_DeviceNames.Names[i+0], LA_ID, PSID_Dev21 + i+0, TAG_DONE);
									LT_New(SubHandle, LA_Type, CHECKBOX_KIND, LA_LabelText, IC_DeviceNames.Names[i+4], LA_ID, PSID_Dev21 + i+4, TAG_DONE);
								LT_EndGroup(SubHandle);
							}
						LT_EndGroup(SubHandle);
					LT_EndGroup(SubHandle);
					LT_New(SubHandle, LA_Type, VERTICAL_KIND, LA_ExtraSpace, TRUE, TAG_DONE);
						LT_New(SubHandle, LA_Type, CHECKBOX_KIND, LA_LabelText, "Gebühre_n", LA_ID, PSID_Charge, TAG_DONE);
						LT_New(SubHandle, LA_Type, CHECKBOX_KIND, LA_LabelText, "_Kurzwahlen", LA_ID, PSID_Ruf, TAG_DONE);
					LT_EndGroup(SubHandle);
				LT_EndGroup(SubHandle);
			LT_EndGroup(SubHandle);
			LT_New(SubHandle, LA_Type, VERTICAL_KIND, TAG_DONE);
				LT_New(SubHandle, LA_Type, HORIZONTAL_KIND, TAG_DONE);
					if(strlen(PrgConfig.ParseFile))
						strcpy(InName, PrgConfig.ParseFile);
					LT_New(SubHandle, LA_Type, STRING_KIND, GTST_MaxChars, 250, LA_Chars, 50, LA_ID, PSID_In, LA_STRPTR, InName, LA_LabelText, "Eingabedatei: ", LAST_Picker, TRUE, TAG_DONE);
					LT_New(SubHandle, LA_Type, BUTTON_KIND, LA_ID, PSID_InDefault, LA_LabelText, "Default", TAG_DONE);
				LT_EndGroup(SubHandle);
				LT_New(SubHandle, LA_Type, HORIZONTAL_KIND, LAGR_LastAttributes, TRUE, TAG_DONE);
					strcpy(OutName, "prt:");
strcpy(OutName, "CON:0/0/640/1024/"PRGNAME": Drucken/AUTO");
					LT_New(SubHandle, LA_Type, VERTICAL_KIND, TAG_DONE);
						LT_New(SubHandle, LA_Type, STRING_KIND, GTST_MaxChars, 250, LA_Chars, 50, LA_ID, PSID_Out, LA_STRPTR, OutName, LA_LabelText, "Ausgabedatei: ", LAST_Picker, TRUE, TAG_DONE);
					LT_EndGroup(SubHandle);
					LT_New(SubHandle, LA_Type, VERTICAL_KIND, TAG_DONE);
						LT_New(SubHandle, LA_Type, BUTTON_KIND, LA_ID, PSID_OutPrinter, LA_LabelText, "Drucker", TAG_DONE);
						LT_New(SubHandle, LA_Type, BUTTON_KIND, LA_ID, PSID_OutWindow, LA_LabelText, "Fenster", TAG_DONE);
					LT_EndGroup(SubHandle);
				LT_EndGroup(SubHandle);
			LT_EndGroup(SubHandle);
			LT_New(SubHandle, LA_Type, XBAR_KIND, LAXB_FullSize, TRUE, TAG_DONE);
			LT_New(SubHandle, LA_Type, HORIZONTAL_KIND, LAGR_Spread, TRUE, TAG_DONE);
				LT_New(SubHandle, LA_Type, BUTTON_KIND, LA_LabelText, "Drucken/Speichern", LA_ID, PSID_Print, LABT_ReturnKey, TRUE, LABT_ExtraFat, TRUE, TAG_DONE);
				LT_New(SubHandle, LA_Type, BUTTON_KIND, LA_LabelText, "Abbrechen", LA_ID, PSID_Cancel, LABT_EscKey, TRUE, LABT_ExtraFat, TRUE, TAG_DONE);
			LT_EndGroup(SubHandle);
		LT_EndGroup(SubHandle);

		LT_SetAttributes(SubHandle, PSID_Base,  GTCB_Checked, PS.PrintMask & PS_BAS, TAG_DONE);
		LT_SetAttributes(SubHandle, PSID_Dev,   GTCB_Checked, PS.PrintMask & PS_DEV, TAG_DONE);
		LT_SetAttributes(SubHandle, PSID_Dev21, GTCB_Checked, PS.PrintMask & PS_DEV21, TAG_DONE);
		LT_SetAttributes(SubHandle, PSID_Dev22, GTCB_Checked, PS.PrintMask & PS_DEV22, TAG_DONE);
		LT_SetAttributes(SubHandle, PSID_Dev23, GTCB_Checked, PS.PrintMask & PS_DEV23, TAG_DONE);
		LT_SetAttributes(SubHandle, PSID_Dev24, GTCB_Checked, PS.PrintMask & PS_DEV24, TAG_DONE);
		LT_SetAttributes(SubHandle, PSID_Dev25, GTCB_Checked, PS.PrintMask & PS_DEV25, TAG_DONE);
		LT_SetAttributes(SubHandle, PSID_Dev26, GTCB_Checked, PS.PrintMask & PS_DEV26, TAG_DONE);
		LT_SetAttributes(SubHandle, PSID_Dev27, GTCB_Checked, PS.PrintMask & PS_DEV27, TAG_DONE);
		LT_SetAttributes(SubHandle, PSID_Dev28, GTCB_Checked, PS.PrintMask & PS_DEV28, TAG_DONE);
		LT_SetAttributes(SubHandle, PSID_Charge,GTCB_Checked, PS.PrintMask & PS_CHA, TAG_DONE);
		LT_SetAttributes(SubHandle, PSID_Ruf,   GTCB_Checked, PS.PrintMask & PS_KWV, TAG_DONE);

		if(Window = LT_Build(SubHandle,
									LAWN_Title,			WinTitle,
									LAWN_IDCMP,			IDCMP_CLOSEWINDOW|IDCMP_GADGETDOWN|IDCMP_GADGETUP|IDCMP_RAWKEY|IDCMP_REFRESHWINDOW,
									LAWN_Zoom,			TRUE,
									LAWN_SmartZoom,	TRUE,
									WA_CloseGadget,	TRUE,
									WA_DragBar,			TRUE,
									WA_Activate,		TRUE,
									WA_DepthGadget,	TRUE,
									TAG_DONE))
		do
		{
			WaitPort(Window -> UserPort);
			while(Message = GT_GetIMsg(Window->UserPort))
			{
				MsgClass			= Message->Class;
				MsgCode			= Message->Code;
				MsgQualifier	= Message->Qualifier;
				MsgGadget		= Message->IAddress;

				GT_ReplyIMsg(Message);
				LT_HandleInput(SubHandle, MsgQualifier, &MsgClass, &MsgCode, &MsgGadget);

				switch(MsgClass)
				{
					case	IDCMP_CLOSEWINDOW:
						done = TRUE;
						break;
					case	IDCMP_GADGETUP:
						switch(MsgGadget->GadgetID)
						{
							case	PSID_All:
								PS.PrintMask = ~0;
								LT_SetAttributes(SubHandle, PSID_Base,  GTCB_Checked, PS.PrintMask & PS_BAS, TAG_DONE);
								LT_SetAttributes(SubHandle, PSID_Dev,   GTCB_Checked, PS.PrintMask & PS_DEV, TAG_DONE);
								LT_SetAttributes(SubHandle, PSID_Dev21, GTCB_Checked, PS.PrintMask & PS_DEV21, GA_Disabled, FALSE, TAG_DONE);
								LT_SetAttributes(SubHandle, PSID_Dev22, GTCB_Checked, PS.PrintMask & PS_DEV22, GA_Disabled, FALSE, TAG_DONE);
								LT_SetAttributes(SubHandle, PSID_Dev23, GTCB_Checked, PS.PrintMask & PS_DEV23, GA_Disabled, FALSE, TAG_DONE);
								LT_SetAttributes(SubHandle, PSID_Dev24, GTCB_Checked, PS.PrintMask & PS_DEV24, GA_Disabled, FALSE, TAG_DONE);
								LT_SetAttributes(SubHandle, PSID_Dev25, GTCB_Checked, PS.PrintMask & PS_DEV25, GA_Disabled, FALSE, TAG_DONE);
								LT_SetAttributes(SubHandle, PSID_Dev26, GTCB_Checked, PS.PrintMask & PS_DEV26, GA_Disabled, FALSE, TAG_DONE);
								LT_SetAttributes(SubHandle, PSID_Dev27, GTCB_Checked, PS.PrintMask & PS_DEV27, GA_Disabled, FALSE, TAG_DONE);
								LT_SetAttributes(SubHandle, PSID_Dev28, GTCB_Checked, PS.PrintMask & PS_DEV28, GA_Disabled, FALSE, TAG_DONE);
								LT_SetAttributes(SubHandle, PSID_Charge,GTCB_Checked, PS.PrintMask & PS_CHA, TAG_DONE);
								LT_SetAttributes(SubHandle, PSID_Ruf,   GTCB_Checked, PS.PrintMask & PS_KWV, TAG_DONE);
								break;
							case	PSID_Cha:
								{
								int	i;
									PS.PrintMask |= PS_CHA;
									PS.PrintMask &= ~(PS_BAS|PS_DEV|PS_KWV);
									LT_SetAttributes(SubHandle, PSID_Base,  GTCB_Checked, PS.PrintMask & PS_BAS, TAG_DONE);
									LT_SetAttributes(SubHandle, PSID_Dev,   GTCB_Checked, PS.PrintMask & PS_DEV, TAG_DONE);
									LT_SetAttributes(SubHandle, PSID_Charge,GTCB_Checked, PS.PrintMask & PS_CHA, TAG_DONE);
									LT_SetAttributes(SubHandle, PSID_Ruf,   GTCB_Checked, PS.PrintMask & PS_KWV, TAG_DONE);
									for(i = 0 ; i < 8 ; i++)
										LT_SetAttributes(SubHandle, PSID_Dev21 + i, GA_Disabled, TRUE, TAG_DONE);
								}
								break;
							case	PSID_Base:
								if(LT_GetAttributes(SubHandle, MsgGadget->GadgetID, TAG_DONE))
									PS.PrintMask |= PS_BAS;
								else
									PS.PrintMask &= ~PS_BAS;
								break;
							case	PSID_Dev:
								{
								BOOL	set; int i;
									if(set = LT_GetAttributes(SubHandle, MsgGadget->GadgetID, TAG_DONE))
										PS.PrintMask |= PS_DEV;
									else
										PS.PrintMask &= ~PS_DEV;
									for(i = 0 ; i < 8 ; i++)
										LT_SetAttributes(SubHandle, PSID_Dev21 + i, GA_Disabled, !set, TAG_DONE);
								}
								break;
							case	PSID_Dev21:
							case	PSID_Dev22:
							case	PSID_Dev23:
							case	PSID_Dev24:
							case	PSID_Dev25:
							case	PSID_Dev26:
							case	PSID_Dev27:
							case	PSID_Dev28:
								{
								int	i = MsgGadget->GadgetID - PSID_Dev21;
									i = PS_DEV21 << i;
									if(LT_GetAttributes(SubHandle, MsgGadget->GadgetID, TAG_DONE))
										PS.PrintMask |= i;
									else
										PS.PrintMask &= ~i;
								}
								break;
							case	PSID_Charge:
								if(LT_GetAttributes(SubHandle, MsgGadget->GadgetID, TAG_DONE))
									PS.PrintMask |= PS_CHA;
								else
									PS.PrintMask &= ~PS_CHA;
								break;
							case	PSID_Ruf:
								if(LT_GetAttributes(SubHandle, MsgGadget->GadgetID, TAG_DONE))
									PS.PrintMask |= PS_KWV;
								else
									PS.PrintMask &= ~PS_KWV;
								break;
							case	PSID_In:
								break;
							case	PSID_InDefault:
								strcpy(InName, PrgConfig.ParseFile);
								LT_SetAttributes(SubHandle, PSID_In, GTST_String, InName, TAG_DONE);
								break;
							case	PSID_Out:
								break;
							case	PSID_OutPrinter:
								LT_SetAttributes(SubHandle, PSID_Out, GTST_String, "prt:", TAG_DONE);
								strcpy(OutName, "prt:");
								break;
							case	PSID_OutWindow:
								strcpy(OutName, "CON:0/0/640/1024/"PRGNAME": Drucken/AUTO");
								LT_SetAttributes(SubHandle, PSID_Out, GTST_String, OutName, TAG_DONE);
								break;

							case	PSID_Print:
								PrintItReal = TRUE;
							case	PSID_Cancel:
								done = TRUE;
								break;
						}
						break;
					case	IDCMP_IDCMPUPDATE:
						switch(MsgGadget->GadgetID)
						{
							case	PSID_In:
								{
								struct	FileRequester	*freq;
								char		gad_FDir[256];
								char		gad_FNam[256];
								STRPTR	dummy;
									LT_LockWindow(Window);
									if(freq = AllocFileRequest())
									{
										strcpy(gad_FDir, InName);
										dummy = FilePart(gad_FDir); if(dummy) *dummy = 0x00;
										strcpy(gad_FNam, FilePart(InName));
										if(AslRequestTags(freq, ASLFR_RejectIcons, TRUE, ASLFR_InitialHeight, 999, ASLFR_InitialPattern, "#?.uip", ASLFR_InitialFile, gad_FNam, ASLFR_InitialDrawer, gad_FDir, ASLFR_RejectIcons, TRUE, ASLFR_DoPatterns, TRUE, TAG_DONE))
										{
											strcpy(InName, freq->fr_Drawer);
											AddPart(InName, freq->fr_File, 158);
											LT_SetAttributes(SubHandle, PSID_In, GTST_String, InName, TAG_DONE);
										}
										FreeFileRequest(freq);
									}
									LT_UnlockWindow(Window);
								}
								break;
							case	PSID_Out:
								{
								struct	FileRequester	*freq;
								char		gad_FDir[256];
								char		gad_FNam[256];
								STRPTR	dummy;
									LT_LockWindow(Window);
									if(freq = AllocFileRequest())
									{
										strcpy(gad_FDir, OutName);
										dummy = FilePart(gad_FDir); if(dummy) *dummy = 0x00;
										strcpy(gad_FNam, FilePart(OutName));
										if(AslRequestTags(freq, ASLFR_RejectIcons, TRUE, ASLFR_InitialHeight, 999, ASLFR_InitialFile, gad_FNam, ASLFR_InitialDrawer, gad_FDir, ASLFR_RejectIcons, TRUE, ASLFR_DoPatterns, TRUE, TAG_DONE))
										{
											strcpy(OutName, freq->fr_Drawer);
											AddPart(OutName, freq->fr_File, 158);
											LT_SetAttributes(SubHandle, PSID_Out, GTST_String, OutName, TAG_DONE);
										}
										FreeFileRequest(freq);
									}
									LT_UnlockWindow(Window);
								}
								break;
						}
						break;
				}
			}
		}
		while(!done);
		LT_DeleteHandle(SubHandle);
	}

	if(PrintItReal)
	{
		LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Lade benötigte Einstellungen aus der Anlage...", TAG_DONE);
		if(!SerialError && !IC_Loaded.DevConfig)
		{
			ICReadDevices(&IC_DevConfig[0], TRUE);
			IC_Loaded.DevConfig	= TRUE;
		}
		/* Lade Gebuehren */
		if(!SerialError && !IC_Loaded.Charge)
		{
			ICReadCharge(&IC_Charge, PrgConfig.UnitCost, TRUE);
			IC_Loaded.Charge		= TRUE;
			ICUpdateDevConfig(&IC_BaseConfig, &IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)], LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE), IC_Charge.Charge[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)], IC_Charge.ChargeType[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)]);
		}
		/* Lade Kurzwahlen */
		if(!SerialError && !IC_Loaded.RufConfig)
		{
		int	n;
			LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, ~NULL, TAG_DONE);
			for(n = 0 ; n < 60 ; n++)
			{
				if(ICGetRufConfig(&IC_RufConfig[n], n+1, TRUE))
				{
					AddTail(&IC_ShortList, (struct Node *)&IC_RufConfig[n]);
					ICSetRC_LV(&IC_ShortList, &IC_RufConfig[n]);
				}
				else
					break;
			}
			LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, &IC_ShortList, GTLV_Selected, 0, TAG_DONE);
			ICSetRC_Gadgets(&IC_RufConfig[LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE)]);
			IC_Loaded.RufConfig = TRUE;
		}

		LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Drucke Anlageneinstellungen...", TAG_DONE);

		PS.ParseText = PS.Buffer = NULL;

		PS.ParseError = 0;
		PS.UseDev	= 0;		/* Benutze Geraet 21 */
		PS.UseKWV	= 0;		/* Benutze Kurzwahlnr. 301 */
		PS.PrintVal = 0;
		PS.infh			= NULL;	/* Input FileHandle */
		PS.LoopPos		= -1;		/* Erklaere LoopPos fuer ungueltig */
		PS.LoopCount	=  0;		/* LoopCounter = 0 */
		PS.LoopEnd		=  0;		/* EndWert fuer Loop */


		if(!SerialError)
		if(!(PS.ParseText	= AllocVec(10000, MEMF_CLEAR)))
			Requester(NULL, PRGNAME": Drucken", "Es konnte nicht mehr genug Speicher reserviert werden!", "Ok", NULL, NULL);
		else
		if(!(PS.ParseTextCopy= AllocVec(10000, MEMF_CLEAR)))
			Requester(NULL, PRGNAME": Drucken", "Es konnte nicht mehr genug Speicher reserviert werden!", "Ok", NULL, NULL);
		else
		if(!(PS.Buffer		= AllocVec(10000, MEMF_CLEAR)))
			Requester(NULL, PRGNAME": Drucken", "Es konnte nicht mehr genug Speicher reserviert werden!", "Ok", NULL, NULL);
		else
		if(!(PS.infh		= Open(InName, MODE_OLDFILE)))
			Requester(NULL, PRGNAME": Drucken", "Es konnte nicht die Eingabedatei geöffnet werden!", "Ok", NULL, NULL);
		else
		if(!(outfh			= Open(OutName, MODE_NEWFILE)))
			Requester(NULL, PRGNAME": Drucken", "Es konnte nicht die Ausgabedatei geöffnet werden!", "Ok", NULL, NULL);
		else
		{
		char	*doit;
			PS.ParseLen = PS.BufferLen = 10000 - 2;

			doit = FGets(PS.infh, PS.ParseText, PS.ParseLen);
			while(doit)
			{
				for(;;)
				{
					if(strlen(PS.ParseText) >= 2)
						if(!strcmp("\\\\\n", &PS.ParseText[strlen(PS.ParseText) - 3]))
						{
							if(!FGets(PS.infh, &PS.ParseText[strlen(PS.ParseText) - 3], PS.ParseLen - strlen(PS.ParseText)))
								break;
							else
								PS.ParseError = PARSE_ERROR_LINETERM;
						}
						else
							break;
					else
						break;
				}
				strcpy(PS.ParseTextCopy, PS.ParseText);

				if(Parse(&PS))
				{
					if(!PS.PrintVal)
						FPuts(outfh, PS.ParseText);
					else
					if(PS.PrintVal & PS.PrintMask)
						FPuts(outfh, PS.ParseText);
				}
				else
				{
					if(PS.ParseError)
					{
					STRPTR	Lines[8];
								Lines[0] = "Es ist ein Fehler beim Parsen aufgetreten:";
								Lines[2] = "";
								Lines[3] = PS.ParseTextCopy;
								Lines[4] = "";
								Lines[5] = NULL;
						if(PS.ParseTextCopy[strlen(PS.ParseTextCopy) - 1] == '\n')
							PS.ParseTextCopy[strlen(PS.ParseTextCopy) - 1] = 0x00;
						switch(PS.ParseError)
						{
							case	PARSE_ERROR_BRACKET:
								Lines[1] = "Die Klammerebenen stimmen nicht!";
								break;
							case	PARSE_ERROR_NOVAR:
								Lines[1] = "Es wurde keine Variable angegeben!";
								break;
							case	PARSE_ERROR_WRONG_VALUE:
								Lines[1] = "Es wurde eine Zahl erwartet!";
								break;
							case	PARSE_ERROR_LARGE_TEXT:
								Lines[1] = "Die Zeile ist zu lang!";
								break;
							case	PARSE_ERROR_LINETERM:
								Lines[1] = "Es wurde ein Zeilenvorschub nach dem \"\\\\\" erwartet";
								break;
						}
						INFOrequest(NULL, NULL, PRGNAME": Drucken", Lines);
					}
				}
				doit = FGets(PS.infh, PS.ParseText, PS.ParseLen);
			}
		}
		if(PS.infh)
			Close(PS.infh);
		if(outfh)
		{
			if(!strnicmp(OutName, "CON:", 4))
				Requester(NULL, PRGNAME": Drucken", "Ausgabefenster schliessen?", "Ja", NULL, NULL);
			Close(outfh);
		}
		if(PS.ParseText)
			FreeVec(PS.ParseText);
		if(PS.Buffer)
			FreeVec(PS.Buffer);
	}
	return(TRUE);
}















void main(LONG ArgC, char *ArgV[])
{
struct	Window	*Window;
int	n;

	if(ArgC)
	{
		fprintf(stderr, "%s kann nur von der Workbench gestartet werden!\n\n", ArgV[0]);
		exit(0);
	}
	if(!InitMain())
	{
		ExitMain(EXITMAINSTART);
		exit(5);
	};
	diskobj = GetDiskObject(SysBase->ThisTask->tc_Node.ln_Name);

	for(n = 0 ; n < 8 ; n++)
		sprintf(IC_DeviceNames.Names[n], "Gerät %ld", 21 + n);
	IC_DeviceNames.Dummy = NULL;
	for(n = 0 ; n < 8 ; n++)
		IC_Charge.ChargeType[n] = 0x00;
	PrgConfig.UnitCost = 12;
	/* Aliasliste loeschen */
	NewList(&IC_AliasList);

	if(diskobj)
	{
	STRPTR	Text;
	char		Buffer[100];
	ULONG		UnitNum;

		Text = FindToolType(diskobj->do_ToolTypes, "DeviceName");
		if(!Text) Text = SERIALNAME;
		UnitNum = atol(FindToolType(diskobj->do_ToolTypes, "UnitNummer"));

		/* Open the serial device */
		if(SerialMP = CreateMsgPort())
			if(SerialIO = (struct IOExtSer *)CreateExtIO(SerialMP, sizeof(struct IOExtSer)))
			{
				if(!OpenDevice(Text, UnitNum, (struct IORequest *)SerialIO, 0))
				{
					SerialBool = TRUE;
					SerialIO->IOSer.io_Command = CMD_RESET;
					DoIO((struct IORequest *)SerialIO);
					/* Die Settings fuer die IsTec einstellen */
					SerialIO->io_SerFlags	|= SERF_XDISABLED;
					SerialIO->io_Baud			= 9600;
					SerialIO->io_ReadLen		= 8;
					SerialIO->io_WriteLen	= 8;
					SerialIO->io_StopBits	= 1;
					SerialIO->IOSer.io_Command = SDCMD_SETPARAMS;
					if(DoIO((struct IORequest *)SerialIO))
					{
						CloseDevice((struct IORequest *)SerialIO);
						SerialBool = FALSE;
					}
				}
			}
		/* Öffnen des Device ist schiefgegangen */
		if(!SerialBool)
		{
			ExitMain(EXITMAINSERIAL);
			exit(5);
		}
		/* Oeffnen des Device ist erfolgreich, CEPatch aktivieren ? */
		if(FindToolType(diskobj->do_ToolTypes, "CEPatch"))
		{
			Text = FindToolType(diskobj->do_ToolTypes, "DeviceName");
			if(!Text) Text = SERIALNAME;
			if(!strcmp(Text, SERIALNAME))
			{
				ciab.ciapra |= CIAF_COMDTR;
			}
			else
			{
			/* Sonst SETCTRLLINES versuchen (klappt wohl nur bei Vector Karten) */
				SerialIO->IOSer.io_Command  = VSCMD_SETCTRLLINES;
				SerialIO->IOSer.io_Offset   = VSIOCTLF_DTR;
				SerialIO->IOSer.io_Length   = 0;
				if(DoIO((struct IORequest *)SerialIO))
				{
				STRPTR	Lines[10] = {"Es ist ein Problem aufgetreten!", "CEPatch wird von dem angegebenen Device nicht unterstützt!", NULL};

					INFOrequest(NULL, NULL, "CEPatch", Lines);
				}
			}
		}

		if(MatchToolValue(FindToolType(diskobj->do_ToolTypes, "AllesLaden"), "JA"))
			PrgConfig.LoadAll = TRUE; else PrgConfig.LoadAll = FALSE;
		if(Text = FindToolType(diskobj->do_ToolTypes, "DruckerDatei"))
			strcpy(PrgConfig.ParseFile, Text);
		if(Text = FindToolType(diskobj->do_ToolTypes, "GEBÜHRENJEEINHEIT"))
			PrgConfig.UnitCost = (atoi(Text) < 1) ? 1 : ((atoi(Text) > 99) ? 99 : (atoi(Text)));
		if(Text = FindToolType(diskobj->do_ToolTypes, "GEBÜHRENNAME"))
			strncpy(PrgConfig.DMname, Text, 4); else strcpy(PrgConfig.DMname, "DM");
		if(Text = FindToolType(diskobj->do_ToolTypes, "gebührenname"))
			strncpy(PrgConfig.DMname, Text, 4); else strcpy(PrgConfig.DMname, "DM");
		if(!strlen(PrgConfig.DMname)) strcpy(PrgConfig.DMname, "DM");
		if(Text = FindToolType(diskobj->do_ToolTypes, "gebührenjeeinheit"))
			PrgConfig.UnitCost = (atoi(Text) < 1) ? 1 : ((atoi(Text) > 99) ? 99 : (atoi(Text)));
		if(Text = FindToolType(diskobj->do_ToolTypes, "GEBÜHRENANSICHT"))
			for(n = 0 ; n < 8 ; n++)
				if(Text[n] == '+') IC_Charge.ChargeType[n] = PrgConfig.UnitCost;
		if(Text = FindToolType(diskobj->do_ToolTypes, "gebührenansicht"))
			for(n = 0 ; n < 8 ; n++)
				if(Text[n] == '+') IC_Charge.ChargeType[n] = PrgConfig.UnitCost;
		for(n = 0 ; n < 8 ; n++)
		{
			sprintf(Buffer, "GERÄT%ld", n + 21);
			if(Text = FindToolType(diskobj->do_ToolTypes, Buffer))
				if(strlen(Text))
					strncpy(IC_DeviceNames.Names[n], Text, 8);
			IC_DeviceNames.Names[n][8] = 0x00;
		}
		for(n = 0 ; n < 8 ; n++)
		{
			sprintf(Buffer, "gerät%ld", n + 21);
			if(Text = FindToolType(diskobj->do_ToolTypes, Buffer))
				if(strlen(Text))
					strncpy(IC_DeviceNames.Names[n], Text, 8);
			IC_DeviceNames.Names[n][8] = 0x00;
		}
		PrgConfig.AliasListeName[0] = '\0';
		if(Text = FindToolType(diskobj->do_ToolTypes, "AliasListe"))
		{
		BPTR	fh;
			strcpy(PrgConfig.AliasListeName, Text);
			if(fh = Open(Text, MODE_OLDFILE))
			{
			char	Buffer[256];
				while(FGets(fh, Buffer, sizeof(Buffer) - 2))
				{
				BOOL	err = FALSE;
				int	i = 0, j = 0;
				char	Number[22], Name[22];

					if(Buffer[strlen(Buffer)-1] = '\n')
						Buffer[strlen(Buffer)-1] = '\0';

					while((isdigit(Buffer[i])) && (!err))
					{
						Number[j++] = Buffer[i++];
						if(j > 19)
							err = TRUE;
					}
					Number[j] = 0x00;
					if(!j) err = TRUE;
					j = 0;
					if(Buffer[i++] == ',')
						while((Buffer[i]) && (!err))
						{
							Name[j++] = Buffer[i++];
							if(j > 19)
								err = TRUE;
						}
					Name[j] = 0x00;
					if(!err)
					{
					struct	IC_Alias	*al = (struct IC_Alias *)IC_AliasList.lh_Head;
					BOOL		doit = TRUE;
						while(al -> Node.ln_Succ)
						{
							if(!stricmp(al->Name, Name))
								doit = FALSE;
							if(!stricmp(al->Number, Number))
								doit = FALSE;
							al = (struct IC_Alias *)al -> Node.ln_Succ;
						}
						if(doit)
						{
						struct	IC_Alias	*al = AllocVec(sizeof(struct IC_Alias), MEMF_CLEAR);
							if(al)
							{
								al->Node.ln_Name = al->Text;
								strcpy(al->Name, Name);
								strcpy(al->Number, Number);
								sprintf(al->Text, "%19s:%-19s", Name, Number);
								AddTail(&IC_AliasList, (struct Node *)al);
							}
						}
					}
				}
				Close(fh);
			}
			else
			{
			STRPTR	Lines[10] = {"Es ist ein Fehler aufgetreten!", "", PRGNAME" konnte die AliasListe nicht öffnen", "", NULL};
			char	Buffer[256];
			char	ErrBuf[100];
				Fault(IoErr(), NULL, ErrBuf, 90);
				sprintf(Buffer, "Fehler: %d (%s)", IoErr(), ErrBuf);
				Lines[3] = Buffer;
				INFOrequest(NULL, NULL, "Aliasliste-Fehler", Lines);
			}
		}
		n = 0;
		while(Text = diskobj->do_ToolTypes[n++])
		{
			if(!strnicmp(Text, "Alias=", strlen("Alias=")))
			{
			BOOL	err = FALSE;
			int	i, j;
			char	Number[22], Name[22];

				i = strlen("Alias=");
				j = 0;
				while((isdigit(Text[i])) && (!err))
				{
					Number[j++] = Text[i++];
					if(j > 19)
						err = TRUE;
				}
				Number[j] = 0x00;
				j = 0;
				if(Text[i++] == ',')
					while((Text[i]) && (!err))
					{
						Name[j++] = Text[i++];
						if(j > 19)
							err = TRUE;
					}
				Name[j] = 0x00;
				{
				struct	IC_Alias	*al = (struct IC_Alias *)IC_AliasList.lh_Head;
				BOOL		doit = TRUE;
					while(al -> Node.ln_Succ)
					{
						if(!stricmp(al->Name, Name))
							doit = FALSE;
						if(!stricmp(al->Number, Number))
							doit = FALSE;
						al = (struct IC_Alias *)al -> Node.ln_Succ;
					}
					if(doit)
					{
					struct	IC_Alias	*al = AllocVec(sizeof(struct IC_Alias), MEMF_CLEAR);
						if(al)
						{
							al->Node.ln_Name = al->Text;
							strcpy(al->Name, Name);
							strcpy(al->Number, Number);
							sprintf(al->Text, "%19s:%-19s", Name, Number);
							AddTail(&IC_AliasList, (struct Node *)al);
						}
					}
				}
			}
		}
	}

	/* Kurzwahlnummernliste loeschen */
	NewList(&IC_ShortList);

	Window = OpenMainWindow();
	LT_LockWindow(Window);

	if(Window)
	{
	int	n;
		MainWindow = Window;
		/* Pruefe die Anlage auf Bereitschaft */
		ICCheck(TRUE);
		/* Lese den Zustand ein (Day/Night) */
		if(!SerialError)
			IC_DayNight = ICReadDayNight(TRUE);
		/* Lese die Grundgeraeteinformationen ein, UpdateGUI */
		if(!SerialError)
			ICReadBaseConfig(&IC_BaseConfig, TRUE, TRUE);
		/* Pruefe, ob die richtige Anlage angeschlossen ist */
		if(!SerialError)
		{
			if((IC_BaseConfig.Connection	!= 0) ||
				(IC_BaseConfig.Protocol		!= 1) ||
				(IC_BaseConfig.VersionHigh  < 2))
			{
			STRPTR	Lines[] = {"Es ist ein Fehler aufgetreten!", "Ihre Anlage erfüllt nicht die Anforderungen von "PRGNAME, "",
										PRGNAME" unterstützt nur Mehrgeräteanschluß, ", "das E-DSS1-Protokoll", "und Firmwareversionen ab 2.0",
										"", "Eine dieser Voraussetzungen wird von Ihrer Anlage nicht erfüllt!", NULL};
				INFOrequest(Window, Handle, "Kompatibilitätsfehler", Lines);
				LT_DeleteHandle(Handle);
				Window = NULL;
				MainWindow = NULL;
			}
		}
		IC_Changed.BaseConfig = FALSE;
		for(n = 0 ; n < 8 ; n++)
			IC_Changed.DevConfig[n] = FALSE;
		IC_Changed.Charge = FALSE;
		for(n = 0 ; n <60 ; n++)
			IC_Changed.RufConfig[n] = FALSE;

		IC_Loaded.DevConfig = FALSE;
		IC_Loaded.Charge = FALSE;
		IC_Loaded.RufConfig = FALSE;
	}
	if(SerialError)
		if(Window)
		{
			LT_DeleteHandle(Handle);
			Window = NULL;
			MainWindow = NULL;
		}

	if((Window) &&
		(!SerialError))
	{
	struct	Menu				*WindowMenu;
	struct	IntuiMessage	*Message;
	ULONG							 MsgQualifier, MsgClass;
	UWORD							 MsgCode;
	struct	Gadget			*MsgGadget;
	BOOL							 done = FALSE;

		WindowMenu = LT_NewMenuTags(
											LAMN_LayoutHandle,	Handle,

											LAMN_TitleText,		"Projekt",
												!Key ? TAG_IGNORE : LAMN_ItemText,			"L\0Laden...",
													!Key ? TAG_IGNORE : LAMN_UserData,		MENU_Load,
												!Key ? TAG_IGNORE : LAMN_ItemText,			"S\0Speichern...",
													!Key ? TAG_IGNORE : LAMN_UserData,		MENU_Save,
												!Key ? TAG_IGNORE : LAMN_ItemText,			NM_BARLABEL,
												LAMN_ItemText,			"Einstellungen...",
													LAMN_UserData,		MENU_PrgConfig,
												LAMN_ItemText,			NM_BARLABEL,
												LAMN_ItemText,			"P\0Drucken",
													LAMN_UserData,		MENU_Print,
												LAMN_ItemText,			"?\0Info",
													LAMN_UserData,		MENU_Version,
												LAMN_ItemText,			NM_BARLABEL,
												LAMN_ItemText,			"Q\0Beenden",
													LAMN_UserData,		MENU_Quit,
											LAMN_TitleText,		"Anlage",
												LAMN_ItemText,			"Gebühren",
													LAMN_SubText,			"Übersicht...",
														LAMN_UserData,		MENU_Charge,
													LAMN_SubText,			"Löschen",
														LAMN_UserData,		MENU_ChargeReset,
												LAMN_ItemText,			NM_BARLABEL,
												LAMN_ItemText,			"Erneut einladen",
													LAMN_SubText,			"1\0Anlagenkonfiguration",
														LAMN_UserData,		MENU_ReloadBase,
													LAMN_SubText,			"2\0Endgerätekonfiguration",
														LAMN_UserData,		MENU_ReloadDev,
													LAMN_SubText,			"3\0Gebühren",
														LAMN_UserData,		MENU_ReloadCharge,
													LAMN_SubText,			"4\0Kurzwahlen",
														LAMN_UserData,		MENU_ReloadRuf,
												LAMN_ItemText,			NM_BARLABEL,
												LAMN_ItemText,			"Auf Lieferzustand zurücksetzen",
													LAMN_UserData,		MENU_ConfigReset,
												LAMN_ItemText,			"Anlagenreset",
													LAMN_UserData,		MENU_Reset,
											TAG_DONE);
		if(WindowMenu)
			SetMenuStrip(Window, WindowMenu);

		/* Lade jetzt ggf. alle Konfigs ein */
		if(PrgConfig.LoadAll)
		{
			/* Lade Devices */
			if(!SerialError)
				ICReadDevices(&IC_DevConfig[0], TRUE);
				IC_Loaded.DevConfig	= TRUE;
			/* Lade Gebuehren */
			if(!SerialError)
				ICReadCharge(&IC_Charge, PrgConfig.UnitCost, TRUE);
				IC_Loaded.Charge		= TRUE;
			ICUpdateDevConfig(&IC_BaseConfig, &IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)], LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE), IC_Charge.Charge[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)], IC_Charge.ChargeType[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)]);
			/* Lade Kurzwahlen */
			if(!SerialError)
			{
			int	n;
				LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, ~NULL, TAG_DONE);
				for(n = 0 ; n < 60 ; n++)
				{
					if(ICGetRufConfig(&IC_RufConfig[n], n+1, TRUE))
					{
						AddTail(&IC_ShortList, (struct Node *)&IC_RufConfig[n]);
						ICSetRC_LV(&IC_ShortList, &IC_RufConfig[n]);
					}
					else
						break;
				}
				LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, &IC_ShortList, GTLV_Selected, 0, TAG_DONE);
				ICSetRC_Gadgets(&IC_RufConfig[LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE)]);
			}
			IC_Loaded.RufConfig = TRUE;
		}

		LT_UnlockWindow(Window);
		do
		{
			WaitPort(Window -> UserPort);
			while(Message = GT_GetIMsg(Window->UserPort))
			{
				MsgClass			= Message->Class;
				MsgCode			= Message->Code;
				MsgQualifier	= Message->Qualifier;
				MsgGadget		= Message->IAddress;

				GT_ReplyIMsg(Message);
				LT_HandleInput(Handle, MsgQualifier, &MsgClass, &MsgCode, &MsgGadget);

				switch(MsgClass)
				{
					case	IDCMP_CLOSEWINDOW:
						if(!done)
						{
						int	n;
						BOOL	ask = FALSE;
							{
								done = TRUE;
								if(IC_Changed.BaseConfig || IC_Changed.Charge)
									ask = TRUE;
								for(n = 0 ; n < 8 ; n++)
									if(IC_Changed.DevConfig[n])
										ask = TRUE;
								for(n = 0 ; n < 60 ; n++)
									if(IC_Changed.RufConfig[n])
										ask = TRUE;
								if(ask)
									done = Requester(Window, PRGNAME": Achtung!", "Achtung!\nDurch das Beenden von "PRGNAME"\ngehen die gemachten Änderungen\nverloren!!!", "Beenden|Abbrechen", NULL, NULL);
							}
						}
						break;
					case	IDCMP_MENUPICK:
						LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
						while(MsgCode != MENUNULL)
						{
						struct	MenuItem	*MItem;
							MItem = ItemAddress(WindowMenu, MsgCode);
							switch((int)GTMENUITEM_USERDATA(MItem))
							{
								case	MENU_Quit:
									{
									int	n;
									BOOL	ask = FALSE;
										done = TRUE;
										if(IC_Changed.BaseConfig || IC_Changed.Charge)
											ask = TRUE;
										for(n = 0 ; n < 8 ; n++)
											if(IC_Changed.DevConfig[n])
												ask = TRUE;
										for(n = 0 ; n < 60 ; n++)
											if(IC_Changed.RufConfig[n])
												ask = TRUE;
										if(ask)
											done = Requester(Window, PRGNAME": Achtung!", "Achtung!\nDurch das Beenden von "PRGNAME"\ngehen die gemachten Änderungen\nverloren!!!", "Beenden|Abbrechen", NULL, NULL);
									}
									break;
								case	MENU_Load:
									LT_LockWindow(Window);
									LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Konfiguration einladen...", TAG_DONE);
									if(Menu_Load())
									{
										LT_SetAttributes(Handle, GAD_MAINPAGE, LATB_Active, 0, TAG_DONE);
										LT_SetAttributes(Handle, GAD_PAGE0, LAGR_ActivePage, 0, TAG_DONE);
									}
									LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
									LT_UnlockWindow(Window);
									break;
								case	MENU_Save:
									LT_LockWindow(Window);
									LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Konfiguration speichern...", TAG_DONE);
									Menu_Save();
									LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
									LT_UnlockWindow(Window);
									break;
								case	MENU_Version:
									LT_SetAttributes(Handle, GAD_MAINPAGE, LATB_Active, 0, TAG_DONE);
									LT_SetAttributes(Handle, GAD_PAGE0, LAGR_ActivePage, 0, TAG_DONE);
									break;
								case	MENU_Charge:
									LT_LockWindow(Window);
									if(!(IC_Loaded.Charge))
										if(!SerialError)
											ICReadCharge(&IC_Charge, PrgConfig.UnitCost, TRUE);
									IC_Loaded.Charge		= TRUE;
									LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Gebührenübersicht...", TAG_DONE);
									Menu_ViewCharge();
									LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
									LT_UnlockWindow(Window);
									break;
								case	MENU_ChargeReset:
									{
									int	n;
										for(n = 0 ; n < 8 ; n++)
											IC_Charge.Charge[n] = 0;
										IC_Changed.Charge = TRUE;
										IC_Loaded.Charge = TRUE;
										n = LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);
										if(IC_Charge.ChargeType[n])
											sprintf(gad_Charge, "%ld.%02ld", IC_Charge.Charge[n] * IC_Charge.Charge[n] / 100, (IC_Charge.Charge[n] * IC_Charge.Charge[n]) % 100);
										else
											sprintf(gad_Charge, "%ld", IC_Charge.Charge[n]);
										LT_SetAttributes(Handle, GAD_DevConfig_Charge, GTTX_Text, gad_Charge, TAG_DONE);
									}
									break;
								case	MENU_PrgConfig:
									LT_LockWindow(Window);
									LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Programmeinstellungen bearbeiten...", TAG_DONE);
									if(Menu_ChangePrgConfig())
									{
									int	n;
										LT_SetAttributes(Handle, GAD_MAINPAGE, LATB_Active, 0, TAG_DONE);
										LT_SetAttributes(Handle, GAD_PAGE0, LAGR_ActivePage, 0, TAG_DONE);

										LT_SetAttributes(Handle, GAD_BaseConfig_TFE_E, LAPU_Labels, &(GAD_BaseConfig_MusicOnHold_Labels[2]), TAG_DONE);
										for(n = 0 ; n < 8 ; n++)
											LT_SetAttributes(Handle, GAD_BaseConfig_TFE_T_21 + n, LA_LabelText, IC_DeviceNames.Names[n], TAG_DONE);
										LT_SetAttributes(Handle, GAD_BaseConfig_MusicOnHold, LAPU_Labels, GAD_BaseConfig_MusicOnHold_Labels, TAG_DONE);
										LT_SetAttributes(Handle, GAD_DevConfig_Device, LATB_Labels, GAD_DevConfig_Device_Labels, TAG_DONE);
										for(n = 0 ; n < 8 ; n++)
											LT_SetAttributes(Handle, GAD_RufConfig_Dev21 + n, LA_LabelText, IC_DeviceNames.Names[n], TAG_DONE);
										LT_SetAttributes(Handle, GAD_DevConfig_Reroute, LAPU_Labels, GAD_DevConfig_Reroute_Labels, TAG_DONE);
										LT_SetAttributes(Handle, GAD_DevConfig_RerouteIfBusy, LAPU_Labels, GAD_DevConfig_RerouteIfBusy_Labels, TAG_DONE);
										LT_SetAttributes(Handle, GAD_DevConfig_RerouteDelayed, LAPU_Labels, GAD_DevConfig_RerouteIfBusy_Labels, TAG_DONE);
										for(n = 0 ; n < 8 ; n++)
											LT_SetAttributes(Handle, GAD_DevConfig_IKnock0 + n, LA_LabelText, IC_DeviceNames.Names[n], TAG_DONE);

										if(PrgConfig.LoadAll)
										{
											/* Lade Devices */
											if(!SerialError && !IC_Loaded.DevConfig)
												ICReadDevices(&IC_DevConfig[0], TRUE);
												IC_Loaded.DevConfig	= TRUE;
											/* Lade Gebuehren */
											if(!SerialError && !IC_Loaded.Charge)
												ICReadCharge(&IC_Charge, PrgConfig.UnitCost, TRUE);
												IC_Loaded.Charge		= TRUE;
											ICUpdateDevConfig(&IC_BaseConfig, &IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)], LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE), IC_Charge.Charge[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)], IC_Charge.ChargeType[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)]);
											/* Lade Kurzwahlen */
											if(!SerialError && !IC_Loaded.RufConfig)
											{
											int	n;
												LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, ~NULL, TAG_DONE);
												for(n = 0 ; n < 60 ; n++)
												{
													if(ICGetRufConfig(&IC_RufConfig[n], n+1, TRUE))
													{
														AddTail(&IC_ShortList, (struct Node *)&IC_RufConfig[n]);
														ICSetRC_LV(&IC_ShortList, &IC_RufConfig[n]);
													}
													else
														break;
												}
												LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, &IC_ShortList, GTLV_Selected, 0, TAG_DONE);
												ICSetRC_Gadgets(&IC_RufConfig[LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE)]);
											}
											IC_Loaded.RufConfig = TRUE;
										}
									}
									LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
									LT_UnlockWindow(Window);
									break;
								case	MENU_Reset:
									LT_LockWindow(Window);
									{
										if(Requester(NULL, PRGNAME": Anlagenreset!", "ACHTUNG!!!\nDie Anlage wird in ihre Grundeinstellung zurückgesetzt\nSämtliche Konfigurationen gehen verloren!\n", "Weiter|Abbrechen", NULL, NULL))
										{
										UBYTE	CMD[] = {0x0b};
											LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Anlagenreset...", TAG_DONE);
											LT_SetAttributes(Handle, GAD_MAINPAGE, LATB_Active, 0, TAG_DONE);
											LT_SetAttributes(Handle, GAD_PAGE0, LAGR_ActivePage, 0, TAG_DONE);

											ICWrite(CMD, 1);

											Requester(NULL, PRGNAME": Anlagenreset!", "Bitte warten, bis die LED an der\nAnlage wieder angegangen ist!\n", "Ok", NULL, NULL);
											ICReadBaseConfig(&IC_BaseConfig, TRUE, TRUE);
											IC_Changed.BaseConfig = FALSE;
											/* Lade Devices */
											if((PrgConfig.LoadAll || IC_Loaded.DevConfig) && !SerialError)
											{
											int	i;
												ICReadDevices(&IC_DevConfig[0], TRUE);
												for(i = 0 ; i < 8 ; i++)
													IC_Changed.DevConfig[i] = FALSE;
											}
											/* Lade Gebuehren */
											if((PrgConfig.LoadAll || IC_Loaded.Charge) && !SerialError)
											{
												ICReadCharge(&IC_Charge, PrgConfig.UnitCost, TRUE);
												IC_Changed.Charge		= FALSE;
												ICUpdateDevConfig(&IC_BaseConfig, &IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)], LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE), IC_Charge.Charge[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)], IC_Charge.ChargeType[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)]);
											}
											/* Lade Kurzwahlen */
											if((PrgConfig.LoadAll || IC_Loaded.RufConfig) && !SerialError)
											{
											int	n;
												LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, ~NULL, TAG_DONE);
												if(!IC_Loaded.RufConfig)
												{
													for(n = 0 ; n < 60 ; n++)
													{
														AddTail(&IC_ShortList, (struct Node *)&IC_RufConfig[n]);
														IC_RufConfig[n].Node.ln_Name = IC_RufConfig[n].Number;
													}
												}
												for(n = 0 ; n < 60 ; n++)
												{
													if(ICGetRufConfig(&IC_RufConfig[n], n+1, TRUE))
													{
														ICSetRC_LV(&IC_ShortList, &IC_RufConfig[n]);
													}
													else
														break;
												}
												LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, &IC_ShortList, GTLV_Selected, 0, TAG_DONE);
												ICSetRC_Gadgets(&IC_RufConfig[LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE)]);
											}
										LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
										}
									}
									LT_UnlockWindow(Window);
									break;
								case	MENU_ConfigReset:
									LT_LockWindow(Window);
									LT_SetAttributes(Handle, GAD_MAINPAGE, LATB_Active, 0, TAG_DONE);
									LT_SetAttributes(Handle, GAD_PAGE0, LAGR_ActivePage, 0, TAG_DONE);
									ICConfigReset();
									LT_UnlockWindow(Window);
									break;
								case	MENU_ReloadBase:
									LT_LockWindow(Window);
									{
										ICReadBaseConfig(&IC_BaseConfig, TRUE, TRUE);
										IC_Changed.BaseConfig = FALSE;
									}
									LT_UnlockWindow(Window);
									break;
								case	MENU_ReloadDev:
									LT_LockWindow(Window);
									{
									int	n;
										ICReadDevices(&IC_DevConfig[0], TRUE);
										for(n = 0 ; n < 8 ; n++)
											IC_Changed.DevConfig[n] = FALSE;
										IC_Loaded.DevConfig = TRUE;
									}
									LT_UnlockWindow(Window);
									break;
								case	MENU_ReloadCharge:
									LT_LockWindow(Window);
									{
										ICReadCharge(&IC_Charge, PrgConfig.UnitCost, TRUE);
										IC_Changed.Charge		= FALSE;
										ICUpdateDevConfig(&IC_BaseConfig, &IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)], LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE), IC_Charge.Charge[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)], IC_Charge.ChargeType[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)]);
										IC_Loaded.Charge = TRUE;
									}
									LT_UnlockWindow(Window);
									break;
								case	MENU_ReloadRuf:
									LT_LockWindow(Window);
									{
									int	n;
										LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, ~NULL, TAG_DONE);
										if(!IC_Loaded.RufConfig)
										{
											for(n = 0 ; n < 60 ; n++)
											{
												AddTail(&IC_ShortList, (struct Node *)&IC_RufConfig[n]);
												IC_RufConfig[n].Node.ln_Name = IC_RufConfig[n].Number;
											}
										}
										for(n = 0 ; n < 60 ; n++)
										{
											if(ICGetRufConfig(&IC_RufConfig[n], n+1, TRUE))
											{
												ICSetRC_LV(&IC_ShortList, &IC_RufConfig[n]);
											}
											else
												break;
										}
										IC_Loaded.RufConfig = TRUE;
										LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, &IC_ShortList, GTLV_Selected, 0, TAG_DONE);
										ICSetRC_Gadgets(&IC_RufConfig[LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE)]);
									}
									LT_UnlockWindow(Window);
									break;
								case	MENU_Print:
									LT_LockWindow(Window);
									{
										LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Drucke Anlageneinstellungen...", TAG_DONE);
										PrintConfig();
										LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
									}
									LT_UnlockWindow(Window);
									break;
							}
							MsgCode = MItem->NextSelect;
						}
						break;
					case	IDCMP_GADGETUP:
						LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
						switch(MsgGadget->GadgetID)
						{
						case	GAD_Cancel:
							{
							int	n;
							BOOL	ask = FALSE;
								done = TRUE;
								if(IC_Changed.BaseConfig || IC_Changed.Charge)
									ask = TRUE;
								for(n = 0 ; n < 8 ; n++)
									if(IC_Changed.DevConfig[n])
										ask = TRUE;
								for(n = 0 ; n < 60 ; n++)
									if(IC_Changed.RufConfig[n])
										ask = TRUE;
								if(ask)
									done = Requester(Window, PRGNAME": Achtung!", "Achtung!\nDurch das Beenden von "PRGNAME"\ngehen die gemachten Änderungen\nverloren!!!", "Beenden|Abbrechen", NULL, NULL);
							}
							break;
						case	GAD_Save:
							if(Key == (struct Keyfile *)-1)
								for(;;);
							LT_LockWindow(Window);
							{
							int	n;
							BOOL	saving = FALSE;
								ICWriteDayNight(IC_DayNight, FALSE);
								if(IC_Changed.BaseConfig)
								{
									ICWriteBaseConfig(&IC_BaseConfig, TRUE);
									IC_Changed.BaseConfig = FALSE;
									saving = TRUE;
								}
								for(n = 0 ; n < 8 ; n++)
								{
									if(IC_Changed.DevConfig[n])
									{
										ICWriteDayNight(IC_DayNight, FALSE);
										ICWriteDevices(&IC_DevConfig[n], TRUE);
										ICWriteDayNight(IC_DayNight, FALSE);
										ICWriteDevices(&IC_DevConfig[n], TRUE);
										saving = TRUE;
									}
									IC_Changed.DevConfig[n] = FALSE;
								}
								if(IC_Changed.Charge)
								{
									ICWriteCharge(&IC_Charge, TRUE);
									IC_Changed.Charge = FALSE;
									saving = TRUE;
								}
								for(n = 0 ; n < 60 ; n++)
								{
									if(IC_Changed.RufConfig[n])
									{
										ICWriteRufConfig(&IC_RufConfig[n], TRUE);
										saving = TRUE;
									}
									IC_Changed.RufConfig[n] = FALSE;
								}
								if(saving)
									ICSaveConfig(TRUE);
								else
									LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Es wurden keine Änderungen an der Konfiguration gemacht!", TAG_DONE);
							}
							LT_UnlockWindow(Window);
							break;

						/* Ober-Page-Selector */
						case	GAD_MAINPAGE:
							LT_LockWindow(Window);
							{
							int	i = LT_GetAttributes(Handle, GAD_MAINPAGE, TAG_DONE);
								switch(i)
								{
									case	0:	/* Allgemeines */
										break;
									case	1:	/* Anlage */
										break;
									case	2:	/* Geraete */
										if(!(IC_Loaded.DevConfig))
											if(!SerialError)
												ICReadDevices(&IC_DevConfig[0], TRUE);
										if(!(IC_Loaded.Charge))
											if(!SerialError)
												ICReadCharge(&IC_Charge, PrgConfig.UnitCost, TRUE);
										IC_Loaded.DevConfig	= TRUE;
										IC_Loaded.Charge		= TRUE;
										{
											int	n = LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);

											if(IC_BaseConfig.MusicPort == (n + 1))
												LT_SetAttributes(Handle, GAD_DevConfig_Page0, LAGR_ActivePage, 1, TAG_DONE);
											else
											{
												ICUpdateDevConfig(&IC_BaseConfig, &IC_DevConfig[n], n, IC_Charge.Charge[n], IC_Charge.ChargeType[n]);
												LT_SetAttributes(Handle, GAD_DevConfig_Page0, LAGR_ActivePage, 0, TAG_DONE);
											}
										}
										break;
									case	3:	/* Kurzwahl */
										if(!(IC_Loaded.RufConfig))
											if(!SerialError)
											{
											int	n;
												LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, ~NULL, TAG_DONE);
												for(n = 0 ; n < 60 ; n++)
												{
													if(ICGetRufConfig(&IC_RufConfig[n], n+1, TRUE))
													{
														AddTail(&IC_ShortList, (struct Node *)&IC_RufConfig[n]);
														ICSetRC_LV(&IC_ShortList, &IC_RufConfig[n]);
													}
													else
														break;
												}
												LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, &IC_ShortList, GTLV_Selected, 0, TAG_DONE);
												ICSetRC_Gadgets(&IC_RufConfig[LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE)]);
											}
										IC_Loaded.RufConfig = TRUE;
										break;
								}
								LT_SetAttributes(Handle, GAD_PAGE0, LAGR_ActivePage, i, TAG_DONE);
							}
							LT_UnlockWindow(Window);
							break;

						/* BaseConfig */
						case	GAD_BaseConfig_TagNacht:
							{
							int	i = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
							int	n;
							BOOL	doit = TRUE;
								LT_LockWindow(Window);
								if(IC_Changed.BaseConfig || IC_Changed.DevConfig[0] || IC_Changed.DevConfig[1] || IC_Changed.DevConfig[2] || IC_Changed.DevConfig[3] || IC_Changed.DevConfig[4] || IC_Changed.DevConfig[5] || IC_Changed.DevConfig[6] || IC_Changed.DevConfig[7])
									doit = Requester(Window, PRGNAME": Achtung!", "Achtung!\nDurch das Umschalten der Tag-/Nachtkonfiguration\nkönnen gemachte Änderungen der Anlagenkonfiguration,\nbzw. der Endgerätekonfiguration verloren gehen!!!", "Weiter|Abbrechen", NULL, NULL);
								if(doit)
								{
									ICWriteDayNight(i, TRUE);
									if(!SerialError)
										ICReadBaseConfig(&IC_BaseConfig, TRUE, TRUE);
									if((!SerialError) && (PrgConfig.LoadAll))
									{
										ICReadDevices(&IC_DevConfig[0], TRUE);
										IC_Loaded.DevConfig = TRUE;
									}
									else
										IC_Loaded.DevConfig = FALSE;
									IC_Changed.BaseConfig = FALSE;
									for(n = 0 ; n < 8 ; n++)
										IC_Changed.DevConfig[n] = FALSE;
								}
								LT_SetAttributes(Handle, MsgGadget->GadgetID, LAPU_Active, IC_DayNight, TAG_DONE);
								LT_UnlockWindow(Window);
							}
							break;
						case	GAD_BaseConfig_Land_Popup:
							{
							int	i = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
								i = LandesKennung[i];
								if(i != 0)
								{
									LT_SetAttributes(Handle, GAD_BaseConfig_Land_Nr, GTIN_Number, i, TAG_DONE);
									IC_BaseConfig.CountryCode[0] = (i >> 8) & 0xFF;
									IC_BaseConfig.CountryCode[1] = (  i   ) & 0xFF;
								}
							}
							break;
						case	GAD_BaseConfig_Land_Nr:
							{
							int	i = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
								for(n = 0 ; n < (sizeof(LandesKennung) / sizeof(int)) ; n++)
									if(LandesKennung[n] == i)
									{
										LT_SetAttributes(Handle, GAD_BaseConfig_Land_Popup, LAPU_Active, n, TAG_DONE);
										break;
									}
								if(n == (sizeof(LandesKennung) / sizeof(int)))
									LT_SetAttributes(Handle, GAD_BaseConfig_Land_Popup, LAPU_Active, 0, TAG_DONE);
								IC_BaseConfig.CountryCode[0] = (i >> 8) & 0xFF;
								IC_BaseConfig.CountryCode[1] = (  i   ) & 0xFF;
							}
							break;
						case	GAD_BaseConfig_MSN0:
						case	GAD_BaseConfig_MSN1:
						case	GAD_BaseConfig_MSN2:
						case	GAD_BaseConfig_MSN3:
						case	GAD_BaseConfig_MSN4:
						case	GAD_BaseConfig_MSN5:
						case	GAD_BaseConfig_MSN6:
						case	GAD_BaseConfig_MSN7:
						case	GAD_BaseConfig_MSN8:
						case	GAD_BaseConfig_MSN9:
							{
							char	*Number = (char *)LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
							int	n;
								for(n = 0 ; n < strlen(Number) ; n++)
									if(!isdigit(Number[n]))
									{
										Number = NULL;
										LT_SetAttributes(Handle, MsgGadget->GadgetID, GTST_String, gad_MSN[MsgGadget->GadgetID - GAD_BaseConfig_MSN0], TAG_DONE);
									}
								if(Number)
								{
									strcpy(gad_MSN[MsgGadget->GadgetID - GAD_BaseConfig_MSN0], Number);
									String2BCD(IC_BaseConfig.MSN[MsgGadget->GadgetID - GAD_BaseConfig_MSN0], Number, 5, 1);
								}
							}
							break;
						case	GAD_BaseConfig_MSN0_Call:
						case	GAD_BaseConfig_MSN1_Call:
						case	GAD_BaseConfig_MSN2_Call:
						case	GAD_BaseConfig_MSN3_Call:
						case	GAD_BaseConfig_MSN4_Call:
						case	GAD_BaseConfig_MSN5_Call:
						case	GAD_BaseConfig_MSN6_Call:
						case	GAD_BaseConfig_MSN7_Call:
						case	GAD_BaseConfig_MSN8_Call:
						case	GAD_BaseConfig_MSN9_Call:
							{
							int n = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
							IC_BaseConfig.Signaling[MsgGadget->GadgetID - GAD_BaseConfig_MSN0_Call] = (n < 3) ? n : ((n == 4) ? 3 : 4);
							}
							break;
						case	GAD_BaseConfig_MusicOnHold:
							{
							int n = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
								if(n == 0)
									IC_BaseConfig.Music = 0x00, IC_BaseConfig.MusicPort = 0x00;
								else
								if(n == 1)
									IC_BaseConfig.Music = 0x01, IC_BaseConfig.MusicPort = 0x00;
								else
									IC_BaseConfig.Music = 0x00, IC_BaseConfig.MusicPort = n-1;
							}
							break;
						case	GAD_BaseConfig_TFE_MainPage:
							{
							int	i = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
								LT_SetAttributes(Handle, GAD_BaseConfig_TFE_Select, LAGR_ActivePage, i, TAG_DONE);
								if(i == 2)	/* IC_Alarm */
									if(IC_Alarm == 0)
										IC_Alarm = 1;
							}
							break;
						case	GAD_BaseConfig_TFE_E:
							{
							int	n = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
								IC_BaseConfig.TFEAssignment = n + 21;
							}
							break;
						case	GAD_BaseConfig_TFE_T:
							{
							int	i;
							int	n = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
								for(i = 0 ; i < 8 ; i++)
									LT_SetAttributes(Handle, GAD_BaseConfig_TFE_T_21 + i, GTCB_Checked, IC_BaseConfig.TFELoc[n] & (1 << i), TAG_DONE);
							}
							break;
						case	GAD_BaseConfig_TFE_T_21:
						case	GAD_BaseConfig_TFE_T_22:
						case	GAD_BaseConfig_TFE_T_23:
						case	GAD_BaseConfig_TFE_T_24:
						case	GAD_BaseConfig_TFE_T_25:
						case	GAD_BaseConfig_TFE_T_26:
						case	GAD_BaseConfig_TFE_T_27:
						case	GAD_BaseConfig_TFE_T_28:
							{
							int	i, n;
								n = MsgGadget->GadgetID - GAD_BaseConfig_TFE_T_21;
								i = LT_GetAttributes(Handle, GAD_BaseConfig_TFE_T, TAG_DONE);
								if(LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE))
									IC_BaseConfig.TFELoc[i] |= (1 << n);
								else
									IC_BaseConfig.TFELoc[i] &= ~(1 << n);
							}
							break;
						case	GAD_BaseConfig_TFE_A:
							{
							int	n = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
								IC_Alarm = n + 1;
							}
							break;

						/* DevConfig */
						case	GAD_DevConfig_Device:
							{
							int	n = LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);
								if(IC_BaseConfig.MusicPort == (n + 1))
									LT_SetAttributes(Handle, GAD_DevConfig_Page0, LAGR_ActivePage, 1, TAG_DONE);
								else
								{
									ICUpdateDevConfig(&IC_BaseConfig, &IC_DevConfig[n], n, IC_Charge.Charge[n], IC_Charge.ChargeType[n]);
									LT_SetAttributes(Handle, GAD_DevConfig_Page0, LAGR_ActivePage, 0, TAG_DONE);
								}
							}
							break;
						case	GAD_DevConfig_MSN0_Call:
						case	GAD_DevConfig_MSN1_Call:
						case	GAD_DevConfig_MSN2_Call:
						case	GAD_DevConfig_MSN3_Call:
						case	GAD_DevConfig_MSN4_Call:
						case	GAD_DevConfig_MSN5_Call:
						case	GAD_DevConfig_MSN6_Call:
						case	GAD_DevConfig_MSN7_Call:
						case	GAD_DevConfig_MSN8_Call:
						case	GAD_DevConfig_MSN9_Call:
							{
							int	y;
								y = 1 << LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);
								if(LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE))
									IC_BaseConfig.MSNGroups[MsgGadget->GadgetID - GAD_DevConfig_MSN0_Call] |= y;
								else
									IC_BaseConfig.MSNGroups[MsgGadget->GadgetID - GAD_DevConfig_MSN0_Call] &= ~y;
							}
							break;
						case	GAD_DevConfig_PIN:
							{
							char	*Number = (char *)LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
							int	n;
								for(n = 0 ; n < strlen(Number) ; n++)
									if(!isdigit(Number[n]))
									{
										Number = NULL;
									}
								if(Number)
								{
									sprintf(gad_PIN, "%04ld", atol(Number));
									String2BCD(IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)].PIN, gad_PIN, 2, 1);
								}
								LT_SetAttributes(Handle, GAD_DevConfig_PIN, GTST_String, gad_PIN, TAG_DONE);
							}
							break;
						case	GAD_DevConfig_DialCaps:
							IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)].DialCaps = LT_GetAttributes(Handle, GAD_DevConfig_DialCaps, TAG_DONE);
							break;
						case	GAD_DevConfig_Service:
							IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)].Service = LT_GetAttributes(Handle, GAD_DevConfig_Service, TAG_DONE);
							break;
						case	GAD_DevConfig_ChargePulse:
							IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)].ChargePulse = LT_GetAttributes(Handle, GAD_DevConfig_ChargePulse, TAG_DONE);
							break;
						case	GAD_DevConfig_TerminalMode:
							IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)].TerminalMode = LT_GetAttributes(Handle, GAD_DevConfig_TerminalMode, TAG_DONE);
							break;
						case	GAD_DevConfig_ChargeType:
							{
							int	n = LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);
								IC_Charge.ChargeType[n] ^= PrgConfig.UnitCost;
								if(IC_Charge.ChargeType[n])
									sprintf(gad_Charge, "%ld.%02ld", IC_Charge.Charge[n] * IC_Charge.ChargeType[n] / 100, (IC_Charge.Charge[n] * IC_Charge.ChargeType[n]) % 100);
								else
									sprintf(gad_Charge, "%ld", IC_Charge.Charge[n]);
								LT_SetAttributes(Handle, GAD_DevConfig_Charge,			GTTX_Text, gad_Charge, TAG_DONE);
							}
							break;
						case	GAD_DevConfig_ChargeReset:
							{
							int	n = LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);
								IC_Charge.Charge[n] = 0x00;
								IC_Charge.ChargeInfo[ 2*n ] = 0x00;
								IC_Charge.ChargeInfo[2*n+1] = 0x00;
								if(IC_Charge.ChargeType[n])
									sprintf(gad_Charge, "%ld.%02ld", IC_Charge.Charge[n] * IC_Charge.ChargeType[n] / 100, (IC_Charge.Charge[n] * IC_Charge.ChargeType[n]) % 100);
								else
									sprintf(gad_Charge, "%ld", IC_Charge.Charge[n]);
								LT_SetAttributes(Handle, GAD_DevConfig_Charge,			GTTX_Text, gad_Charge, TAG_DONE);
							}
							break;
						case	GAD_DevConfig_Reroute:
							{
							int	Dev = LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);
							int	n = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
								if(Dev == (n-2))
									LT_SetAttributes(Handle, MsgGadget->GadgetID, LAPU_Active, ((IC_DevConfig[Dev].Reroute <= 1) ? IC_DevConfig[Dev].Reroute : (IC_DevConfig[Dev].Reroute - 21 + 2))), n = ((IC_DevConfig[Dev].Reroute <= 1) ? IC_DevConfig[Dev].Reroute : (IC_DevConfig[Dev].Reroute - 21 + 2));
								else
									IC_DevConfig[Dev].Reroute = (n <= 1) ? (n) : (n + 21 - 2);
								LT_SetAttributes(Handle, GAD_DevConfig_ExtNum, GA_Disabled, (n == 1) ? FALSE : TRUE, TAG_DONE);
								LT_SetAttributes(Handle, GAD_DevConfig_RerouteIfBusy, GA_Disabled, (n == 0) ? FALSE : TRUE, TAG_DONE);
								LT_SetAttributes(Handle, GAD_DevConfig_RingsUntilReroute, GA_Disabled, (n == 0) ? FALSE : TRUE, TAG_DONE);
								LT_SetAttributes(Handle, GAD_DevConfig_RerouteDelayed, GA_Disabled, (n == 0) ? FALSE : TRUE, TAG_DONE);
							}
							break;
						case	GAD_DevConfig_ExtNum:
							{
							char	*Number = (char *)LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
							int	n;
								for(n = 0 ; n < strlen(Number) ; n++)
									if(!isdigit(Number[n]))
										Number = NULL;
								if(Number)
								{
								char	NewNumber[22];
									if(strlen(Number))
									{
										strcpy(NewNumber+1, Number);
										NewNumber[0] = '0';
									}
									else
										NewNumber[0] = 0x00;
									strcpy(gad_ExtNum, GetAliasName(Number));
									String2BCD(IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)].ExtNum, NewNumber, 10, 1);
									IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)].ExtNumLen = strlen(NewNumber);
								}
								LT_SetAttributes(Handle, GAD_DevConfig_ExtNum, GTST_String, gad_ExtNum, TAG_DONE);
							}
							break;
						case	GAD_DevConfig_RerouteIfBusy:
							{
							int	Dev = LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);
							int	n = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
								if(Dev == (n - 1))
									LT_SetAttributes(Handle, MsgGadget->GadgetID, LAPU_Active, IC_DevConfig[Dev].RerouteIfBusy, TAG_DONE);
								else
									IC_DevConfig[Dev].RerouteIfBusy = n;
							}
							break;
						case	GAD_DevConfig_RingsUntilReroute:
								IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)].RingsUntilReroute = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
							break;
						case	GAD_DevConfig_RerouteDelayed:
							{
							int	Dev = LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);
							int	n = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
								if(Dev == (n - 1))
									LT_SetAttributes(Handle, MsgGadget->GadgetID, LAPU_Active, IC_DevConfig[Dev].RerouteDelayed, TAG_DONE);
								else
									IC_DevConfig[Dev].RerouteDelayed = n;
							}
							break;
						case	GAD_DevConfig_EKnock0:
						case	GAD_DevConfig_EKnock1:
						case	GAD_DevConfig_EKnock2:
						case	GAD_DevConfig_EKnock3:
						case	GAD_DevConfig_EKnock4:
						case	GAD_DevConfig_EKnock5:
						case	GAD_DevConfig_EKnock6:
						case	GAD_DevConfig_EKnock7:
						case	GAD_DevConfig_EKnock8:
						case	GAD_DevConfig_EKnock9:
							{
							int	Dev = LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);
							int	n = MsgGadget->GadgetID - GAD_DevConfig_EKnock0;
							UWORD Flag = (IC_DevConfig[Dev].ExternalKnock[1] << 8) + IC_DevConfig[Dev].ExternalKnock[0];
								if(LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE))
									Flag |=  (1 << n);
								else
									Flag &= ~(1 << n);
								IC_DevConfig[Dev].ExternalKnock[1] = (Flag >> 8) & 0xFF;
								IC_DevConfig[Dev].ExternalKnock[0] = Flag & 0xFF;
							}
							break;
						case	GAD_DevConfig_TKnock:
							{
							int	Dev = LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);
								if(LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE))
									IC_DevConfig[Dev].ExternalKnock[1] |=  (1<<3);
								else
									IC_DevConfig[Dev].ExternalKnock[1] &= ~(1<<3);
							}
							break;
						case	GAD_DevConfig_IKnock0:
						case	GAD_DevConfig_IKnock1:
						case	GAD_DevConfig_IKnock2:
						case	GAD_DevConfig_IKnock3:
						case	GAD_DevConfig_IKnock4:
						case	GAD_DevConfig_IKnock5:
						case	GAD_DevConfig_IKnock6:
						case	GAD_DevConfig_IKnock7:
							{
							int	Dev = LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);
							int	n = MsgGadget->GadgetID - GAD_DevConfig_IKnock0;
								if(LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE))
									IC_DevConfig[Dev].InternalKnock |=  (1<<n);
								else
									IC_DevConfig[Dev].InternalKnock &= ~(1<<n);
							}
							break;

						/* RufConfig */
						case	GAD_RufConfig_LV:
							ICSetRC_Gadgets(&IC_RufConfig[LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE)]);
							break;
						case	GAD_RufConfig_Number:
							{
							int	n = LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE);
							STRPTR	Nummer = (STRPTR)LT_GetAttributes(Handle, GAD_RufConfig_Number, TAG_DONE);
							UBYTE		NewNumber[22];
							UBYTE		Old[10];
							int		i;
								for(i = 0 ; i < strlen(Nummer) ; i++)
									if(!isdigit(Nummer[i]))
										Nummer = NULL;
								if(Nummer)
								{
									if(strlen(Nummer))
									{
										strcpy(gad_RufNummer, GetAliasName(Nummer));
										strcpy(NewNumber+1, Nummer);
										NewNumber[0] = '0';
									}
									else
									{
										strcpy(gad_RufNummer, Nummer);
										strcpy(NewNumber, Nummer);
									}
									for(i = 0 ; i < 10 ; i++)
										Old[i] = IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 0 + i];
									String2BCD(&(IC_RufConfig[n].ReadIn[5]), NewNumber, (strlen(NewNumber) + 1)/2, 0);
									IC_RufConfig[n].ReadIn[4] = strlen(NewNumber);
									for(i = 0 ; i < 10 ; i++)
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 0 + i] = Old[i];
									ICSetRC_LV(&IC_ShortList, &IC_RufConfig[n]);
								}
								LT_SetAttributes(Handle, MsgGadget->GadgetID, GTST_String, gad_RufNummer, TAG_DONE);
							}
							break;
						case	GAD_RufConfig_Type:
							{
							int	n = LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE);
							int	t = LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE);
							int	i;
								switch(t)
								{
									case	0:		/* Inaktiv */
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 0] = 0x00;
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 1] = 0x00;
										break;
									case	1:		/* Babyruf */
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 0] = 0xFF;
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 1] = 0x00;
										break;
									case	2:		/* Kurzwahl / Sperre */
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 0] = 0x00;
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 1] = 0xFF;
										break;
								}
								if(t != 3)		/* Nicht beliebig */
									for(i = 0 ; i < 8 ; i++)
										LT_SetAttributes(Handle, GAD_RufConfig_Dev21 + i, LAPU_Active, t, TAG_DONE);
								ICSetRC_LV(&IC_ShortList, &IC_RufConfig[n]);
							}
							break;
						case	GAD_RufConfig_K_S:
							{
							int n = LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE);
								IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 3] = (LT_GetAttributes(Handle, GAD_RufConfig_K_S, TAG_DONE)) ? 0xFF : 0x00;
								ICSetRC_Gadgets(&IC_RufConfig[LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE)]);
								ICSetRC_LV(&IC_ShortList, &IC_RufConfig[n]);
							}
							break;
						case	GAD_RufConfig_Call:
							{
							int	n = LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE);
								switch(LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE))
								{
									case	0:		/* Normal */
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 2] = 0x00;
										break;
									case	1:		/* Ruf 1 */
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 2] = 0x01;
										break;
									case	2:		/* Ruf 2 */
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 2] = 0x02;
										break;
									case	3:		/* Ruf 3 */
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 2] = 0x04;
										break;
									default:		/* Abweisen */
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 2] = 0x03;
										break;
								}
								ICSetRC_LV(&IC_ShortList, &IC_RufConfig[n]);
							}
							break;
						case	GAD_RufConfig_Dev21:
						case	GAD_RufConfig_Dev22:
						case	GAD_RufConfig_Dev23:
						case	GAD_RufConfig_Dev24:
						case	GAD_RufConfig_Dev25:
						case	GAD_RufConfig_Dev26:
						case	GAD_RufConfig_Dev27:
						case	GAD_RufConfig_Dev28:
							{
							int	n = LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE);
							int	b = MsgGadget->GadgetID - GAD_RufConfig_Dev21;
								switch(LT_GetAttributes(Handle, MsgGadget->GadgetID, TAG_DONE))
								{
									case	0:	/* Inaktiv */
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 0] &= ~(1 << b);
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 1] &= ~(1 << b);
										break;
									case	1:	/* Babyruf */
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 0] |=  (1 << b);
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 1] &= ~(1 << b);
										break;
									case	2: /* Kurzwahl/Sperre */
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 0] &= ~(1 << b);
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 1] |=  (1 << b);
										break;
								}
								LT_SetAttributes(Handle, GAD_RufConfig_Type, LAPU_Active, 3, TAG_DONE);
								ICSetRC_LV(&IC_ShortList, &IC_RufConfig[n]);
							}
							break;
						}
						break;
					case	IDCMP_IDCMPUPDATE:
						switch(MsgGadget->GadgetID)
						{
						case	GAD_DevConfig_ExtNum:
							LT_LockWindow(Window);
							{
							struct	IC_Alias	*al;
								if(al = SelectAlias())
								{
								char	NewNumber[22];
									strcpy(NewNumber+1, al->Number);
									NewNumber[0] = '0';
									strcpy(gad_ExtNum, al->Name);
									String2BCD(IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)].ExtNum, NewNumber, 10, 1);
									IC_DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)].ExtNumLen = strlen(NewNumber);
								}
								LT_SetAttributes(Handle, GAD_DevConfig_ExtNum, GTST_String, gad_ExtNum, TAG_DONE);
							}
							LT_UnlockWindow(Window);
							break;
						case	GAD_RufConfig_Number:
							LT_LockWindow(Window);
							{
							struct	IC_Alias	*al;
								if(al = SelectAlias())
								{
								int	n = LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE);
								STRPTR	Nummer = al->Number;
								UBYTE		NewNumber[22];
								UBYTE		Old[10];
								int		i;
									strcpy(NewNumber+1, Nummer);
									NewNumber[0] = '0';
									for(i = 0 ; i < 10 ; i++)
										Old[i] = IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 0 + i];
									String2BCD(&(IC_RufConfig[n].ReadIn[5]), NewNumber, (strlen(NewNumber) + 1)/2, 0);
									IC_RufConfig[n].ReadIn[4] = strlen(NewNumber);
									for(i = 0 ; i < 10 ; i++)
										IC_RufConfig[n].ReadIn[(IC_RufConfig[n].ReadIn[4] + 1)/2 + 5 + 0 + i] = Old[i];
									ICSetRC_LV(&IC_ShortList, &IC_RufConfig[n]);
									LT_SetAttributes(Handle, GAD_RufConfig_Number, GTST_String, al->Name, TAG_DONE);
								}
							}
							LT_UnlockWindow(Window);
							break;
						}
						break;
				}
				if((MsgClass == IDCMP_GADGETUP) ||
					(MsgClass == IDCMP_IDCMPUPDATE))
				{
					if((MsgGadget->GadgetID > GAD_BaseConfig_MIN) &&
						(MsgGadget->GadgetID < GAD_BaseConfig_MAX) &&
						(MsgGadget->GadgetID !=GAD_BaseConfig_TagNacht))
					{
						IC_Changed.BaseConfig = TRUE;
					}
					else
					if((MsgGadget->GadgetID > GAD_DevConfig_MIN) &&
						(MsgGadget->GadgetID < GAD_DevConfig_MAX))
					{
						if(MsgGadget->GadgetID == GAD_DevConfig_ChargeReset)
							IC_Changed.Charge = TRUE;
						else
						if((MsgGadget->GadgetID >= GAD_DevConfig_MSN0_Call) &&
							(MsgGadget->GadgetID <= GAD_DevConfig_MSN9_Call))
							IC_Changed.BaseConfig = TRUE;
						else
						if((MsgGadget->GadgetID >= GAD_DevConfig_Device) &&
							(MsgGadget->GadgetID <= GAD_DevConfig_Charge))
							;
						else
							IC_Changed.DevConfig[LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE)] = TRUE;
					}
					else
					if((MsgGadget->GadgetID > GAD_RufConfig_MIN) &&
						(MsgGadget->GadgetID < GAD_RufConfig_MAX))
					{
						if(MsgGadget->GadgetID != GAD_RufConfig_LV)
							IC_Changed.RufConfig[LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE)] = TRUE;
					}
				}
			}
			/* Gadgets in den richtigen Status bringen */
			{
			int	n = (LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE) == ~NULL) ? TRUE : FALSE;
				LT_SetAttributes(Handle, GAD_RufConfig_Number,	GA_Disabled, n, TAG_DONE);
				LT_SetAttributes(Handle, GAD_RufConfig_Type,		GA_Disabled, n, TAG_DONE);
				LT_SetAttributes(Handle, GAD_RufConfig_K_S,		GA_Disabled, n, TAG_DONE);
				LT_SetAttributes(Handle, GAD_RufConfig_Call,		GA_Disabled, n, TAG_DONE);
				LT_SetAttributes(Handle, GAD_RufConfig_Dev21,	GA_Disabled, n, TAG_DONE);
				LT_SetAttributes(Handle, GAD_RufConfig_Dev22,	GA_Disabled, n, TAG_DONE);
				LT_SetAttributes(Handle, GAD_RufConfig_Dev23,	GA_Disabled, n, TAG_DONE);
				LT_SetAttributes(Handle, GAD_RufConfig_Dev24,	GA_Disabled, n, TAG_DONE);
				LT_SetAttributes(Handle, GAD_RufConfig_Dev25,	GA_Disabled, n, TAG_DONE);
				LT_SetAttributes(Handle, GAD_RufConfig_Dev26,	GA_Disabled, n, TAG_DONE);
				LT_SetAttributes(Handle, GAD_RufConfig_Dev27,	GA_Disabled, n, TAG_DONE);
				LT_SetAttributes(Handle, GAD_RufConfig_Dev28,	GA_Disabled, n, TAG_DONE);
			}
		}
		while((!done) && (!SerialError));
		ClearMenuStrip(Window);
		LT_DeleteHandle(Handle);
	}
	if(SerialError)
		switch(SerialError)
		{
			/* Istec-Error */
			case	-1:
				{
				char	Error[256];
					sprintf(Error, "Fehler!\nEs ist ein Fehler bei der Datenübertragung zur Anlage\naufgetreten.\nFehlernummer der Anlage: %ld\n\nDas Programm wird aus diesem Grund beendet", IstecError );
					Requester(NULL, PRGNAME": Fehler!", Error, "Ok", NULL, NULL);
				}
				break;
			case	SERIAL_TIMEOUT_ERROR:
					Requester(NULL, PRGNAME": Fehler!", "Fehler!\nDie Istec-Anlage hat eine längere Zeit nicht mehr reagiert.\nDas Programm wird deswegen abgebrochen!!!\n\nPrüfen Sie nach, ob das richtige Device eingestellt ist,\nund alles mit den Verbindungskabeln stimmt!", "Ok", NULL, NULL);
				break;
			default:
				{
				char	Error[256];
					sprintf(Error, "Fehler!\nEs ist ein Fehler bei der Datenübertragung zur Anlage\naufgetreten.\nFehlernummer des Device: %ld\n\nDas Programm wird aus diesem Grund beendet", SerialError);
					Requester(NULL, PRGNAME": Fehler!", Error, "Ok", NULL, NULL);
				}
				break;
		}

	if(diskobj) FreeDiskObject(diskobj);
	while(!IsListEmpty(&IC_AliasList))
		FreeVec(RemTail(&IC_AliasList));
	ExitMain(EXITMAINEND);
} 

