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

//#define	BETA	1
//#define	DEMO	1

#define	PRGNAME		"IstecTool"
#define	PRGVERSION	"1.1beta"

#include	<time.h>
#include "support.h"
#include <time.h>
#include "ENV:ADate.h"

static	char	Version[] = "$VER: "PRGNAME" "PRGVERSION" ("__AMIGADATE__")";

/**************************************************************************/
/* Wichtige Include-Dateien */
#include "support_c"
#include "SC:Source/Istec_Support/Istec_IO"

/**************************************************************************/
/* Globale Vaiablen */

struct	Keyfile			*Key;

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

extern	struct	CIA	ciab;


void main(LONG ArgC, char *ArgV[])
{
int	n;
STRPTR	RDTemp = "O=OutPut/K,Date/S,DateFormat/K,Charge/S,ChargeFormat/K,ChargeCost/K,ChargeReset/S,Day/S,Night/S,SerDev/K,SerUnit/K/N,CEPatch/S";
struct{
	STRPTR	Output;
	ULONG		Date;
	STRPTR	DateFormat;
	ULONG		Charge;
	STRPTR	ChargeFormat;
	STRPTR	ChargeCost;
	ULONG		ChargeReset;
	ULONG		Day;
	ULONG		Night;
	STRPTR	SerDev;
	ULONG		SerUnit;
	ULONG		CEPatch;

} RDArry = {NULL, FALSE, "%3D %D-%2M-%Y  %h:%m:%s\n", FALSE, 
 "Einheiten:\nGerät21:  %a  Gerät22:  %b  Gerät23:  %c  Gerät24:  %d  Gerät25:  %e  Gerät26:  %f  Gerät27:  %g  Gerät28:  %h\n"
 "Kosten in DM:\nGerät21: %A  Gerät22: %B  Gerät23: %C  Gerät24: %D  Gerät25: %E  Gerät26: %F  Gerät27: %G  Gerät28: %H\n",
 "12", FALSE, FALSE, FALSE, "serial.device", NULL, FALSE};
/* %A = Geraet21 in DM, %c = Geraet23 in Einheiten */
struct	RDArgs	*RDArgs = NULL;

BOOL					 WriteIstec	= FALSE;

	if(!InitMain()) exit(0);

	if(!ArgC)
	{
		Requester(NULL, PRGNAME": Achtung!", "Achtung!\nDas ist ein CLI-Programm!!!", "Ok", NULL, NULL);
		ExitMain();
		exit(20);
	}

	Key = GetKeyfile();
	if((Key == (struct Keyfile *)-1) ||
		(Key == NULL))
	{
		Requester(NULL, PRGNAME": Achtung!", "Achtung!\n\nDieses Programm ist nur für registrierte Benutzer\nvon UFT-Istec verfügbar!!!\n\nBitte lassen Sie sich für UFT-Istec registrieren,\nwenn Sie dieses Programm nutzen wollen!", "Ok", NULL, NULL);
		ExitMain();
		exit(20);
	}

	if(RDArgs = ReadArgs(RDTemp, (LONG *)&RDArry, NULL))
	{
	BPTR	fh = Output();
	BOOL	stdfh = TRUE;

		/* Ausgabedatei ggf. öffnen, oder ansonten die Standardausgabe benutzen */
		if(RDArry.Output)
		{
			if(fh = Open(RDArry.Output, MODE_READWRITE))
			{
				Seek(fh, 0, OFFSET_END);
				stdfh = FALSE;
			}
		}

		/* Open the serial device */
		if(SerialMP = CreateMsgPort())
			if(SerialIO = (struct IOExtSer *)CreateExtIO(SerialMP, sizeof(struct IOExtSer)))
			{
				if(!OpenDevice(RDArry.SerDev, RDArry.SerUnit, (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)
		{
			if(!stdfh)
				Close(fh);
			DTrequest(PRGNAME, "Konnte das serial.device nicht öffnen", NULL, NULL);
			if(SerialIO) DeleteExtIO((struct IORequest *)SerialIO);
			if(SerialMP) DeleteMsgPort(SerialMP);
			ExitMain();
			exit(5);
		}
		/* Oeffnen des Device ist erfolgreich, CEPatch aktivieren ? */
		if(RDArry.CEPatch)
		{
			if(!strcmp(RDArry.SerDev, 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))
				{
				char	Info[] = {"Es ist ein Problem aufgetreten!\nCEPatch wird von dem angegebenen Device nicht unterstützt!\n\n"};
					printf(Info);
				}
			}
		}

		/* Datum ausgeben */
		if(RDArry.Date)
		{
		struct	tm	*zeit;
		time_t	sec;
			time(&sec);
			zeit = localtime(&sec);

			for(n = 0 ; n < strlen(RDArry.DateFormat) ; n++)
			{
				switch(RDArry.DateFormat[n])
				{
					case	'%':
						{
						ULONG	Type = 10;

							if(strlen(RDArry.DateFormat) > (n+1))
								if(isdigit(RDArry.DateFormat[n+1]))
									Type = (RDArry.DateFormat[++n]) - '0';

							/* Min. noch ein weiteres Zeichen vorhanden ? */
							if(strlen(RDArry.DateFormat) > (n+1))
							{
							UBYTE		ch;
							char	Buffer[10];

								n++;
								ch = RDArry.DateFormat[n];

								if(ch == 'Y')
								{
									if(Type == 2)
										sprintf(Buffer, "%04ld", 1900 + zeit->tm_year);
									else
										sprintf(Buffer, "%02ld", zeit->tm_year);
									Write(fh, Buffer, strlen(Buffer));
								}
								else
								if(ch == 'M')
								{
								STRPTR	Mon[] = {"Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"};
								STRPTR	Monat[] = {"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"};
									if(Type == 2)
										strcpy(Buffer, Mon[zeit->tm_mon]);
									else
									if(Type == 3)
										strcpy(Buffer, Monat[zeit->tm_mon]);
									else
										sprintf(Buffer, "%02ld", zeit->tm_mon + 1);
									Write(fh, Buffer, strlen(Buffer));
								}
								else
								if(ch == 'D')
								{
								STRPTR	T[] = {"So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"};
								STRPTR	Ta[] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
									if(Type == 2)
										strcpy(Buffer, T[zeit->tm_wday]);
									else
									if(Type == 3)
										strcpy(Buffer, Ta[zeit->tm_wday]);
									else
										sprintf(Buffer, "%02ld", zeit->tm_mday);
									Write(fh, Buffer, strlen(Buffer));
								}
								else
								if(ch == 'h')
								{
									sprintf(Buffer, "%02ld", zeit->tm_hour);
									Write(fh, Buffer, strlen(Buffer));
								}
								else
								if(ch == 'm')
								{
									sprintf(Buffer, "%02ld", zeit->tm_min);
									Write(fh, Buffer, strlen(Buffer));
								}
								else
								if(ch == 's')
								{
									sprintf(Buffer, "%02ld", zeit->tm_sec);
									Write(fh, Buffer, strlen(Buffer));
								}
								else
								if((ch == '%') && (Type == 10))
								{
									Write(fh, "%%", strlen("%%"));
								}
								else
								{
									fprintf(stderr, "FEHLERMELDUNG: Du hast ein undefiniertes Formatelement benutzt \"%%%c\"!\n", ch);
									fprintf(stderr, " Es werden nur folgende Formatelemente unterstützt:\n");
									fprintf(stderr, "  \"%%h\", \"%%m\" und \"%%s\" für die Ausgabe der Stunden, Minuten und Sekunden\n");
									fprintf(stderr, "  \"%%Y\" für die Ausgabe des Jahres, \"%%2Y\" für vierstellige Jahreszahlen [Default: zweistellig]\n");
									fprintf(stderr, "  \"%%M\" für die Ausgabe des Monats, \"%%2M\" für Monatskurzbezeichnungen (z.B: Jan), \"%%3M\" für lange Monatsnamen (z.B: Januar) [Default: Monatszahl zweistellig]\n");
									fprintf(stderr, "  \"%%D\" für die Ausgabe des Tages, \"%%2D\" für Tageskurzbezeichnungen (z.B: So), \"%%3D\" für lange Tagesnamen (z.B: Sonntag) [Default: Tageszahl zweistellig]\n");
									fprintf(stderr, "  \"%%%%\" = \"%%\"\n\n");
								}
							}
							else
							{
								fprintf(stderr, "FEHLERMELDUNG: Du hast ein Formatelementeinleiter am Ende der Zeile benutzt!\n\n");
							}
						}
						break;
					case	'\\':
						{
							/* Min. noch ein weiteres Zeichen vorhanden ? */
							if(strlen(RDArry.DateFormat) > (n+1))
							{
							UBYTE	ch;
								n++;
								ch = RDArry.DateFormat[n];
								switch(ch)
								{
									case	'n':
										Write(fh, "\n", strlen("\n"));
										break;
									case	't':
										Write(fh, "\t", strlen("\t"));
										break;
									case	'\\':
										Write(fh, "\\", strlen("\\"));
										break;
									default:
										fprintf(stderr, "FEHLERMELDUNG: Du hast ein undefiniertes Steuerzeichen benutzt \"\\%c\"!\n", ch);
										fprintf(stderr, " Es werden nur folgende Steuerzeichen unterstützt:\n  \"\\n\" = Zeilenvorschub,\n  \"\\t\" = Tabulator\n  \"\\%c\" = \'%c\'!\n\n", '\\', '\\');
										break;
								}
							}
							else
								fprintf(stderr, "FEHLERMELDUNG: Du hast ein Steuerzeicheneinleiter am Ende der Zeile benutzt!\n\n");
						}
						break;
					default:
						Write(fh, &(RDArry.DateFormat[n]), 1);
						break;
				}
			}
		
		
		}

		/* Gebühren ausgeben */
		if(RDArry.Charge)
		{
		struct	IC_Charge	Charge;

			if(ICCheck(FALSE))
			{
				if(ICReadCharge(&Charge, NULL, FALSE));
				{
				ULONG	ChargeCost = 12;

					if(RDArry.ChargeCost)
						ChargeCost = atol(RDArry.ChargeCost);
					if(!ChargeCost)
						ChargeCost = 12;

					for(n = 0 ; n < strlen(RDArry.ChargeFormat) ; n++)
					{
						switch(RDArry.ChargeFormat[n])
						{
							case	'%':
								{
									/* Min. noch ein weiteres Zeichen vorhanden ? */
									if(strlen(RDArry.ChargeFormat) > (n+1))
									{
									UBYTE	ch;
									ULONG	Cost;
										n++;
										ch = RDArry.ChargeFormat[n];
										if((ch >= 'A') && (ch <= 'H'))
										{
										char	Buffer[10];
											Cost = Charge.Charge[ch - 'A'];
											sprintf(Buffer, "%3ld.%02ld", (Cost * ChargeCost) / 100 , (Cost * ChargeCost) % 100);
											Write(fh, Buffer, strlen(Buffer));
										}
										else
										if((ch >= 'a') && (ch <= 'h'))
										{
										char	Buffer[10];
											Cost = Charge.Charge[ch - 'a'];
											sprintf(Buffer, "%5ld", Cost);
											Write(fh, Buffer, strlen(Buffer));
										}
										else
										if(ch == '%')
										{
											Write(fh, "%%", strlen("%%"));
										}
										else
										{
											fprintf(stderr, "FEHLERMELDUNG: Du hast ein undefiniertes Formatelement benutzt \"%%%c\"!\n", ch);
											fprintf(stderr, " Es werden nur folgende Formatelemente unterstützt:\n");
											fprintf(stderr, "  \"%%A\" - \"%%H\" für die Ausgabe der Gebühren der Endgeräte 21 bis 28\n");
											fprintf(stderr, "  \"%%a\" - \"%%h\" für die Ausgabe der Einheiten der Endgeräte 21 bis 28\n");
											fprintf(stderr, "  \"%%%%\" = \"%%\"\n\n");
										}
									}
									else
									{
										fprintf(stderr, "FEHLERMELDUNG: Du hast ein Formatelementeinleiter am Ende der Zeile benutzt!\n\n");
									}
								}
								break;
							case	'\\':
								{
									/* Min. noch ein weiteres Zeichen vorhanden ? */
									if(strlen(RDArry.ChargeFormat) > (n+1))
									{
									UBYTE	ch;
										n++;
										ch = RDArry.ChargeFormat[n];
										switch(ch)
										{
											case	'n':
												Write(fh, "\n", strlen("\n"));
												break;
											case	't':
												Write(fh, "\t", strlen("\t"));
												break;
											case	'\\':
												Write(fh, "\\", strlen("\\"));
												break;
											default:
												fprintf(stderr, "FEHLERMELDUNG: Du hast ein undefiniertes Steuerzeichen benutzt \"\\%c\"!\n", ch);
												fprintf(stderr, " Es werden nur folgende Steuerzeichen unterstützt:\n  \"\\n\" = Zeilenvorschub,\n  \"\\t\" = Tabulator\n  \"\\%c\" = \'%c\'!\n\n", '\\', '\\');
												break;
										}
									}
									else
										fprintf(stderr, "FEHLERMELDUNG: Du hast ein Steuerzeicheneinleiter am Ende der Zeile benutzt!\n\n");
								}
								break;
							default:
								Write(fh, &(RDArry.ChargeFormat[n]), 1);
								break;
						}
					}
				}
			}
		}
		if(SerialError) goto abbruch;

		/* Gebühren löschen */
		if(RDArry.ChargeReset)
		{
		UBYTE	Buffer[17];
			for(n = 0 ; n < 16 ; n++)
				Buffer[n+1] = 0x00;
			Buffer[0] = 0x05;
			ICWrite(Buffer, 17);
			ICRead(Buffer, 8);
			WriteIstec = TRUE;
		}
		if(SerialError) goto abbruch;

		/* Tagumschaltung */
		if(RDArry.Day)
		{
		char	Meldung[] = "Tagumschaltung erfolgt\n";
			ICWriteDayNight(0, FALSE);
			WriteIstec = TRUE;
			Write(fh, Meldung, strlen(Meldung));
		}
		else
		/* Nachtumschaltung */
		if(RDArry.Night)
		{
		char	Meldung[] = "Nachtumschaltung erfolgt\n";
			ICWriteDayNight(1, FALSE);
			WriteIstec = TRUE;
			Write(fh, Meldung, strlen(Meldung));
		}

		if(WriteIstec)
			ICSaveConfig(FALSE);
abbruch:
		/* Ausgabedatei wieder schliessen */
		if(!stdfh)
			Close(fh);

		FreeArgs(RDArgs);
	}
	else
		fprintf(stderr, "ReadArgs failed!\n");

	ExitMain();
} 
