#include "SC:Source/Istec_Support/Istec_IO"

/* ICReadBaseConfig
 * Liest die Anlagenkonfiguration ein
 * config    => Zeiger auf struct IC_BaseConfig, dort wird die Config reingechrieben
 * load      => TRUE=Aus Anlage lesen, sonst nur GUI berichtigen
 * UpdateGUI => TRUE=GUI an die Werte anpassen, FALSE=GUI nicht veraendern
 * return    => TRUE=Kein Fehler aufgetreten
 */
BOOL	ICReadBaseConfig(struct IC_BaseConfig *config, BOOL load, BOOL UpdateGUI);

/* ICReadDevices
 * Liest die Endgeraete aus der Anlage aus
 * config    => Adresse von &IC_DevConfig[0-7]
 * UpdateGUI => TRUE=GUI wird angepasst, FALSE=GUI wird nicht veraendert
 * return    => TRUE=Alles iO, FALSE=Es ist ein Fehler aufgetreten
 */
BOOL	ICReadDevices(struct IC_DevConfig *config, BOOL UpdateGUI);

/* ICUpdateDevGUI
 * config     => Zeiger auf die entsprechende IC_DevConfig
 * baseconfig => Zeiger auf die IC_BaseConfig
 * DevNumber  => Welches Gerät angezeigt wird
 * Charge     => Einheiten
 * ChargeType => In welcher Einheit (0=Einheiten, x=Pfennig/Einheit)
 */
void ICUpdateDevConfig(struct IC_BaseConfig *baseconfig, struct IC_DevConfig *config, int DevNumber, int Charge, int ChargeType);

/* ICWriteDevices
 * Schreibt die Endgeraete in die Anlage rein
 * config    => Adresse von &IC_DevConfig[x]
 * UpdateGUI => TRUE=GUI wird angepasst, FALSE=GUI wird nicht veraendert
 * return    => TRUE=Alles iO, FALSE=Es ist ein Fehler aufgetreten
 */
BOOL	ICWriteDevices(struct IC_DevConfig *config, BOOL UpdateGUI);

/* ICWriteBaseConfig
 * Schreibt die BasisConfig in die Anlage
 * config    => Adresse von &IC_BaseConfig
 * UpdateGUI => TRUE=GUI wird angepasst, FALSE=GUI wird nicht veraendert
 * return    => TRUE=Alles iO, FALSE=Es ist ein Fehler aufgetreten
 */
BOOL	ICWriteBaseConfig(struct IC_BaseConfig *config, BOOL UpdateGUI);

/* ICSetRC_Gadgets
 * Setzt mit der angegebenen Konfiguration die enstprechenden Gadgets auf
 * die richtigen Werte
 * IC_RufConfig => Die Konfiguration, mit der die Gadgets gesetzt werden sollen
 */
void ICSetRC_Gadgets(struct IC_RufConfig *IC_RufConfig);

/* ICWriteRufConfig
 * Schreibt die Endgeraete in die Anlage rein
 * config    => Adresse von &IC_DevConfig[x]
 * UpdateGUI => TRUE=GUI wird angepasst, FALSE=GUI wird nicht veraendert
 * return    => TRUE=Alles iO, FALSE=Es ist ein Fehler aufgetreten
 */
BOOL	ICWriteRufConfig(struct IC_RufConfig *config, BOOL UpdateGUI);

/* ICSetRC_LV
 * Fuellt mit Hilfe der angegebenen IC_RufConfig den entsprechenden Eintrag
 * in der Liste fuer das ListViewGadget
 * IC_ShortList => Liste mit den Kurzwahlnummern
 * IC_RufConfig => Eintrag, der angepasst werden soll
 */
void ICSetRC_LV(struct List *IC_ShortList, struct IC_RufConfig *IC_RufConfig);

/* ICGetRufConfig
 * holt eine Kurzwahlnummer aus der Istec und schreibt Sie in die
 * Struktur: IC_RufConfig
 * Als Uebergabeparameter wird ein Zeiger auf den zu fuellenden Datensatz erwartet
 * IC_RufConfig => Datensatz der gefuellt werden soll
 * Number       => Nummer des Datensatzes (1 .. 60)
 * UpdateGUI    => TRUE=GUI anpassen
 * Rueckgabe: Ausgefuellter Datensatz, bzw. NULL bei Fehler
 */
struct	IC_RufConfig	*ICGetRufConfig(struct IC_RufConfig *IC_RufConfig, int Number, BOOL UpdateGUI);

