#ifdef	ournix
#include "ournix.h"
#endif
char sccsID[] = "@(#) timesheet.c V2.0 Copyright Julian H. Stacey 1988" ;

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

#define GRIPE gripe(start_hour, start_minute, stop_hour, stop_minute)

char	**ARGV ;
char time_hr_min[] = " Hour:Minute\t\t\t";
unsigned	line_u = 1 ;			/* report bad data. */
char rec_line[100];
char date_line[100];
char rate_line[100];
char job_line[100];
char where_s[20] ;
char day_in_week_s[20];
char time_in_day_s[20];
char job_description[100];
char day_description[100];
#define	JOB_LN	100
#define	DAY_LN	100
unsigned job_ln ;
unsigned day_ln ;
	int	start_hour  ;		/* start hour */
	int	start_minute  ;		/* start minute */
	int	stop_hour  ;		/* stop hour */
	int	stop_minute  ;		/* stop minute */

struct rate_s { char *text ; float factor ; } rate_a[] =
	{	/* Pay Rates depending on work, time of day & day in week */
	"w_site",	1.0, /* Where: On Site */
	"w_full",	1.0, /* Where: Off site Full time work */
	"w_high",	0.8, /* Where: Remote High intensity. */
	"w_low",	0.6, /* Where: Remote Low  intensity. */
	"t_night",	1.5, /* Time: 00:00-08:00 */
	"t_day",	1.0, /* Time: 08:00-19:00 */
	"t_eve",	1.2, /* Time: 19:00-24:00 */
	"d_week",	1.0, /* Day: Monday 08:00-Friday 19:00 */
	"d_sat",	1.1, /* Day: Friday 19:00 - Saturday 19:00 */
	"d_sun",	1.3, /* Day: Saturday 19:00 - Monday 08:00 */
	"d_hol",	1.5, /* Day: Public Holiday eg Christmas */
	"",		0.0
	} ;

float	get_rate2(str_p )
	char *str_p;
	{
	struct rate_s	*rate_p ;

	// printf("get_rate2 in: |%s|\n", str_p );
	// printf("get_rate2 00 %d %d %d\n",
		// sizeof(char *),
		// sizeof(float ),
		// sizeof(struct rate_s ) );
	// (void) fflush(stdout);

	rate_p = &rate_a[0]	;
	while (1) 
		{
		// printf("get_rate2 11:\n");
 		// (void) fflush(stdout);
		// printf("get_rate2 22 %s %f:\n",rate_p->text,rate_p->factor);
		if (rate_p->factor == 0.0 ) GRIPE ; 
		if (!strcmp(str_p,rate_p->text)) 
			{
			// printf("\nget_rate2 out: %s, %f\n", 
				// rate_p->text,  rate_p->factor);
			// (void) fflush(stdout);
			return ( rate_p->factor) ;
			}
		rate_p ++ ;
		} ;
	}

float	get_rate1(where_p, day_in_week_p, time_in_day_p )
	char *where_p, *day_in_week_p, *time_in_day_p  ;
	{
	// printf("\nget_rate1: %s %s %s\n", where_p, day_in_week_p, time_in_day_p);
	(void) fflush(stdout);
	return ( get_rate2(where_p) * get_rate2(day_in_week_p) *
		get_rate2(time_in_day_p) ) ;
	}

