/********************************************************************/
/* Name:  calcfees96.c                                              */
/* Zweck: Berechnung der durch AmigaUUCP verursachten       |    |  */
/*        Telefongebuehren                                  |    |  */
/* Purose: Calculate the phone fees caused by AmigaUUCP     |\__/`  */
/* Autor: Martin Hohl                                       |       */
/*        Robert-Leicht-Strasse 132                         |       */
/*        D-70569 Stuttgart                                         */
/*        F.R.Germany                                               */
/* Version: 0.3  vom 06.Mär.1996                                    */
/* Compiler: AmigaDOS: SAS/C 6.55                                   */
/* Letzte Modifikation: 06.03.1996                                  */
/* Status: Freeware, (C) by Martin Hohl                             */
/********************************************************************/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

#include <math.h>
#ifdef _IEEE
#include <mieeedoub.h>
#endif
#ifdef _M68881
#include <m68881.h>
#endif

/* Zeile von Datei einlesen */
void getline(FILE *fp, char *line)
{
  char c;
  do {
    c = getc(fp);
    if ((!feof(fp)) && (c != EOF) && (c != '\n'))
      *line++ = c;
  } while ((!feof(fp)) && (c != EOF) && (c != '\n'));
  *line = '\0';
}

/* Monat (Text) in Zahl umwandeln */
int montonum(char *monname)
{
  static char monate[12][4] = {"Jan","Feb","Mar","Apr","May","Jun",
                       "Jul","Aug","Sep","Oct","Nov","Dec"};
  int i;
  for (i=0; i<12; i++) if (strcmp(monname,monate[i])==0) return i+1;
  return -1;
}

/* Tarifzone in Abh. von Systemname bestimmen */
/* momentan: Dummy-Funktion mit Nahzone als Default */
int getzone(char *sysname)
{
  /* Not yet implemented !! */
  return 1;
}

unsigned long sum_einh = 0;
unsigned long sum_in = 0;
unsigned long sum_out = 0;
unsigned long sum_dur = 0;

/* Tage-Offset im Jahr am Monatsanfang */
static unsigned short dayoffset[12] = {
  0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
};

/* Ist das Jahr ein Schaltjahr ? */
short isleap(unsigned short year)
{
  if ((year-1972) % 4 == 0) return !0;
  else return 0;
}

/* Wochentag bestimmen */
unsigned short weekday(unsigned short day, unsigned short mon, unsigned short year)
{
  register unsigned short julday;

  julday = year + 4 + ((year + 3) / 4);    /* Julian Calendar    */
  if (year > 1800) {            /* If it's recent, do    */
      julday -= ((year - 1701) / 100);    /* Clavian correction    */
      julday += ((year - 1601) / 400);    /* Gregorian correction    */
  }
  if (year > 1752)            /* Adjust for Gregorian    */
      julday += 3;                /* calendar        */

  julday += dayoffset[mon-1];
  if (isleap(year)) if (mon > 2) julday++;

  julday += day-1;

  return (unsigned short)(julday % 7);
}