/* ICReadDayNight
 * Liest den aktuellen Tag-/Nachtstatus aus der Anlage aus
 * UpdateGUI => TRUE=GUI anpassen
 * return    => TRUE=Kein Fehler aufgetreten
 */
BOOL	ICReadDayNight(BOOL UpdateGUI);

/* ICReadAlarm
 * Liest den aktuellen Alarmstatus aus der Anlage aus
 * UpdateGUI => TRUE=GUI anpassen
 * return    => 0=OFF, 1-8 Kanal
 */
BOOL	ICReadAlarm(BOOL UpdateGUI);

/* ICWriteAlarm
 * Aendert den Alarmstatus der Anlage
 * Alarm     => 0=Off, 1-8 = Kanal
 * UpdateGUI => TRUE=GUI anpassen
 * return    => TRUE=Kein Fehler aufgetreten
 */
BOOL	ICWriteAlarm(int Alarm, BOOL UpdateGUI);















/* ICReadBaseConfig
 * Liest die Anlagenkonfiguration ein
 * config    => Zeiger auf struct IC_BaseConfig, dort wird die Config reingechrieben
 * load      => TRUE=Aus Anlage lesen, sonst nur GUI berichtigen
 * UpdateGUI => TRUE=GUI an die Werte anpassen, FALSE=GUI nicht veraendern
 * return    => TRUE=Kein Fehler aufgetreten
 */
BOOL	ICReadBaseConfig(struct IC_BaseConfig *config, BOOL load, BOOL UpdateGUI)
{
UBYTE	CMD[] = {0x0a};

	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Lese Grundkonfiguration...", TAG_DONE);
	if(load) ICWrite(CMD, sizeof(CMD));
	if(!SerialError)
	{
		if(load) ICRead((UBYTE *)config, sizeof(struct IC_BaseConfig));
		if(((!SerialError) && (UpdateGUI)) || (!load))
		{
		static	STRPTR	Connection[] = {"Mehrgeräte", "Anlagen"};
		static	STRPTR	Protocol[] = {"1TR6 (National)", "E-DSS1 (Euro)"};
		int	n;

			sprintf(gad_Version, "%ld.%ld", config->VersionHigh, config->VersionLow);
			LT_SetAttributes(Handle, GAD_BaseConfig_Version,	GTTX_Text, gad_Version, TAG_DONE);
			LT_SetAttributes(Handle, GAD_BaseConfig_Connection,GTTX_Text, (config->Connection < 2) ? Connection[config->Connection] : (UBYTE *)"Unbekannt" , TAG_DONE);
			LT_SetAttributes(Handle, GAD_BaseConfig_Protocol,	GTTX_Text, (config->Protocol < 2) ? Protocol[config->Protocol] : (UBYTE *)"Unbekannt" , TAG_DONE);
			sprintf(gad_DevCount, "%ld", config->DevCount);
			LT_SetAttributes(Handle, GAD_BaseConfig_DevCount,	GTTX_Text, gad_DevCount, TAG_DONE);
			sprintf(gad_IntS0, "%ld", config->IntS0);
			LT_SetAttributes(Handle, GAD_BaseConfig_IntS0,		GTTX_Text, gad_IntS0, TAG_DONE);
			sprintf(gad_ExtS0, "%ld", config->ExtS0);
			LT_SetAttributes(Handle, GAD_BaseConfig_ExtS0,		GTTX_Text, gad_ExtS0, TAG_DONE);

			for(n = 0; n < bcMSNCount; n++)
			{
				BCD2String(gad_MSN[n], config->MSN[n], 10, 1);
				LT_SetAttributes(Handle, GAD_BaseConfig_MSN0 + n,			GTST_String,	gad_MSN[n], TAG_DONE);
				LT_SetAttributes(Handle, GAD_BaseConfig_MSN0_Call + n,	GTCY_Active,	(config->Signaling[n] < 3) ? (config->Signaling[n]) : ((config->Signaling[n] == 4) ? 3 : 4) , TAG_DONE);
			}

			/* TFE */
			IC_Alarm = ICReadAlarm(TRUE);
			if(IC_Alarm)
			{
				LT_SetAttributes(Handle, GAD_BaseConfig_TFE_MainPage, LATB_Active, 2, TAG_DONE);
				LT_SetAttributes(Handle, GAD_BaseConfig_TFE_Select, LAGR_ActivePage, 2, TAG_DONE);
				LT_SetAttributes(Handle, GAD_BaseConfig_TFE_A, LAPU_Active, IC_Alarm - 1, TAG_DONE);
			}
			else
			if(config->TFEAssignment)
			{
				LT_SetAttributes(Handle, GAD_BaseConfig_TFE_MainPage, LATB_Active, 0, TAG_DONE);
				LT_SetAttributes(Handle, GAD_BaseConfig_TFE_Select, LAGR_ActivePage, 0, TAG_DONE);
				LT_SetAttributes(Handle, GAD_BaseConfig_TFE_E, LAPU_Active, config->TFEAssignment - 21, TAG_DONE);
			}
			else
			if(config->TFELoc[0] || config->TFELoc[1] || config->TFELoc[2] || config->TFELoc[3])
			{
				LT_SetAttributes(Handle, GAD_BaseConfig_TFE_MainPage, LAPU_Active, 1, TAG_DONE);
				LT_SetAttributes(Handle, GAD_BaseConfig_TFE_Select, LAGR_ActivePage, 1, TAG_DONE);
				LT_SetAttributes(Handle, GAD_BaseConfig_TFE_T, LAPU_Active, 0, TAG_DONE);
				for(n = 0 ; n < 8 ; n++)
					LT_SetAttributes(Handle, GAD_BaseConfig_TFE_T_21 + n, GTCB_Checked, config->TFELoc[0] & (1 << n), TAG_DONE);
			}
			
			if(config->Music)
				LT_SetAttributes(Handle, GAD_BaseConfig_MusicOnHold, LAPU_Active, 1, TAG_DONE), config->MusicPort = 0;
			else
				LT_SetAttributes(Handle, GAD_BaseConfig_MusicOnHold, LAPU_Active, (config->MusicPort > 8) ? 0 : (config->MusicPort + 1), TAG_DONE);
			for(n = 0 ; n < (sizeof(LandesKennung) / sizeof(int)) ; n++)
				if(LandesKennung[n] == ( (config->CountryCode[0] << 8) + config->CountryCode[1] ))
					LT_SetAttributes(Handle, GAD_BaseConfig_Land_Popup, LAPU_Active, n, TAG_DONE);
			LT_SetAttributes(Handle, GAD_BaseConfig_Land_Nr, GTIN_Number, ( (config->CountryCode[0] << 8) + config->CountryCode[1] ), TAG_DONE);
		}
	}
	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
	if(!SerialError) return(TRUE);
	return(FALSE);
}