main(argc, argv)
	int argc ; char **argv ;
	{
	/* Input */
	int	break_minutes  ;		/* lunch & other breaks, in minutes */

	/* Internal calculations */
	long		start_l, stop_l, tmp_l ;	/* temporaries */
	int 		silent = 1 ;

	float		factor_numeric ;

	int	session_hours_flat = 0 ;	/* hours that session */
	int	session_minutes_flat = 0 ;	/* minutes that day */
	int	cumulative_hours_flat = 0 ;	/* hours total */
	int	cumulative_minutes_flat = 0 ;	/* minutes total */

	/* Factored hours & mins eg Night rate may be = 1.5 */
	float	session_minutes_factored ;	/* hours that session */
	float	cumulative_minutes_factored = 0.0 ;	/* hours total */
	/* To avoid cumulative floating divide error, do not keep
		the total in hours, but minutes, & just convert minutes to
		hours on output. */
	char *job_p ;
	char *day_p ;
	int ch_i ;

	/* ---- */
	ARGV = argv ;
#ifdef	VSL	/* { */
#include	"../../include/vsl.h"
#endif		/* } */
	if (!silent)
		{
		printf(
		 "Examples:\tOvernight session:\t\tStart 21:00,\tEnd 26:00\n");
		printf(
		 "\t\tInclude previous total:\t\tStart 0:0,\tEnd 52:30\n");
		printf(
		 "\t\tDeduct mistake:\t\t\tLunch -80\n\n");
		}
	do	{
		/* Zero them in case we rport a syntax error while they
		   would otherwise have random or old values */
		start_hour = start_minute = stop_hour = stop_minute
			= break_minutes = 0 ;
		rec_line[0] = '\0' ;
		date_line[0] = '\0' ;
		rate_line[0] = '\0' ;
		job_line[0] = '\0' ;
	/* -- Look for ^@Rec */

		if ((scanf("%s", rec_line) < 1) ||
			 strncmp("@Rec",  rec_line, strlen("@Rec"))) GRIPE ;

		line_u++ ;
	/* -- Look for ^@Day multi word line (usually Date Day) */
		if ((scanf("%s", &date_line ) < 1 ) ||
			 strncmp("@Day", date_line, strlen("@Day"))) GRIPE ; 
		/* Swallow space before date & day */
		while (1)
			{
			if ((ch_i = getchar() ) == EOF ) GRIPE ;
			if (( (char)ch_i != ' ') && 
				( (char)ch_i != '\t')) break ;
			}
		/* Swallow rest of date line */
		day_p = day_description ; day_ln = DAY_LN ;
		while	(( (char)ch_i != '\n') && ( (char)ch_i != '\0') && 
				--day_ln )
			{
			*day_p++ = (char)ch_i ; 
			if ((ch_i = getchar() ) == EOF ) GRIPE ;
			} 
		*day_p = '\0';
		line_u++ ;
	/* -- Look for ^@Rate word x word x word */
		if ((scanf("%s %s x %s x %s",
			 	&rate_line,
			 	&where_s,
				&day_in_week_s,
				&time_in_day_s
				) != 4) ||
			 strncmp("@Rate", rate_line, strlen("@Rate"))) GRIPE ;
		line_u++ ;
	/* -- Look for ^@Job multi word description .... */
		if ((scanf("%s", &job_line ) < 1 ) ||
			 strncmp("@Job", job_line, strlen("@Job"))) GRIPE ;
		/* Swallow space before job description */
		while (1)
			{
			if ((ch_i = getchar() ) == EOF ) GRIPE ;
			if (( (char)ch_i != ' ') && 
				( (char)ch_i != '\t')) break ;
			}
		/* Swallow rest of job line */
		job_p = job_description ; job_ln = JOB_LN ;
		while	(( (char)ch_i != '\n') && ( (char)ch_i != '\0') && 
				--job_ln )
			{
			*job_p++ = (char)ch_i ; 
			if ((ch_i = getchar() ) == EOF ) GRIPE ;
			} 
		*job_p = '\0';

		line_u++ ;
	/* -- Look for start time ^[0-9][0-9]:[0-9][0-9] */
		if (!silent) printf("%02d\tStart%s", line_u, time_hr_min);
		if ((scanf("%d:%d", &start_hour , &start_minute) != 2) ||
			( start_hour < 0 ) || (start_hour > 23) ||
			( start_minute < 0 ) || (start_minute > 59) ) GRIPE ;
		start_l = start_hour * 60 + start_minute ;
		line_u++ ;
	/* -- Look for stop time ^[0-9][0-9]:[0-9][0-9] */
		if (!silent) printf("\tStop %s\t", time_hr_min);
		if ((scanf("%d:%d", &stop_hour, &stop_minute) != 2) ||
			( stop_hour < 0 )
			/* No check of ( stop_hour > 24),
			  Allows entry of
			  overnight jobs stopping at 3am as 27:00 */
			 || ( stop_minute < 0 ) || (stop_minute > 59)
			) GRIPE ;
		stop_l = stop_hour * 60 + stop_minute ;

		if ( 0 > (tmp_l = (stop_l - start_l ))) GRIPE ;
		line_u++ ;
	/* -- Look for break minute time ^[0-9][0-9] */
		/* No checks here, so we can cludge totals */
		if (!silent) printf("\tLunch Duration, (Mins.):\t\t\t\t");
		if ((scanf("%d", &break_minutes) != 1) ||
			( break_minutes < 0 ) ) GRIPE; 
		/* no check of if ( break_minutes > 60 )
			Allow people to book a lunch break of eg 70 mins,
			plus other breaks (perhaps to nip out shopping,
			or for higher priority work on a different project etc)
		 */
		if ( tmp_l < (long) break_minutes ) GRIPE; 
		tmp_l -= (long) break_minutes ;

		line_u++ ;

	/* -- Finished input of a session record, now output. */

		// printf("\n") ;
		printf("%s: ", day_description) ;
		printf("%s\n", job_description) ;

		/* Start & Finish Times */
		printf("%02d:%02d-%02d:%02d ",
			start_hour, start_minute, stop_hour, stop_minute);

		/* Minutes Off On Breaks */
		printf("%3u", (unsigned)break_minutes);
			/* might be a few hours so need 3 digits */

		/* Session in Hours & Minutes */
		session_hours_flat = tmp_l / 60 ;
		session_minutes_flat = tmp_l % 60 ;
		printf(" %2d:%02d", session_hours_flat, session_minutes_flat );

		/* Cumulative of all sessions in Hours & Minutes */
		cumulative_hours_flat += session_hours_flat ;
		cumulative_minutes_flat += session_minutes_flat ;
		cumulative_hours_flat += cumulative_minutes_flat / 60 ;
		cumulative_minutes_flat %= 60 ;
		printf(" \%3d:%02d",
			 cumulative_hours_flat, cumulative_minutes_flat );
			/* 3 digits is enough for a a few months of hours,
			   sure a years worth of hours goes into 4 digits,
			   even just for one person, but billing 
			   doesnt wait half a year!
			 */

		/* Factor Text */
		printf(" %-6s %-6s %-7s",
			/* 	6: "w_site" "w_full" "w_high" "w_low"
        			6: "d_week" "d_sat" "d_sun" "d_hol"
        			7: "t_night" "t_day" "t_eve"
			*/
				where_s, day_in_week_s, time_in_day_s );

		/* Factor Numeric */
		factor_numeric = 
			get_rate1(where_s, day_in_week_s, time_in_day_s ) ;
		printf(" %f", factor_numeric );

		/* Factored Session in Hours */
		session_minutes_factored = factor_numeric *
			( session_hours_flat * 60 + session_minutes_flat ) ;
		printf(" %-2f", session_minutes_factored / 60 );

		/* Factored Cumulative in Hours */
		cumulative_minutes_factored += session_minutes_factored ;
		printf(" \%-3f", cumulative_minutes_factored / 60 );

		printf("\n" );
		}
	while (session_hours_flat || session_minutes_flat) ;
	exit(0);
	}

gripe(start_hour, start_minute, stop_hour, stop_minute)
	int	start_hour ;	/* start hour */
	int	start_minute ;	/* start minute */
	int	stop_hour ;	/* stop hour */
	int	stop_minute ;	/* stop minute */
	{
	printf("\nLine %u, Where:%s, Day_In_Week:%s, Time_In_Day:%s, Job %s\n%02d:%02d-%02d:%02d ", 
		line_u, where_s, day_in_week_s, time_in_day_s,
		job_description,
		start_hour, start_minute, stop_hour, stop_minute);
	printf("something strange with numbers, ");
	(void) scanf("%*s\n") ;
	printf("try again.\n");
	(void) fflush(stdout);
	/* I used to allow a return, as this used to take interactive input,
	   but I havent done that for years now, it only ever
	   processes a log, so just exit, else it often loops forever
	   */
	exit(1);
	}
