/* $VER: EZCrond by Jim Hines v2.00 1995-1997 All Rights Reserved
** Thanks must go to Gene Heskett for his help in coding some functions.
*/

	csi='9b'x
	Ital=csi'3m'
	bold=csi'1m'
	norm=csi'0m'
	black=csi'31m'
	white=csi'32m'
	blue=csi'33m'
	LF = '0a'x
	
/* ========END VARABLES == */

	arg command .

	if ~show('L','rexxsupport.library') then
		call addlib('rexxsupport.library',0,-30)

	if exists('s:cron.config') then address command 'copy s:cron.config t:'
	else do
		call rtezrequest('A config file does NOT exist.'||LF||'Use EZCronPrefs to create one.', "Okay",'EZCron Error',)
		exit
	end

	if command = 'START' then call startrtn()
	if command = 'STOP' | command = 'QUIT' then call stoprtn()
	if command ~= 'START' | command ~= 'STOP' | command ~= 'QUIT' then do
		say ''
		say 'ERROR: Unknown option' command
		exit
	end

stoprtn:
	if command = "STOP" then do
		if showlist('P', 'EZCROND') then do
			say 'Exiting EZCron... This may take several seconds.'
			address 'EZCROND' STOP
			exit
		end
	end
	else
		say 'EZCron is not running.'
		exit
	end

	/* =======LOOP== */