/* Zeile in UUSPOOL:Timelog auswerten */
void eval_line(char *linebuf, char *system, unsigned short monat)
{
  unsigned short day = 0, mon, year = 0;
  unsigned short hour = 0, min = 0;
  unsigned short durh = 0, durm = 0;
  unsigned short dauer;
  unsigned long inbytes = 0, outbytes = 0;
  unsigned short tarifzone;
  char monname[16];
  char sysname[64];
  unsigned short numtakte;
  double rate, takt;
  unsigned long uhrzeit;
  unsigned short wd;
 
  sscanf(linebuf,"%2hd-%3s-%2hd %2hd:%2hd %2hd:%2hd in=%ld out=%ld %s",&day,monname,&year,&hour,&min,&durh,&durm,&inbytes,&outbytes,sysname);
  if (year<96) return;
  mon = montonum(monname);
  if (strcmp(system,"*")!=0) if (strcmp(sysname,system)!=0) return;
  if ((short)monat != -1) if (monat!=mon) return;
  dauer = durh*60 + durm;
  tarifzone = getzone(sysname);
  uhrzeit = (unsigned long)(hour * 60 + min) * 60;

  wd = weekday(day,mon,year+1900);
  if ((wd > 0) && (wd < 6)) {
    if (tarifzone == 1) { /* Zeittakt City */
      if ((uhrzeit >= 5*3600L) && (uhrzeit < 9*3600L)) takt = 150;
      else if ((uhrzeit >= 9*3600L) && (uhrzeit < 18*3600L)) takt = 90;
      else if ((uhrzeit >= 18*3600L) && (uhrzeit < 21*3600L)) takt = 150;
      else takt = 240;
    }
    else if (tarifzone == 2) { /* Zeittakt Region 50 */
      if ((uhrzeit >= 5*3600L) && (uhrzeit < 9*3600L)) takt = 45;
      else if ((uhrzeit >= 9*3600L) && (uhrzeit < 12*3600L)) takt = 26; /* Spitzenlast */
      else if ((uhrzeit >= 12*3600L) && (uhrzeit < 18*3600L)) takt = 30;
      else if ((uhrzeit >= 18*3600L) && (uhrzeit < 21*3600L)) takt = 45;
      else if ((uhrzeit >= 2*3600L) && (uhrzeit < 5*3600L)) takt = 120;
      else takt = 60;
    }
    else if (tarifzone == 3) { /* Zeittakt Region 200 */
#ifdef BEFORE_1_7_96
      if ((uhrzeit >= 5*3600L) && (uhrzeit < 9*3600L)) takt = 21.5;
      else if ((uhrzeit >= 9*3600L) && (uhrzeit < 12*3600L)) takt = 12; /* Spitzenlast */
      else if ((uhrzeit >= 12*3600L) && (uhrzeit < 18*3600L)) takt = 13.5;
      else if ((uhrzeit >= 18*3600L) && (uhrzeit < 21*3600L)) takt = 21.5;
      else if ((uhrzeit >= 2*3600L) && (uhrzeit < 5*3600L)) takt = 120;
      else takt = 30;
#else
      if ((uhrzeit >= 5*3600L) && (uhrzeit < 9*3600L)) takt = 22.5;     
      else if ((uhrzeit >= 9*3600L) && (uhrzeit < 12*3600L)) takt = 13; /* Spitzenlast */
      else if ((uhrzeit >= 12*3600L) && (uhrzeit < 18*3600L)) takt = 14;
      else if ((uhrzeit >= 18*3600L) && (uhrzeit < 21*3600L)) takt = 22.5;
      else if ((uhrzeit >= 2*3600L) && (uhrzeit < 5*3600L)) takt = 120;
      else takt = 36;
#endif
    }
    else /* (tarifzone == 4) */ { /* Zeittakt Ferntarif */
#ifdef BEFORE_1_7_96
      if ((uhrzeit >= 5*3600L) && (uhrzeit < 9*3600L)) takt = 20;
      else if ((uhrzeit >= 9*3600L) && (uhrzeit < 12*3600L)) takt = 11.5; /* Spitzenlast */
      else if ((uhrzeit >= 12*3600L) && (uhrzeit < 18*3600L)) takt = 12.5;
      else if ((uhrzeit >= 18*3600L) && (uhrzeit < 21*3600L)) takt = 20;
      else if ((uhrzeit >= 2*3600L) && (uhrzeit < 5*3600L)) takt = 120;
      else takt = 25;
#else
      if ((uhrzeit >= 5*3600L) && (uhrzeit < 9*3600L)) takt = 21.5;
      else if ((uhrzeit >= 9*3600L) && (uhrzeit < 12*3600L)) takt = 12; /* Spitzenlast */
      else if ((uhrzeit >= 12*3600L) && (uhrzeit < 18*3600L)) takt = 13.5;
      else if ((uhrzeit >= 18*3600L) && (uhrzeit < 21*3600L)) takt = 21.5;
      else if ((uhrzeit >= 2*3600L) && (uhrzeit < 5*3600L)) takt = 120;
      else takt = 30;
#endif
    }
  }
  else {
    if (tarifzone == 1) { /* Zeittakt City */
      if ((uhrzeit >= 5*3600L) && (uhrzeit < 21*3600L)) takt = 150;
      else takt = 240;
    }
    else if (tarifzone == 2) { /* Zeittakt Region 50 */
      if ((uhrzeit >= 5*3600L) && (uhrzeit < 21*3600L)) takt = 45;
      else takt = 60;
    }
    else if (tarifzone == 3) { /* Zeittakt Region 200 */
#ifdef BEFORE_1_7_96
      if ((uhrzeit >= 5*3600L) && (uhrzeit < 21*3600L)) takt = 21.5;
      else takt = 30;
#else
      if ((uhrzeit >= 5*3600L) && (uhrzeit < 21*3600L)) takt = 22.5;
      else takt = 36;
#endif
    }
    else /* (tarifzone == 4) */ { /* Zeittakt Ferntarif */
#ifdef BEFORE_1_7_96
      if ((uhrzeit >= 5*3600L) && (uhrzeit < 21*3600L)) takt = 20;
      else takt = 25;
#else
      if ((uhrzeit >= 5*3600L) && (uhrzeit < 21*3600L)) takt = 21.5;
      else takt = 30;
#endif
    }
  }
  printf("%02hu.%02hu.%02hu %7s %9lu %9lu ",day,mon,year,sysname,inbytes,outbytes);
  numtakte = (unsigned short)(ceil((double)dauer / takt));
  if (dauer != 0) rate = (double)(inbytes+outbytes)/(double)dauer;
  else rate = 0;
  printf(" %4hu  %4.0lf  %5.1lf  %3hu  %hu,%02hu DM\n",dauer,rate,takt,numtakte,(unsigned short)((numtakte*12L)/ 100),(unsigned short)((numtakte*12L) % 100));

  sum_einh += numtakte;
  sum_in += inbytes;
  sum_out += outbytes;
  sum_dur += dauer;
}

main(int argc, char *argv[])
{
  FILE *in;
  char *linebuf;
  char *sysname;
  char *mon;
  double rate;

  if (argc>=3) mon = strdup(argv[2]);
  else mon = "*";
  if (argc>=2) sysname = strdup(argv[1]);
  else sysname = "*";

  linebuf = malloc(1024);
  if (linebuf == NULL) {
    perror(argv[0]);
    exit(20);
  }
  memset(linebuf,0,1024);
  in = fopen("UUSPOOL:Timelog","r");
  if (in == NULL) {
    perror(argv[0]);
    exit(20);
  }
  printf("                     Input    Output Dauer  Rate   Takt \n");
  printf("Datum     System   [Bytes]   [Bytes]   [s] [B/s]   [s]  Einh. Gebühren\n");
  puts("-----------------------------------------------------------------------");

  do {
    getline(in,linebuf);
    if (feof(in)) break;
    eval_line(linebuf,sysname,montonum(mon));
  } while (!feof(in));
  puts("-----------------------------------------------------------------------");
  if (sum_dur != 0) rate = (double)(sum_in+sum_out)/(double)sum_dur;
  else rate = 0;
  printf("Summe:          %10lu %9lu %5lu  %4.0lf         %3lu %2hu,%02hu DM\n",sum_in,sum_out,sum_dur,rate,sum_einh,(unsigned short)((sum_einh*12L)/ 100),(unsigned short)((sum_einh*12L) % 100));
  fclose(in);
}