/* ICReadDevices
 * Liest die Endgeraete aus der Anlage aus
 * config    => Adresse von &IC_DevConfig[0-7]
 * UpdateGUI => TRUE=GUI wird angepasst, FALSE=GUI wird nicht veraendert
 * return    => TRUE=Alles iO, FALSE=Es ist ein Fehler aufgetreten
 */
BOOL	ICReadDevices(struct IC_DevConfig *config, BOOL UpdateGUI)
{
UBYTE	CMD[] = {0x08};
char	Buffer[100];

	sprintf(Buffer, "Lese Endgerätedaten...");
	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, Buffer, TAG_DONE);
	ICWrite(CMD, sizeof(CMD));
	if(!SerialError)
	{
	int	n;
		for(n = 0 ; n < 8 ; n++)
		{
			sprintf(Buffer, "Lese Endgerätedaten für Gerät %ld...", n + 21);
			if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, Buffer, TAG_DONE);
			ICRead((UBYTE *)config + n * sizeof(struct IC_DevConfig), sizeof(struct IC_DevConfig));
			if(SerialError) break;
		}
		if((!SerialError) && (UpdateGUI))
		{
		int	n = LT_GetAttributes(Handle, GAD_DevConfig_Device, TAG_DONE);
	
			ICUpdateDevConfig(&IC_BaseConfig, &IC_DevConfig[n], n, IC_Charge.Charge[n], IC_Charge.ChargeType[n]);
		}
	}
	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
	if(SerialError)
		return(FALSE);
	return(TRUE);
}

/* ICUpdateDevGUI
 * config     => Zeiger auf die entsprechende IC_DevConfig
 * baseconfig => Zeiger auf die IC_BaseConfig
 * DevNumber  => Welches Gerät angezeigt wird
 * Charge     => Einheiten
 * ChargeType => In welcher Einheit (0=Einheiten, x=Pfennig/Einheit)
 */
