#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#include <tos.h>
#include <ext.h>

/* Ergnzungen fr Feiertagsberechnungen */
struct date local;
struct date datum;

#define PRN stdout

/* define some simple keyword replacements */

#define false           0
#define true            1
#define val(s,res) res=atof(s)
#define STRSIZ 255      /* default string length */

/* Prototypes */
int feiertag(char *ptr);
void feier(int jahrestag, int jahr, struct date *ptr);


float tarif[6][2] = {
						360.000, 720.000,	/* Orts- und Nahzone */
						 60.000, 120.000,	/* Regionalzone */
						 21.000,  42.000,	/* Weitzone */
						 12.000,  16.000,	/* Europa Fernzone 1 */
						 10.667,  10.667,	/* Europa Fernzone 2 */
						  4.420,   4.420	/* Rest der Welt */
					};

/*
 * copy len bytes from the dynamic string dstr starting at position from
 *
 */
char *copy(char *str, int from, int len)
{
   static char buf[STRSIZ];
   buf[0]=0;
   if (from>strlen(str))     /* copy past end gives null string */
      return buf;

   strcpy(buf,str+from-1);  /* skip over first part of string */
   buf[len] = 0;            /* truncate after len characters */
   return buf;
}

/*
 * string build - like scat, sprintf, but will not over-write any
 *                input parameters
 */

void sbld(char *dest, char *control, ...)
{
   char buf[STRSIZ];
   va_list args;

   va_start(args, control);     /* get variable arg pointer */
   vsprintf(buf,control,args);  /* format into buf with variable args */
   va_end(args);                /* finish the arglist */

   strcpy(dest,buf);            /* copy result */
}



/*
 * spos(str1,str2) - returns index of first occurence of str1 within str2;
 *    1=first char of str2
 *    0=nomatch
 */

int spos(char *str1, char *str2)
{
   char *res;
   res = strstr(str2,str1);
   if (res == NULL)
	  return(0);
   else
	  return((int) (res - str2 + 1));
}


/*
 * cpos(str1,str2) - returns index of first occurence of c within str2;
 *    1=first char of str2
 *    0=nomatch
 */

int cpos(char c, char *str2)
{
   char *res;
   res = strchr(str2,c);
   if (res == NULL)
      return 0;
   else
	  return((int)(res - str2 + 1));
}



/*
 * Scanf/Fscanf support
 *
 * These functions operate like scanf and fscanf except for an added control
 * code used for full-line reads.
 *
 */

int fscanv(FILE *fd, char *control, ...)
{
   va_list args;
   char *arg1;
   int     i;

   va_start(args, control);     /* get variable arg pointer */

   /* process special case for full-line reads (why doesn't scanf allow
      full-line string reads?  why don't gets and fgets work the same?) */
   if (*control == '#') {
      arg1 = va_arg(args,char *);
      fgets(arg1,STRSIZ,fd);
      arg1[strlen(arg1)-1] = 0;
      return 1;
   }

   /* pass the request on to fscanf */
   i = vfscanf(fd,control,args);    /* scan with variable args */
   va_end(args);                    /* finish the arglist */

   return i;                        /* return a pointer to the string */
}


float einheit  = 0.23;
char TelFile[80]  = "RUFUS.LOG";

char bereich;
long teuer, billig;
int einheiten;
float kosten;
float SummeKosten;
long SummeTeuer, SummeBillig;
int SummeEinheiten;
FILE *rf;
char         OnZeit[9];
char 		 OnDate[8];				/* eigene Ergnzung */
char         OffZeit[9];
char         kopf[81];

void         InitVars(void)
{
	bereich = 0;
	einheiten = 0;
	teuer = 0;
	billig = 0;
	kosten = 0;
	SummeKosten = 0;
	SummeEinheiten = 0;
	SummeTeuer = 0;
	SummeBillig = 0;
	strcpy(OnZeit,"");
	strcpy(OffZeit,"");
	strcpy(kopf,"Datum    BBS                  Bereich   Teuert.  Billigt. Einheiten    Kosten");
}


void InitScreen(void)
{
	fprintf(PRN,"\n");
	fprintf(PRN,"TFKOSTEN - Berechnung der Telefongebhren aus RUFUS.LOG\n");
	fprintf(PRN,"\n");
}


void TestExistance(void)
{
	rf = fopen(TelFile,"r");
	if (rf == NULL)
	{
		printf("Wo ist das %s ?\n\n", TelFile);
		exit(0);
	}
}