startrtn:
	RC = showlist('P', 'EZCROND')
	if RC = 1 then do
		say 'EZCron is Already Running.'
		exit
	end
    drop rc

	openport('EZCROND')

	/* =======Look for EZCronPrefs and signal. ==*/
	if showlist('P', 'EZCRONPREFS') then do
		call delay(50)
		address "EZCRONPREFS" refresh
	end

	SIGNAL on HALT

	/* =======PARSE CONFIG FILE & TIMER SECTION == */
	do forever
        sec = right(time('N'),2)   /* get seconds */
		sec2 = 60 - sec        /* 60 (seconds) minus sec) */
		delayvar = sec2 * 50   /* sec2 x 50 ticks or 1 second sets the delay time */
		LT = delayvar / 50
		LTime = 60 - LT
		call delay(delayvar)    /* 3000 would be equal to 1 minute */

		pkt = getpkt('EZCROND')
		if pkt ~= '0000 0000'x then call aport(pkt)

		clock = time('N')				/* 22:58:00 */
		clock2 = LEFT(clock,5)			/* 22:58 */
		date = Date(USA)               /*   08/04/92  */
		date2 = Date(S)                /*   19920804  */
		date3 = Date(W, date2, 'S')    /*   Friday    */

		event. = 0

		if ~open(cronfile,'t:cron.config','READ') then do
			exit 20
		end

		errors = 0

		do until eof(cronfile)
			/* Grab the line, parse the event and ignore the comments */
			linein = readln(cronfile)
			parse var linein line ';'
			parse var line line '!'
			next = event.0 + 1

	        parse var line event.next.command','event.next.pargs','event.next.time',',
			event.next.date','event.next.startdate','event.next.enddate',',
			event.next.rng1','event.next.rng2','event.next.sfx','event.next.txt',',

			event.next.date = translate(event.next.date, 'abcdefghijklmnopqrstuvwxyz',,
							'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
							/* TRANSLATES THE DATE TO LOWERCASE IF NOT NUMERIC */
			event.next.time = translate(event.next.time, 'abcdefghijklmnopqrstuvwxyz',,
							'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
							/* TRANSLATES THE TIME TO LOWERCASE IF NOT NUMERIC */
			select
				when event.next.command = "" then iterate
				when event.next.command = "" then do
					errors =  1
					iterate
				end
			otherwise event.0 = next
			end
		end  /* end of the eof loop */
		call close(cronfile)

	/* ======== END OF PARSE SECTION == */

		do i = 1 to event.0
			parse var clock2 ahrs ':' amin   		/* Actual Hrs and Mins */
			parse var event.i.time ehrs':'emin  	/* Event Hrs and Mins */
			parse var date amm'/'add'/'ayy			/* Actual mm dd yy */
			parse var event.i.date emm'/'edd'/'eyy  /* Event mm dd yy */
			parse var event.i.startdate sdmm'/'sddd'/'sdyy  /* Event Startdate mm dd yy */
			parse var event.i.enddate edmm'/'eddd'/'edyy  /* Event Enddate mm dd yy */

	/* ======= Arguments Routine == */
			if event.i.pargs = '-' then event.i.pargs = ''

	/* ======= Misc Routines == */
			if event.i.sfx = '-' then event.i.sfx = ''
			if event.i.txt = '-' then event.i.txt = ''

	/* ======= Every Minute Routine == */
			if event.i.time = 'minute' then event.i.time = clock2

	/* ======= Every Five Minute Routine ==  */
			if event.i.time = 'five_min' then do
				fiveresult = amin / 5
				parse var fiveresult intmin '.' decsec
			end
			if decsec = '' then event.i.time = clock2
			drop fiveresult intmin decsec

	/* ======= Every Ten Minute Routine ==  */
			if event.i.time = 'ten_min' then do
				tenresult = amin / 10
				parse var tenresult intmin '.' decsec
			end
			if decsec = '' then event.i.time = clock2
			drop tenresult intmin decsec

	/* ======= Quarterly Routine == */
			if event.i.time = 'quarterly' then do
				qresult = amin / 15
				parse var qresult intmin '.' decsec
			end
			if decsec = '' then event.i.time = clock2
			drop qresult intmin decsec

	/* ======= Every Thirty Minute Routine ==  */
			if event.i.time = 'thirty_min' then do
				if amin = '00' | amin = '30' then event.i.time = clock2
			end

	/* ======= Every Hour Routine == */
			if amin = 00 & event.i.time = 'hourly' then event.i.time = clock2

	/* ======= Daily Routine == */
			if event.i.date = 'daily' then event.i.date = date

	/* ======= Weekly Routine == */

			if event.i.date = 'sunday' & date3 = 'Sunday' then event.i.date = date
			if event.i.date = 'monday' & date3 = 'Monday' then event.i.date = date
			if event.i.date = 'tuesday' & date3 = 'Tuesday' then event.i.date = date
			if event.i.date = 'wednesday' & date3 = 'Wednesday' then event.i.date = date
			if event.i.date = 'thursday' & date3 = 'Thursday' then event.i.date = date
			if event.i.date = 'friday' & date3 = 'Friday' then event.i.date = date
			if event.i.date = 'saturday' & date3 = 'Saturday' then event.i.date = date

	/* ======= Weekdays Routine == The 'ol Mon-Fri routine */
			if event.i.date = 'weekdays' & date3 ~= 'Sunday' & date3 ~= 'Saturday'
				then event.i.date = date

	/* ======= Weekend Routine == The ol' Sat & Sun routine */
			if event.i.date = 'weekends' & date3 = 'Saturday' then event.i.date = date
			if event.i.date = 'weekends' & date3 = 'Sunday' then event.i.date = date

	/* ======= Monthly Routine == */
			month.event = event.i.date
			parse var month.event mth '-' day2
			if mth = 'monthly' then do
				parse var date month '/' day '/' year
				if day2 = day & event.i.time = clock2 then event.i.date = date
			end

	/* =======  4th Fri, 2nd Tue, etc routine == */

 			parse var event.i.date var1 '_' num '_' dow  /* every 2 wed */
			if var1 = 'every' then do
				del3 = date(n)   /* 20 Apr 88 */
				parse var del3 del1 cm del2
				drop del1 del2 /* dont even need them */

				if cm = 'Jan' then cm = 31;if cm = 'Feb' then cm = 28 /* This is for 1996. Will need to be changed to 28 after Feb 29. */
				if cm = 'Mar' then cm = 31;if cm = 'Apr' then cm = 30
				if cm = 'May' then cm = 31;if cm = 'Jun' then cm = 30
				if cm = 'Jul' then cm = 31;if cm = 'Aug' then cm = 31
				if cm = 'Sep' then cm = 30;if cm = 'Oct' then cm = 31
				if cm = 'Nov' then cm = 30;if cm = 'Dec' then cm = 31
				countvar = 0

				do z = 1 to cm
					currdate = date(s)				/* 19951221 year month day 	*/
					yearmonth = left(currdate, 6)	/* 199512 	year month		*/

					if z < 10 then do
						zdate = yearmonth'0'z   /* 19951201 */
						newz = '0'z
					end
					else do
						zdate = yearmonth''z   /* 19951231 */
						newz = z
					end

					myday = Date(W, zdate, 'S')   /* Friday   */
					myday = left(myday, 3)         /* Fri 		*/
					myday = translate(myday, 'abcdefghijklmnopqrstuvwxyz',,
									'ABCDEFGHIJKLMNOPQRSTUVWXYZ') /* fri */

					if myday = dow then countvar = countvar + 1
					if myday = dow & countvar = num then do
						year = left(zdate, 4) 			/* 1995 	*/
						year2 = right(year, 2) 			/*   95 	*/
						month = right(zdate, 4)			/*     1221 */
						month2 = left(month, 2) 		/*	   12	*/
						event.i.date = month2'/'newz'/'year2
						leave
					end
				end
			end


	/* ======= Special Time/Date Routine AF == */

			if ehrs = '##' | emin = '##' & event.i.time ~= void_event then do
				if ehrs = '##' then event.i.time = ahrs':'emin
				if emin = '##' then event.i.time = ehrs':'amin
				if emin = '##' & ehrs = '##' then event.i.time = clock2
			end

			if emm = '##' | edd = '##' | eyy = '##' then do
				if emm = '##' then event.i.date = amm'/'edd'/'eyy
				if edd = '##' then event.i.date = emm'/'add'/'eyy
				if eyy = '##' then event.i.date = emm'/'edd'/'ayy
				if edd = '##' & emm = '##' then event.i.date = amm'/'add'/'eyy
				if emm = '##' & eyy = '##' then event.i.date = amm'/'edd'/'ayy
				if edd = '##' & eyy = '##' then event.i.date = emm'/'add'/'ayy
				if emm = '##' & edd = '##' & eyy = '##' then event.i.date = date
			end

	/* ======= Time Range routine == */
			if event.i.rng1 ~= '--:--' & event.i.rng2 ~= '--:--' then do
				strng = event.i.rng1
				parse var strng sthrs':'stmin
				strngdrop = 60 * sthrs
				strng = strngdrop + stmin
				endrng = event.i.rng2
				parse var endrng edhrs':'edmin
				edrngdrop = 60 * edhrs
				edrng = edrngdrop + edmin
				currtim = time(m) /* current time in minutes since midnight */
				if currtim >= strng then a = 1
				if currtim <= edrng then b = 1
				if a = 1 & b = 1 then runit = 1
				if runit ~= 1 then event.i.time = void_event
				drop strng edrng currtim a b runit
			end

	/* ======= Date Range Routine == */

			if event.i.startdate ~= '--/--/--' & event.i.enddate ~= '--/--/--' then do
							
				if pos('##', event.i.startdate, 1) > 0 | pos('##', event.i.enddate, 1) > 0 then do
					/* Start Range */
					if sdmm = '##' then event.i.startdate = amm'/'sddd'/'sdyy
					if sddd = '##' then event.i.startdate = sdmm'/'add'/'sdyy
					if sdyy = '##' then event.i.startdate = sdmm'/'sddd'/'ayy
					if sddd = '##' & sdmm = '##' then event.i.startdate = amm'/'add'/'sdyy
					if sdmm = '##' & sdyy = '##' then event.i.startdate = amm'/'sddd'/'ayy
					if sddd = '##' & sdyy = '##' then event.i.startdate = sdmm'/'add'/'ayy
					if sdmm = '##' & edd = '##' & sdyy = '##' then event.i.startdate = date

					/* End Range */
					if edmm = '##' then event.i.enddate = amm'/'eddd'/'edyy
					if eddd = '##' then event.i.enddate = edmm'/'add'/'edyy
					if edyy = '##' then event.i.enddate = edmm'/'eddd'/'ayy
					if eddd = '##' & edmm = '##' then event.i.enddate = amm'/'add'/'edyy
					if edmm = '##' & edyy = '##' then event.i.enddate = amm'/'eddd'/'ayy
					if eddd = '##' & edyy = '##' then event.i.enddate = edmm'/'add'/'ayy
					if edmm = '##' & edd = '##' & edyy = '##' then event.i.enddate = date
					SAY 'ENDING TRACE'
				end

				a = b = 0
				sd = event.i.startdate
				edt = event.i.enddate
				parse var sd tmm'/'tdd'/'tyy
				sd = date(c,'19'tyy''tmm''tdd,s)
				parse var edt tmm'/'tdd'/'tyy
				edt = date(c,'19'tyy''tmm''tdd,s)
				currdt = date(usa)
				parse var currdt tmm'/'tdd'/'tyy
				currdt = date(c,'19'tyy''tmm''tdd,s)
				if currdt < sd then a = 1
				if currdt > edt then b = 1
				if a = 1 | b = 1 then event.i.date = void_event
				drop sd edt currdt tmm tdd tyy a b
			end
	
	/* ======= Final Routine == */

	       	if event.i.time = clock2 & event.i.date = date then
				address command 'run >NIL:' event.i.command event.i.pargs

			if event.i.time = clock2 & event.i.date = date & event.i.sfx ~= '' then do
				if exists('EZCron:prefs/sfx.prefs') then do
					open(sfxconfig, 'EZCron:prefs/sfx.prefs', 'r')
					sfxplayer = readln(sfxconfig)
					close(sfxconfig)
					address command 'run >nil:' sfxplayer event.i.sfx
				end
			end
			if event.i.time = clock2 & event.i.date = date & event.i.txt ~= "" then do
				address command 'run >nil: rx >nil: ezcron:rexx/Reminder.rexx' event.i.txt /*This calls the external rexx proggy for the event display */
				if showlist(h,SPEAK) then do
					address command 'echo' '"'event.i.txt'"' '>speak:'
				end
			end
			if event.i.time = clock2 & event.i.date = date
			then event.i.date = 'Finished with Event'
		end   	/* end of 'do i = 1 to event.0' */
	end		 	/* end of do forever */

/* ======== CLEANUP == */
	if event.0 = 0 then exit
	options failat 300

/* ======== Arexx Port Message Check == */
aport:
	Cmd = getarg(Pkt)
	if Cmd = 'STOP' then do
        call reply(Pkt, 0)
		call closeport('EZCROND')
		if showlist(P, 'EZCRONPREFS') then address 'EZCRONPREFS' refresh
		exit
	end