void ICUpdateDevConfig(struct IC_BaseConfig *baseconfig, struct IC_DevConfig *config, int DevNumber, int Charge, int ChargeType)
{
int	n, m;

	/* MSN 0-9 */
	for(n = 0 ; n < bcMSNCount ; n++)
	{
	STRPTR	msn;
		msn = (char *)LT_GetAttributes(Handle, GAD_BaseConfig_MSN0 + n, TAG_DONE);
		strcpy(gad_MSN[n], msn);
		for(m = 0 ; m < strlen(msn) ; m++)
			if(!isdigit(gad_MSN[n][m]))
				gad_MSN[n][0] = 0x00;
		LT_SetAttributes(Handle, GAD_DevConfig_MSN0 + n, GTTX_Text, gad_MSN[n], TAG_DONE);
	}
	for(n = 0 ; n < bcMSNCount ; n++)
	{
		LT_SetAttributes(Handle, GAD_DevConfig_MSN0_Call + n, GTCB_Checked, ((baseconfig->MSNGroups[n]) & (1<<DevNumber)), TAG_DONE);
	}

	/* Allgemeines */
	BCD2String(gad_PIN, (UBYTE *)config->PIN, 4, 1);
	LT_SetAttributes(Handle, GAD_DevConfig_PIN,				GTST_String, gad_PIN, TAG_DONE);
	LT_SetAttributes(Handle, GAD_DevConfig_DialCaps,		LAPU_Active, config->DialCaps, TAG_DONE);
	LT_SetAttributes(Handle, GAD_DevConfig_Service,			LAPU_Active, config->Service, TAG_DONE);
	LT_SetAttributes(Handle, GAD_DevConfig_ChargePulse,	GTCB_Checked, config->ChargePulse, TAG_DONE);
	LT_SetAttributes(Handle, GAD_DevConfig_TerminalMode,	GTCB_Checked, config->TerminalMode, TAG_DONE);
	LT_SetAttributes(Handle, GAD_DevConfig_ChargeType,		LAPU_Active, ChargeType ? 1 : 0, TAG_DONE);
	if(ChargeType)
		sprintf(gad_Charge, "%ld.%02ld", Charge * ChargeType / 100, (Charge * ChargeType) % 100);
	else
		sprintf(gad_Charge, "%ld", Charge);
	LT_SetAttributes(Handle, GAD_DevConfig_Charge,			GTTX_Text, gad_Charge, TAG_DONE);

	/* Rufumleitung */
	LT_SetAttributes(Handle, GAD_DevConfig_Reroute,			LAPU_Active, (config->Reroute <= 1) ? (config->Reroute) : (config->Reroute - 21 + 2), TAG_DONE);
	{
	char	Buffer[22];
		BCD2String(Buffer, (UBYTE *)config->ExtNum, 20, 1);
		if(Buffer[0] == '0')
			strcpy(Buffer, Buffer + 1);
		strcpy(gad_ExtNum, GetAliasName(Buffer));
	}
	LT_SetAttributes(Handle, GAD_DevConfig_ExtNum,			GTST_String, gad_ExtNum, GA_Disabled, (config->Reroute == 1) ? FALSE : TRUE, TAG_DONE);
	LT_SetAttributes(Handle, GAD_DevConfig_RerouteIfBusy,			LAPU_Active, config->RerouteIfBusy,		GA_Disabled, (config->Reroute == 0) ? FALSE : TRUE, TAG_DONE);
	LT_SetAttributes(Handle, GAD_DevConfig_RingsUntilReroute,	GTSL_Level, config->RingsUntilReroute,	GA_Disabled, (config->Reroute == 0) ? FALSE : TRUE, TAG_DONE);
	LT_SetAttributes(Handle, GAD_DevConfig_RerouteDelayed,		LAPU_Active, config->RerouteDelayed,	GA_Disabled, (config->Reroute == 0) ? FALSE : TRUE, TAG_DONE);

	/* Anklopfen */
	for(n = 0 ; n < 8 ; n++)
		LT_SetAttributes(Handle, GAD_DevConfig_IKnock0+n,	GTCB_Checked, (config->InternalKnock & (1<<n)) ? TRUE : FALSE, TAG_DONE);
	m = (config->ExternalKnock[1] << 8) + config->ExternalKnock[0];
	for(n = 0 ; n < 10 ; n++)
		LT_SetAttributes(Handle, GAD_DevConfig_EKnock0+n,	GTCB_Checked, (m & (1<<n)) ? TRUE : FALSE, TAG_DONE);
	LT_SetAttributes(Handle, GAD_DevConfig_TKnock,			GTCB_Checked, (m & (1<<10))? TRUE : FALSE, TAG_DONE);
}

