D			[0-9]
DATE			{D}{D}"."{D}{D}"."{D}{D}{D}{D}
TIME			{D}{D}":"{D}{D}":"{D}{D}

%{
#include <stdio.h>
#include <time.h>
#include <string.h>

#define MODE_OFFLINE		0
#define MODE_ONLINE			1
#define MODE_RECONNECT	2

int flag = MODE_OFFLINE;
float unit_cost;

struct Connection
{
	int bday, bmonth, byear;
	int bhour, bminute, bsecond;

	int eday, emonth, eyear;
	int ehour, eminute, esecond;

	int total;
	int total_time;
	int last;
	int days[32];
	int times[32];
	int crashes;

} conex, *ctx = &conex;

%}
%%
"Offline:"	{
			flag = MODE_OFFLINE;
		}

"Online:"	{
			/* two "Online"'s in a row mean that there
			 was a crash/reboot inbetween */

			if(flag == MODE_ONLINE)
			{
				ctx->crashes++;
				ctx->total++;
			}

			flag = MODE_ONLINE;
		}

"Reconnect:"	{
			flag = MODE_RECONNECT;
		}

{DATE}		{
			if(flag == MODE_ONLINE)
				sscanf(yytext,"%d.%d.%d", &ctx->bday, &ctx->bmonth, &ctx->byear);
			else
				sscanf(yytext,"%d.%d.%d", &ctx->eday, &ctx->emonth, &ctx->eyear);
		}

{TIME}		{
			struct tm itm;
			int start, end;

			if(flag == MODE_ONLINE)
				sscanf(yytext,"%d:%d:%d", &ctx->bhour, &ctx->bminute, &ctx->bsecond);
			else
			{
				sscanf(yytext,"%d:%d:%d", &ctx->ehour, &ctx->eminute, &ctx->esecond);

				itm.tm_sec = ctx->bsecond;
				itm.tm_min = ctx->bminute;
				itm.tm_hour = ctx->bhour;
				itm.tm_mday = ctx->bday;
				itm.tm_mon = ctx->bmonth;
				itm.tm_year = ctx->byear;
				itm.tm_isdst = 0;

				start = mktime(&itm);

				itm.tm_sec = ctx->esecond;
				itm.tm_min = ctx->eminute;
				itm.tm_hour = ctx->ehour;
				itm.tm_mday = ctx->eday;
				itm.tm_mon = ctx->emonth;
				itm.tm_year = ctx->eyear;
				itm.tm_isdst = 0;

				end = mktime(&itm);

				ctx->last = (end - start + 179) / 180;
				ctx->times[ctx->bday] += end - start;
				ctx->total_time += end - start;
				ctx->days[ctx->bday] += ctx->last;
				ctx->total += ctx->last;
			}
		}

\n			{}
.			{ /* ignore bad characters */ }

%%

yywrap()
{
	return(1);
}

main(int argc, char *argv[])
{
	int i, x, max = 0;

	if(argc == 2)
	{
		if(sscanf(argv[1], "%f", &unit_cost) != 1)
		{
			printf("Bad args!\n");
			exit(1);
		}
	}
	else
		unit_cost = 0.23;

	memset(ctx, 0, sizeof(struct Connection));
	yylex();

	for(i = 1; i <= ctx->eday; i++)
		if(max < ctx->days[i])
			max = ctx->days[i];

	for(i = 1; i <= ctx->eday; i++)
	{
		printf("day %02ld: ", i);
		for(x = 0; x < ctx->days[i]; x++)
			printf("#");

		printf("%*s(%02ld:%02ld:%02ld)\n", max - ctx->days[i] + 1, "", ctx->times[i] / 3600, (ctx->times[i] / 60) % 60, ctx->times[i] % 60);
	}

	printf("\nLast connection: %d pulses (%.2f zl)\nSum:\t%ld pulses\nTime:\t%02ld:%02ld:%02ld\nPrice:\t%.2f zl\nDaily:\t%.2f zl\n", ctx->last, ctx->last * unit_cost, ctx->total, ctx->total_time / 3600, (ctx->total_time / 60) % 60, ctx->total_time % 60, ctx->total * unit_cost, ctx->total * unit_cost / ctx->eday);

	if(ctx->crashes)
		printf("\nWARNING!!!\nThere %s %ld crash%s so the actual pulse count may be higher!\n", ctx->crashes == 1 ? "was" : "were", ctx->crashes, ctx->crashes == 1 ? "" : "es");

}