void CalculateSeconds(char *On,char *OnDate, char *Off, long *teuer, long *billig)
{
#define TANF 28800L		/* 8 Uhr */
#define TEND 64800L		/* 18 Uhr */

	int HOn, MOn, SOn, HOff, MOff, SOff;
	long start, stop;


	val(copy(On,1,2),HOn);
	val(copy(On,4,2),MOn);
	val(copy(On,7,2),SOn);
	val(copy(Off,1,2),HOff);
	val(copy(Off,4,2),MOff);
	val(copy(Off,7,2),SOff);

	start = (long)SOn + (60L * (long)MOn) + (3600L * (long)HOn);	/* Startzeitpunkt */
	stop  = (long)SOff + (60L * (long)MOff) + (3600L * (long)HOff);	/* Stopzeitpunkt */

	if ((start > TANF) && (start < TEND) && (stop > TANF) && (stop < TEND))
	{								/* alles im teuren Bereich */
	if (feiertag(OnDate) != 7) 	/* kein Feiertag/Samstag/Sonntag */	
	 	{
	 	*teuer  = stop - start;
		*billig  = 0;
		}
	else
		{
		/*printf("\nFeiertag !!!!");*/
		*teuer  = 0;
		*billig = stop - start;
		}
	}
	else
	if (((start < TANF) && (stop < TANF)) || ((start > TEND) && (stop > TEND)))
	{
		if (stop < start)
			*billig = start - stop;
		else
			*billig = stop - start;
		*teuer = 0;
	}
	else
	if ((start > TEND) && (stop < TANF))
	{
		*billig = (24L * 3600L) - start + stop;
		*teuer  = 0;
	}
	else
	if ((start < TANF) && (stop > TANF))
	{
	if (feiertag(OnDate) != 7) 	/* kein Feiertag */	
		{
		*billig = TANF - start;
		*teuer = stop - TANF;
		}
	else 
		{
		*billig = (TANF - start )+stop-TANF;
		*teuer  = 0;
		}
	}	
	else
	{
	if (feiertag(OnDate) != 7) 	/* kein Feiertag */	
		{
		*teuer = TEND - start;
		*billig = stop - TEND;
		}
	else
		{
		*teuer= 0;
		*billig = stop-start;
		} 
	}
}



void DoIt(void)
{
char ReadLine[81], WriteLine[81];
char tmpline[81];
char BBS[41];
char dummy[STRSIZ];
char i;
char *p;


	fprintf(PRN,"Kennziffern der Tarifzonen Deutschland:\n");
	fprintf(PRN," [0] Ortsnetz     [1] <= 50 km   [2] ber 50 km\n");
	fprintf(PRN,"Kennziffern der Tarifzonen Ausland:\n");
	fprintf(PRN," [3] Fernzone 1   [4] Fernzone 2 und Mittelmeer  [5] Rest der Welt\n\n");
    fprintf(PRN,"%s\n",kopf);
    fprintf(PRN,"------------------------------------------------------------------------------\n");
	while (feof(rf) == false)
	{
		fscanv(rf,"#\n",ReadLine);
        if (spos("Connect",ReadLine) != 0)
		{
			strcpy(OnZeit,copy(ReadLine,10,8));
			strcpy(OnDate,copy(ReadLine,3,6));
			p = strstr(&ReadLine[23], ")");
			if (p != NULL)
			{
				p++;
				*p = '\0';
	            p = strcpy(BBS,&ReadLine[23]);
				strcat(BBS,&ReadLine[30]);
				val(copy(BBS,cpos('(',BBS) + 1,1),bereich);
				p = strstr(BBS,"(");
				if (p != NULL)
					*p = '\0';
				do
				{
					fscanv(rf,"#\n",ReadLine);
				} while (!(spos("Offline",ReadLine) != 0));
				strcpy(OffZeit,copy(ReadLine,10,8));
				CalculateSeconds(OnZeit,OnDate,OffZeit, &teuer, &billig);

				SummeTeuer += teuer;
				SummeBillig += billig;
				einheiten =  floor ((teuer / tarif[bereich][0])) + floor (( billig / tarif[bereich][1]) + 1);
				SummeEinheiten = SummeEinheiten + einheiten;
				kosten = einheiten * einheit;
				SummeKosten = SummeKosten + kosten;

				if (strlen(BBS) < 30)
					for (i = strlen(BBS) + 1; i <= 30; i++)
						sbld(BBS,"%s ",BBS);
				strcpy(WriteLine,BBS);
				sbld(dummy,"%5d",bereich);
				sbld(WriteLine,"%s%s",WriteLine,dummy);
				sbld(dummy,"%10ld", teuer);
				sbld(WriteLine,"%s%s",WriteLine,dummy);
				sbld(dummy,"%10ld",billig);
				sbld(WriteLine,"%s%s",WriteLine,dummy);
				sbld(dummy,"%10d",einheiten);
				sbld(WriteLine,"%s%s",WriteLine,dummy);
				sbld(dummy,"%10.2f DM",kosten);
				sbld(WriteLine,"%s%s",WriteLine,dummy);
                fprintf(PRN,"%s\n",WriteLine);
			}
			else
				strcpy(BBS, "");
		}
		else
			strcpy(tmpline, ReadLine);
	}
	fclose(rf);
    fprintf(PRN,"------------------------------------------------------------------------------\n");
	strcpy(WriteLine,"                            Summe: ");
	sbld(dummy,"%10ld",SummeTeuer);
	sbld(WriteLine,"%s%s",WriteLine,dummy);
	sbld(dummy,"%10ld",SummeBillig);
	sbld(WriteLine,"%s%s",WriteLine,dummy);
	sbld(dummy,"%10d",SummeEinheiten);
	sbld(WriteLine,"%s%s",WriteLine,dummy);
	sbld(dummy,"%10.2f DM",SummeKosten);
	sbld(WriteLine,"%s%s",WriteLine,dummy);
    fprintf(PRN,"%s\n",WriteLine);
	printf("Weiter mit beliebiger Taste....");
    fclose(PRN);
	getch();

}