/* ICWriteDevices
 * Schreibt die Endgeraete in die Anlage rein
 * config    => Adresse von &IC_DevConfig[x]
 * UpdateGUI => TRUE=GUI wird angepasst, FALSE=GUI wird nicht veraendert
 * return    => TRUE=Alles iO, FALSE=Es ist ein Fehler aufgetreten
 */
BOOL	ICWriteDevices(struct IC_DevConfig *config, BOOL UpdateGUI)
{
BOOL	ret;
char	Buffer[100];

	sprintf(Buffer, "Schreibe Endgerät %ld...", config->DevNum + 21);
	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, Buffer, TAG_DONE);
	if(ret = ICCheck(FALSE))
	{
	UBYTE	CMD = config->Command;
	UBYTE	Buffer[10];
		config->Command = 0x07;
		ICWrite((UBYTE *)config, sizeof(struct IC_DevConfig));
		config->Command = CMD;
		ICRead(Buffer, 8);
		if(!SerialError)
		{
			if((Buffer[0] != 0x18) ||
				(Buffer[1] != config->DevNum))
			{
				if(Buffer[0] == 0x13)
					IstecError = Buffer[0] << 8 + Buffer[1], SerialError = -1;
				else
				   IstecError = -1, SerialError = -1;
			}
		}
	}
	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
	if(!SerialError)
		return(ret);
	return(FALSE);
}

/* ICWriteBaseConfig
 * Schreibt die BasisConfig in die Anlage
 * config    => Adresse von &IC_BaseConfig
 * UpdateGUI => TRUE=GUI wird angepasst, FALSE=GUI wird nicht veraendert
 * return    => TRUE=Alles iO, FALSE=Es ist ein Fehler aufgetreten
 */
BOOL	ICWriteBaseConfig(struct IC_BaseConfig *config, BOOL UpdateGUI)
{
BOOL	ret;
int	alarm = 0;

	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Schreibe Grundkonfiguration...", TAG_DONE);
	if(ret = ICCheck(FALSE))
	{
	UBYTE	CMD = config->Command;
		config->Command = 0x09;

		{
		int	tfe = LT_GetAttributes(Handle, GAD_BaseConfig_TFE_MainPage, TAG_DONE);

			if(tfe == 0)			/* Emmerich - Anlage */
			{
				config->TFELoc[0] = 0;
				config->TFELoc[1] = 0;
				config->TFELoc[2] = 0;
				config->TFELoc[3] = 0;
			}
			else
			if(tfe == 1)			/* Telekom - Anlage */
			{
				if((config->TFELoc[0] == 0)	&&
					(config->TFELoc[1] == 0)	&&
					(config->TFELoc[2] == 0)	&&
					(config->TFELoc[3] == 0))
					config->TFEAssignment = 21;
				else
					config->TFEAssignment = 0;
			}
			else
			if(tfe == 2)			/* Alarm - Funktion */
			{
				config->TFEAssignment = 0;
				config->TFELoc[0] = 0;
				config->TFELoc[1] = 0;
				config->TFELoc[2] = 0;
				config->TFELoc[3] = 0;
				alarm = IC_Alarm;
			}
		}
		ICWrite((UBYTE *)config, sizeof(struct IC_BaseConfig));
		config->Command = CMD;
	}
	ICWriteDayNight(IC_DayNight, UpdateGUI);
	ICWriteAlarm(alarm, UpdateGUI);

	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
	if(!SerialError)
		return(ret);
	return(FALSE);
}

/* ICSetRC_Gadgets
 * Setzt mit der angegebenen Konfiguration die enstprechenden Gadgets auf
 * die richtigen Werte
 * IC_RufConfig => Die Konfiguration, mit der die Gadgets gesetzt werden sollen
 */
