#define TIME_FILENAME 	"~/TimeClock/TimeFile.DATA"

#define TET_EOF 			0
#define TET_PUNCH_IN		1
#define TET_PUNCH_OUT 		2

class TimeEntry
{
	TimeEntry	*next, *last;
	U8			 type;
	CDate		 datetime;
	U8			*desc;
};

U0 TimeFileRead(TimeEntry *header)
{
	U8			*buf, *ptr;
	I64			 type;
	TimeEntry	*tmpt;

	buf = FileRead(TIME_FILENAME);
	if (!buf)
		buf = CAlloc(1);
	QueueInit(header);
	ptr = buf;
	while (type = *ptr++)
	{
		tmpt = CAlloc(sizeof(TimeEntry));
		tmpt->type		= type;
		tmpt->datetime	= *ptr(CDate *)++;
		tmpt->desc		= StrNew(ptr);
		ptr += StrLen(ptr) + 1;
		QueueInsert(tmpt, header->last);
	}
	Free(buf);
}

U0 TimeFileWrite(TimeEntry *header)
{
	U8			*buf, *ptr;
	TimeEntry	*tmpt;
	I64			 size = 1; //for EOF

	tmpt = header->next;
	while (tmpt != header)
	{
		size += sizeof(U8) + sizeof(CDate) + StrLen(tmpt->desc) + 1;
		tmpt = tmpt->next;
	}
	buf = MAlloc(size);

	ptr = buf;
	tmpt = header->next;
	while (tmpt != header)
	{
		*ptr+ += tmpt->type;
		*ptr(CDate *)++ = tmpt->datetime;
		StrCopy(ptr, tmpt->desc);
		ptr += StrLen(tmpt->desc) + 1;
		tmpt = tmpt->next;
	}
	*ptr = TET_EOF;
	FileWrite(TIME_FILENAME, buf, size);
	Free(buf);
}

U0 TimeEntriesDel(TimeEntry *header)
{
	TimeEntry *tmpt = header->next, *tmpt1;

	while (tmpt != header)
	{
		tmpt1 = tmpt->next;
		Free(tmpt->desc);
		Free(tmpt);
		tmpt = tmpt1;
	}
	Free(header);
}

public Bool TimeRep(TimeEntry **_header=NULL)
{
	Bool		 is_in = FALSE, first = TRUE;
	I64			 week, cur_week = -1, week_total;
	TimeEntry	*tmpt, *header = MAlloc(sizeof(TimeEntry));

	if (_header)
		*_header = header;
	TimeFileRead(header);
	tmpt = header->next;
	while (tmpt != header)
	{
		week = tmpt->datetime.date / 7;  //TODO
		if (week != cur_week)
		{
			if (!first)
			{
				if (is_in)
					week_total += Now;
				"Week Total:%T\n", week_total - local_time_offset;
			}
			else
				first = FALSE;
			cur_week = week;
			week_total = 0;
		}
		if (tmpt->type == TET_PUNCH_IN)
		{
			"$$RED$$IN ";
			if (!is_in)
				week_total -= tmpt->datetime;
			is_in = TRUE;
		}
		else
		{
			"$$RED$$OUT";
			if (is_in)
				week_total += tmpt->datetime;
			is_in = FALSE;
		}
		" %D %T:$$FG$$\n%s\n", tmpt->datetime, tmpt->datetime, tmpt->desc;
		tmpt = tmpt->next;
	}
	if (is_in)
		week_total += Now;
	"$$RED$$Week Total:%T$$FG$$\n", week_total - local_time_offset;
	if (!_header)
		TimeEntriesDel(header);
	return is_in;
}

public U0 PunchOut()
{
	TimeEntry *tmpt, *header;

	if (!TimeRep(&header))
		"$$BK,1$$Already Punched-Out$$BK,0$$\n";
	else
	{
		tmpt = MAlloc(sizeof(TimeEntry));
		tmpt->type		= TET_PUNCH_OUT;
		tmpt->datetime	= Now;
		"\nEnter Description.\nPress <ESC> when done.\n";
		if (!(tmpt->desc = StrGet(,, SGF_WITH_NEW_LINE)))
			tmpt->desc	= CAlloc(1);
		QueueInsert(tmpt, header->last);
		TimeFileWrite(header);
	}
	TimeEntriesDel(header);
}

public U0 PunchIn()
{
	TimeEntry *tmpt, *header;

	if (TimeRep(&header))
		"$$BK,1$$Already Punched-In$$BK,0$$\n";
	else
	{
		tmpt=MAlloc(sizeof(TimeEntry));
		tmpt->type		= TET_PUNCH_IN;
		tmpt->datetime	= Now;
		"\nEnter Description.\nPress <ESC> when done.\n";
		if (!(tmpt->desc = StrGet(,, SGF_WITH_NEW_LINE)))
			tmpt->desc	= CAlloc(1);
		QueueInsert(tmpt, header->last);
		TimeFileWrite(header);
	}
	TimeEntriesDel(header);
}