int main(int argc, char *argv[])
{
	if(argc > 1)
		strcpy(TelFile, argv[1]);
 InitVars();
 InitScreen();
 TestExistance();
 DoIt();
 return(0);
}




/* feiertag : berechnet anhand des Datums, ob Werktag oder
   Feiertag/Samstag/Sonntag */
int feiertag(char *da)
{
int a,b,c,d,e,f,n,jahr,ret=0,days[5];
int i,date,bussbett;

getdate(&datum);			/* aktuelles Jahr holen */
da[2]=0;
datum.da_day = (char) atoi(da);
switch(da[3])
	{
	case 'J':	if (strncmp(&da[3],"Jan",3L)==0)
					datum.da_mon = 1; 				/* Januar */
				if (strncmp(&da[3],"Jun",3L)==0)
					datum.da_mon = 6; 	 			/* Juni */
				if (strncmp(&da[3],"Jul",3L)==0)
					datum.da_mon = 7; 				/* Juli */
				break;
	case 'F':	datum.da_mon = 2; 	break;			/* Februar */
	case 'M':	if (strncmp(&da[3],"Mai",3L)==0)
					datum.da_mon = 5; 	 			/* Mai */
				else
					datum.da_mon = 3; 	break;		/* Mrz */
					
	case 'A':	if (strncmp(&da[3],"Aug",3L)==0)
					datum.da_mon = 8; 				/* August */
				else
					datum.da_mon = 4; 	break;		/* April */
	case 'S':	datum.da_mon = 9; 	break;			/* September */
	case 'O':	datum.da_mon = 10; 	break;			/* Oktober   */
	case 'N':	datum.da_mon = 11; 	break;			/* November  */
	case 'D':	datum.da_mon = 12; 	break;			/* Dezember  */
	default: 	printf("\n ERROR IN DATUMSROUTINE !!");
				printf("\n da=%s    da[3]=%s",da,&da[3]);
				break;
	}

jahr = datum.da_year;

/* Wochentag berechnen */
ret=((jahr-1901)*1461/4)+1+datum.da_day+((158*datum.da_mon-157)/5)+
	(datum.da_mon>2)*(datum.da_mon-(0<(jahr%4)));

ret= ret % 7 +1;

if (ret ==6)	ret = 7;


a = jahr % 19;
b = jahr % 4;
c = jahr % 7;
d = (19 * a + 24) % 30;
e = (2*b + 4*c + 6*d +5);
f = d + e -9;
n = f + 90 - (0== (jahr%4) );

if (ret != 7)
	{
	date=datum.da_mon*10+datum.da_day;
	bussbett =22-((jahr-1901)*1461/4)+1+22+((158*12-157)/5)+
		(12>2)*(12-(0<(jahr%4)));
	bussbett *=10+11;
	
	switch (date)
		{
		case 0101:	ret = 7;	break;		/* Neujahr */
		case 0105:	ret = 7;	break;		/* 1.Mai   */
		case 0310:	ret = 7;	break;		/* Tag der dt. Einheit    */
											/* wird evtl. abgeschafft */
		case 2412:	ret = 7;	break;		/* Billigtarif lt. Telefonbuch */
		case 2512:	ret = 7;	break;		/* Weihnachten */
		case 2612:	ret = 7;	break;		/* Weihnachten */
		case 3112:	ret = 7;	break;		/* Billigtarif lt. Telefonbuch */
		
		default  : 	if (bussbett==date) 	/* Bu- und Bettag */
						ret=7;	
					break;	
		}
	}
if (ret != 7)	
	{
	days[0]=n-48;
	days[1]=n;					
	days[2]=n+39;				/* Christi Himmelfahrt */
	days[3]=n+49;				/* Pfingstmontag (eigentlich + 11, oder ? ) */
	
	for (i=0; i<5; i++)
		{
		feier(days[i],datum.da_year,&local);
		if ( (datum.da_mon == local.da_mon) && (datum.da_day == local.da_day) )
			{
			ret=7;
			break;
			}
		}
	}
return(ret);
}

void feier(int jahrestag, int jahr, struct date *ptr)
{
int i,tag;

for (i=6;i<2; i--)
	{
	tag = ( (158*i - 157) / 5) + (i>2) * (i- (0<jahr%4) );
	if ( jahrestag > tag )
		{
		ptr -> da_day = (char) jahrestag-tag;
		ptr -> da_mon = (char) i;
		break; /* for Schleife abbrechen */
		}
	}
}