void ICSetRC_Gadgets(struct IC_RufConfig *IC_RufConfig)
{
static	STRPTR	CLabels1[] = {"Inaktiv", "Babyruf", "Kurzwahl", NULL};
static	STRPTR	CLabels2[] = {"Inaktiv", "Babyruf", "Sperre", NULL};
static	STRPTR	TypLabels1[] = {"Inaktiv", "Babyruf", "Kurzwahl", "Beliebig", NULL};
static	STRPTR	TypLabels2[] = {"Inaktiv", "Babyruf", "Sperre", "Beliebig", NULL};
char	Telefon[30];
int	n;

	/* Kurzwahlnummer */
	BCD2String(Telefon, &(IC_RufConfig->ReadIn[5]), IC_RufConfig->ReadIn[4], 0);
	if(Telefon[0] == '0')
		strcpy(Telefon, &Telefon[1]);
	LT_SetAttributes(Handle, GAD_RufConfig_Number, GTST_String, GetAliasName(Telefon), TAG_DONE);
	strcpy(gad_RufNummer, GetAliasName(Telefon));
	/* Kurzwahl / Sperre */
	if(IC_RufConfig->ReadIn[(IC_RufConfig->ReadIn[4] + 1)/2 + 5 + 3] == 0)
	{
		LT_SetAttributes(Handle, GAD_RufConfig_Type, LAPU_Labels, TypLabels1, LAPU_Active, 3, TAG_DONE);
		LT_SetAttributes(Handle, GAD_RufConfig_K_S, LAPU_Active, 0, TAG_DONE);
		for(n = 0 ; n < 8 ; n++)
			LT_SetAttributes(Handle, GAD_RufConfig_Dev21 + n, LAPU_Labels, CLabels1, TAG_DONE);
	}
	else
	{
		LT_SetAttributes(Handle, GAD_RufConfig_Type, LAPU_Labels, TypLabels2, LAPU_Active, 3, TAG_DONE);
		LT_SetAttributes(Handle, GAD_RufConfig_K_S, LAPU_Active, 1, TAG_DONE);
		for(n = 0 ; n < 8 ; n++)
			LT_SetAttributes(Handle, GAD_RufConfig_Dev21 + n, LAPU_Labels, CLabels2, TAG_DONE);
	}

	/* Geräte */
	for(n = 0 ; n < 8 ; n++)
	{
		if(IC_RufConfig->ReadIn[(IC_RufConfig->ReadIn[4] + 1)/2 + 5 + 0] & (1<<n))
			LT_SetAttributes(Handle, GAD_RufConfig_Dev21 + n, LAPU_Active, 1, TAG_DONE);
		else
			if(IC_RufConfig->ReadIn[(IC_RufConfig->ReadIn[4] + 1)/2 + 5 + 1] & (1<<n))
				LT_SetAttributes(Handle, GAD_RufConfig_Dev21 + n, LAPU_Active, 2, TAG_DONE);
			else
				LT_SetAttributes(Handle, GAD_RufConfig_Dev21 + n, LAPU_Active, 0, TAG_DONE);
	}
	/* RufTon */
	LT_SetAttributes(Handle, GAD_RufConfig_Call, LAPU_Active, ((IC_RufConfig->ReadIn[(IC_RufConfig->ReadIn[4] + 1)/2 + 5 + 2]) < 3) ? ((IC_RufConfig->ReadIn[(IC_RufConfig->ReadIn[4] + 1)/2 + 5 + 2])) : (((IC_RufConfig->ReadIn[(IC_RufConfig->ReadIn[4] + 1)/2 + 5 + 2]) == 3) ? 4 : 3), TAG_DONE);
}

/* ICWriteRufConfig
 * Schreibt die Endgeraete in die Anlage rein
 * config    => Adresse von &IC_DevConfig[x]
 * UpdateGUI => TRUE=GUI wird angepasst, FALSE=GUI wird nicht veraendert
 * return    => TRUE=Alles iO, FALSE=Es ist ein Fehler aufgetreten
 */
BOOL	ICWriteRufConfig(struct IC_RufConfig *config, BOOL UpdateGUI)
{
BOOL	ret;
char	Buffer[100];

	if(UpdateGUI)
		sprintf(Buffer, "Schreibe Kurzwahlnummer %ld...", 300 + config->ReadIn[3]),
		LT_SetAttributes(Handle, GAD_Status, GTTX_Text, Buffer, TAG_DONE);

	if(ret = ICCheck(FALSE))
	{
	UBYTE	CMD1 = config->ReadIn[1];
	UBYTE	CMD2 = config->ReadIn[2];
		config->ReadIn[1] = CTI_CONF;
		config->ReadIn[2] = CTI_STORE_NUMBER;
		ICWrite(config->ReadIn, (config->ReadIn[4] + 1) / 2 + 4 + 6);
		config->ReadIn[1] = CMD1;
		config->ReadIn[2] = CMD2;
/*
		ICRead(Buffer, 8);
		if(!SerialError)
		{
			if((Buffer[0] != 0x18) ||
				(Buffer[1] != config->DevNum))
			{
				if(Buffer[0] == 0x13)
					IstecError = Buffer[0] << 8 + Buffer[1], SerialError = -1;
				else
				   IstecError = -1, SerialError = -1;
			}
		}
*/
	}
	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
	if(!SerialError)
		return(ret);
	return(FALSE);
}

/* ICSetRC_LV
 * Fuellt mit Hilfe der angegebenen IC_RufConfig den entsprechenden Eintrag
 * in der Liste fuer das ListViewGadget
 * IC_ShortList => Liste mit den Kurzwahlnummern
 * IC_RufConfig => Eintrag, der angepasst werden soll
 */
void ICSetRC_LV(struct List *IC_ShortList, struct IC_RufConfig *IC_RufConfig)
{
char	Telefon[30];
char	Type = 'K';
char	Geraete[10];
char	Ruf;
int	n;
int	active = LT_GetAttributes(Handle, GAD_RufConfig_LV, TAG_DONE);

	if((active < 0) ||
		(active > 59))
		active = 0;
	LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, ~NULL, TAG_DONE);

	/* Kurzwahlnummer */
	strcpy(Telefon, "  -- Keine Nummer --");
	if(IC_RufConfig->ReadIn[4])
		BCD2String(Telefon, &(IC_RufConfig->ReadIn[5]), IC_RufConfig->ReadIn[4], 0);
	if(Telefon[0] == '0')
		strcpy(Telefon, &Telefon[1]);
	strcpy(Telefon, GetAliasName(Telefon));
	/* Kurzwahl */
	if(IC_RufConfig->ReadIn[(IC_RufConfig->ReadIn[4] + 1)/2 + 5 + 3] == 0)
		Type = 'K';
	else
		Type = 'S';
	/* Geräte */
	Geraete[8] = 0x00;
	for(n = 0 ; n < 8 ; n++)
	{
		if(IC_RufConfig->ReadIn[(IC_RufConfig->ReadIn[4] + 1)/2 + 5 + 0] & (1<<n))
			Geraete[n] = 'B';
		else
			if(IC_RufConfig->ReadIn[(IC_RufConfig->ReadIn[4] + 1)/2 + 5 + 1] & (1<<n))
				Geraete[n] = Type;
			else
				Geraete[n] = '-';
	}
	/* RufTon */
	switch(IC_RufConfig->ReadIn[(IC_RufConfig->ReadIn[4] + 1)/2 + 5 + 2])
	{
		case	0:
			Ruf = 'N';
			break;
		case	1:
			Ruf = '1';
			break;
		case	2:
			Ruf = '2';
			break;
		case	4:
			Ruf = '3';
			break;
		default:
			Ruf = 'A';
			break;
	}
	sprintf(IC_RufConfig->Number, "3%02ld %-20s %s %c",
					IC_RufConfig->ReadIn[3], Telefon, Geraete, Ruf);

	LT_SetAttributes(Handle, GAD_RufConfig_LV, GTLV_Labels, IC_ShortList, GTLV_Selected, active, TAG_DONE);
}

/* ICGetRufConfig
 * holt eine Kurzwahlnummer aus der Istec und schreibt Sie in die
 * Struktur: IC_RufConfig
 * Als Uebergabeparameter wird ein Zeiger auf den zu fuellenden Datensatz erwartet
 * IC_RufConfig => Datensatz der gefuellt werden soll
 * Number       => Nummer des Datensatzes (1 .. 60)
 * UpdateGUI    => TRUE=GUI anpassen
 * Rueckgabe: Ausgefuellter Datensatz, bzw. NULL bei Fehler
 */
struct	IC_RufConfig	*ICGetRufConfig(struct IC_RufConfig *IC_RufConfig, int Number, BOOL UpdateGUI)
{
UBYTE	CMD[] = {CTI_START, CTI_QUERY, CTI_LOAD_NUMBER, 0x00, CTI_STOP};
UBYTE	Buffer[256];
int	n;

	if(UpdateGUI)
		sprintf(Buffer, "Lese Kurzwahlnummer %ld aus...", 300 + Number),
		LT_SetAttributes(Handle, GAD_Status, GTTX_Text, Buffer, TAG_DONE);

	CMD[3] = Number;
	for(n = 0 ; n < 5 ; n++)
	{
		ICWrite(CMD, sizeof(CMD));
		ICRead(IC_RufConfig->ReadIn, 100);

		if(!SerialError &&
			(IC_RufConfig->ReadIn[1] == CTI_ACK) &&
			(IC_RufConfig->ReadIn[2] == CTI_LOAD_NUMBER) &&
			(IC_RufConfig->ReadIn[3] == Number))
			break;
	}
	if(n < 5)
	{
		IC_RufConfig->Node.ln_Name = IC_RufConfig->Number;

		if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
		return(IC_RufConfig);
	}
#ifdef BETA
	printf("ICGetRufConfig: Failed\n");
	printf("%02lx %02lx %02lx %02lx\n", IC_RufConfig->ReadIn[0], IC_RufConfig->ReadIn[1], IC_RufConfig->ReadIn[2], IC_RufConfig->ReadIn[3]);
#endif
	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
	return(NULL);
}

/* ICReadDayNight
 * Liest den aktuellen Tag-/Nachtstatus aus der Anlage aus
 * UpdateGUI => TRUE=GUI anpassen
 * return    => TRUE=Kein Fehler aufgetreten
 */
BOOL	ICReadDayNight(BOOL UpdateGUI)
{
UBYTE	CMD[] = {CTI_START, CTI_QUERY, CTI_DAY_NIGHT, CTI_STOP};

BOOL	ret = 0;
UBYTE	Buffer[10];

	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Lese Tag-/Nachtwert ein...", TAG_DONE);
	if(ret = ICCheck(FALSE))
		ICWrite(CMD, sizeof(CMD));
	if(!SerialError)
		ICRead(Buffer, sizeof(Buffer));
	if(!SerialError)
	{
		if((Buffer[0] == CTI_START)		&&
			(Buffer[1] == CTI_ACK)			&&
			(Buffer[2] == CTI_DAY_NIGHT)	&&
			(Buffer[4] == CTI_STOP))
		{
			ret = Buffer[3];
			if(UpdateGUI) LT_SetAttributes(Handle, GAD_BaseConfig_TagNacht, LAPU_Active, ret ? 1 : 0, TAG_DONE);
		}
		else
		{
			SerialError = -1;
			IstecError = Buffer[1] << 8 + Buffer[2];
		}
	}
	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
	return(ret);
}

/* ICReadAlarm
 * Liest den aktuellen Alarmstatus aus der Anlage aus
 * UpdateGUI => TRUE=GUI anpassen
 * return    => 0=OFF, 1-8 Kanal
 */
BOOL	ICReadAlarm(BOOL UpdateGUI)
{
UBYTE	CMD[] = {CTI_START, CTI_QUERY, CTI_ALARM, CTI_STOP};

BOOL	ret = 0;
UBYTE	Buffer[10];

	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Lese Alarmstatus ein...", TAG_DONE);
	if(ret = ICCheck(FALSE))
		ICWrite(CMD, sizeof(CMD));
	if(!SerialError)
		ICRead(Buffer, sizeof(Buffer));
	if(!SerialError)
	{
		if((Buffer[0] == CTI_START)		&&
			(Buffer[1] == CTI_ACK)			&&
			(Buffer[2] == CTI_ALARM)		&&
			(Buffer[4] == CTI_STOP))
		{
			ret = Buffer[3];
			if(UpdateGUI) LT_SetAttributes(Handle, GAD_BaseConfig_TFE_A, LAPU_Active, (ret == 0) ? 0 : (ret - 1), TAG_DONE);
		}
		else
		{
			SerialError = -1;
			IstecError = Buffer[1] << 8 + Buffer[2];
		}
	}
	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
	return(ret);
}

/* ICWriteAlarm
 * Aendert den Alarmstatus der Anlage
 * Alarm     => 0=Off, 1-8 = Kanal
 * UpdateGUI => TRUE=GUI anpassen
 * return    => TRUE=Kein Fehler aufgetreten
 */
BOOL	ICWriteAlarm(int Alarm, BOOL UpdateGUI)
{
UBYTE	CMD[] = {CTI_START, CTI_CONF, CTI_ALARM, 0, CTI_STOP};

UBYTE	Buffer[10];

	CMD[3] = Alarm;
	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, "Schreibe Alarmkanal in die Anlage...", TAG_DONE);
	if(ICCheck(FALSE))
		ICWrite(CMD, sizeof(CMD));
	if(!SerialError)
		ICRead(Buffer, sizeof(Buffer));
	if(!SerialError)
	{
		if(  ((Buffer[0] == CTI_START)		&&
				(Buffer[1] == CTI_ACK)			&&
				(Buffer[2] == CTI_ALARM)		&&
				(Buffer[3] == CTI_STOP)))
		{
			IC_Alarm = Alarm;
		}
		else
		{
			SerialError = -1;
			IstecError = Buffer[2] << 8 + Buffer[3];
		}
	}
	if(UpdateGUI) LT_SetAttributes(Handle, GAD_Status, GTTX_Text, gad_Status, TAG_DONE);
	return((BOOL)!SerialError);
}


