/* ACron by Jim Hines and some needed advice from Gene Heskett 
** 10-23-95 Added requester to verify making a NEW cron.config file. See newrtn:
** 10-25-95 Fixed Bug in the above and added renaming of the old config file. See newrtn:
** 11-30-95 added the text string reminder support and the sfx functions
** This does NOT HAVE SPEECH SUPPORT INCLUDED WITHIN IT. See EZCron for details to add it
*/

/* call trace(all) */


/* ======== Envirorment Varables == */
	clock = time('N')
	clock2 = LEFT(clock,5)
	date = Date(USA)
	date2 = Date(S)             /*     -> 19920804  */
	date3 = Date(W, date2, 'S')  /*    -> Friday  */
	sec = right(clock, 2)  /* Get Seconds */
	sec2 = 60 - sec        /* 61 (seconds) minus sec) */
	delayvar = sec2 * 50   /* sec2 x 50 ticks or 1 second sets the delay time */
	LT = delayvar / 50
	LTime = 60 - LT

/* ======== CHARACTOR TYPE VARABLES == */
	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 lg .

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

/* ======== THIS IS THE INPUT PARSING / USAGE SECTION WITH A SUB-ROUTINE== */

	select
		when command = "ADD" then do
			call addrtn()
		end
		when command = 'START' then do
			call startrtn()
		end
		when command = "STOP" then do
			call stoprtn()
		end
		when command = "QUIT" then do
			command = "STOP"
			call stoprtn()
		end
		when command = "NEW" then do
			call newrtn()
		end
		when command = "DOC" then do
			call docrtn()
			exit
		end
		when command = "LIST" then do
			call listrtn()
		end
		when command = '' then do
			call nulinp()
		end
		otherwise
			say ''
			say bold'ERROR,'norm 'Unknown option'blue command norm
			call nulinp()
		end
	end
	
nulinp:
	say ' '
	say white'	Usage: rx ACron [option] [LOG]' norm
	say ''
	say blue'	[NEW]'norm'   This creates a new blank config file in your s:'
	say ' 		directory. YOU MUST DO THIS FIRST IF YOU''VE'
        say '                NEVER RUN IT BEFORE'
        say '                (If you already have one this WILL delete it!!)'
	say ''
	say blue'	[ADD]'norm '  This will allow you to set up your config'
	say ' 		file interactivatly.'
	say ''
	say blue'      [START]'norm '  This runs it. You must create a config'
	say ' 		file first using the NEW command option.' norm
	say ''
	say blue'       [STOP]'norm '  Just like it says. If its running, this kills it.'
	say ''
	say blue'        [DOC]'norm'   Short Docs'
	say ''
	say blue'       [LIST]'norm'   This will list the events in s:cron.config'
	say ''
	say blue'        [LOG]'norm'   If specified, This will log events in s:cronlog'
	say ''
exit

newrtn:
	if command = "NEW" then do
		if ~exists('s:cron.config') then do
					open(MkCfg, 's:cron.config',W)
					say ''
					say 'OKay, a blank cron.config file has been created in your s: directory'
					say ''
					close(MkCfg)
		exit
		end
	else
		rtezrequest("A cron.config file already exists."||LF||"Do you wish to overwrite it?.", "_Yes|_No", , "rt_reqpos = reqpos_centerscr")
		if rtresult == 1 then do
			say ''
			say 'Renaming your cron.config file to cron.config.old'
			address command 'c:rename s:cron.config s:cron.config.old'
			call delay(3)
			open(MkCfg, 's:cron.config',W)				
			say ''
			say 'Your cron.config file has been overwritten with a new empty file. Use 'rx acron add' to add new events.'
			say ''
		exit
		end

		if rtresult == 0 then do
			say "Operation Cancelled"
		exit
		end


stoprtn:
	if command = "STOP" then do
		if showlist('P', 'ACRON_REXX') then do
		say ital 'Exiting ACron: Please Wait. Program will exit in' LT 'seconds!' norm
		address 'ACRON_REXX' STOP
		exit
		end
		else
		say bold ital 'ACron is not running.' norm
	exit
	end

ADDRTN:
	if command  = "ADD" then do
		filename = rtfilerequest(, , "Pick a File To Run",OK, "rt_reqpos = reqpos_centerscr")
		if rtresult == 0 then do
			say 'ACron ADD operation aborted!'
		exit
		end
		else
		rtezrequest( "Do You Wish To Add Program Arguments?.", "_Yes|_No", , "rt_reqpos = reqpos_centerscr")

		if rtresult == 1 then
			pargs = rtgetstring("- - - -","Enter Program Arguments", "Arguments Requester", ,"rt_reqpos = reqpos_centerscr")
		if rtresult == 0 then pargs = "- - - -"

		STime = rtgetstring(clock2,'Enter the Time You Wish in Existing Format' , "Enter Start Time:", , "rt_reqpos = reqpos_centerscr")
		if rtresult == 0 then do
			say 'ACron ADD operation aborted!'
		exit
		end

		SDate = rtgetstring(date,'Enter the Date You Wish in Existing Format' , "Enter Start Data:", , "rt_reqpos = reqpos_centerscr")
		if rtresult == 0 then do
			say 'ACron ADD operation aborted!'
	 	exit
		end

		rtezrequest( "Do You Wish To Add A Sound Sample?.", "_Yes|_No", , "rt_reqpos = reqpos_centerscr")
		if rtresult == 1 then
			seffect = rtfilerequest(, , "Pick a sound file",_OK, "rt_reqpos = reqpos_centerscr")
		if rtresult == 0 then seffect = '-'

		say 'Appending New Data to the Existing Config File.'
		open(dfile, 's:cron.config', 'a')
		writeln(dfile, filename pargs STime SDate seffect '-')
		close(dfile)

		say ''
		say 'THIS IS YOUR CURRENT CONFIG'
		say '==========================='
		address command 'c:type s:cron.config'
		say ''
		say "To run the Cron, Type 'rx ACron Start'"
	exit
	end

docrtn:
	if command = "DOC" then do
		say ''
		say 'This is pretty much straight forward. The First thing you need to do is'
		say 'type 'rx ACron new'. This sets up an empty config file in your s: dir.'
		say 'Once that is done, type 'rx ACron add' to add files to run to the list.'
		say ''
		say 'Follow the input format given with the requesters with the following'
		say 'exceptions: '
		say ''
		say 'ARGUMENTS REQUESTER'
		say '==================='
		say 'You may enter program arguments at this prompt. The requester will '
		say 'default to "- - - -" representing 4 arguments. If only 1 argument is'
		say 'entered, 3 of the dashes MUST remain. (ie. maxmem=400000 - - - ) and'
		say 'if two args are entered, 2 dashes must remain etc.'
		say ''
		say 'TIME REQUESTER'
		say '=============='
		say 'You may enter "Minute" in the time requester to run an event every minute.'
		say 'You may also enter "Hourly" to run the task every hour on the hour'
		say ''
		say 'DATE REQUESTER'
		say '=============='
		say 'You may enter "Daily" within the DATE requester to run every day at a'
		say 'given time.'
		say 'Yoy may enter a weekday (ie. Sunday, Monday) to run the program once a week'
		say 'at the given time and day.'
		say 'You may enter "Monthly-03" to run a task every month on the given day.'
		say 'In this case the third of every month.'
		say ''
		say 'These exceptions are CASE SENITIVE! (ie. Sunday must be "Sunday" minus the'
		say 'quotes).'
		say ''
		say 'Thats it. Enjoy!'
		say ''
		say 'ACRON by Jim Hines'
		say ''
	exit
	end


/* =======LOOP== */
startrtn:
	if ~exists('s:cron.config') then do
		say 'The s:cron.config file does not exist. Use "rx cron new" to create one'
		say 'Then use 'rx ACron add' to add your events.'
	exit
	end

	RC = showlist('P', 'ACRON_REXX')
	if RC = 1 then do
		say bold ital white 'ACron is Already Active' norm
	exit
	end

	openport('ACRON_REXX')
	SIGNAL on HALT

/* =======PARSE CONFIG FILE SECTION == */
	do forever
	config = 's:cron.config'		/* Name of file for reading events from */
	event. = 0

	if ~open(cronfile, 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 '#'
	
			next = event.0 + 1
		
	        parse var line event.next.command event.next.pargs1 event.next.pargs2,
			event.next.pargs3 event.next.pargs4 event.next.time	event.next.date,
			event.next.sfx event.next.txt

			event.next.date = translate(event.next.date, 'abcdefghijklmnopqrstuvwxyz',,
							'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
							/* THE ABOVE TRANSLATES THE DATE TO LOWERCASE IF NOT NUMERIC */

			event.next.time = translate(event.next.time, 'abcdefghijklmnopqrstuvwxyz',,
							'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
							/* THE ABOVE TRANSLATES THE TIME TO LOWERCASE IF NOT NUMERIC */
	
			select
				when event.next.command = "" then iterate
				when event.next.command = "" then do
					say "Not enough fields in:" linein
					errors =  1
					iterate
				end
				otherwise event.0 = next
			end
		end
		call close(cronfile)

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

		sec = right(clock, 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

/* ======== AREXX PORT STUFF == */
		pkt = getpkt('ACRON_REXX')
			if pkt ~= '0000 0000'x then do
				call aport(pkt)
			end

		say 'The Current Time & Date is:' bold clock2 date norm
		if lg = log then say 'LOG ENABLED'
		call delay(delayvar)    /* 3000 would be equal to 1 minute */
	
		DO i = 1 to event.0
			clock = time('N')
			clock2 = LEFT(clock,5)
			date = Date(USA)               /*  -> 08/04/92  */
			date2 = Date(S)                /*  -> 19920804  */
			date3 = Date(W, date2, 'S')    /*  -> Friday    */
	
	/* ======= Arguments Routine == */
			if event.i.pargs1 = '-' then
				event.i.pargs1 = ''
			if event.i.pargs2 = '-' then
				event.i.pargs2 = ''
			if event.i.pargs3 = '-' then
				event.i.pargs3 = ''
			if event.i.pargs4 = '-' then
				event.i.pargs4 = ''
	
	/* ======= 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 Hour Routine == */
			parse var clock2 hrs ':' min
			if min = 00 & event.i.time = 'Hourly' then event.i.time = clock2
	
	/* ======= Daily Routine == */
			if event.i.date = 'Daily'
				then event.i.date = date
	
	/* ======= Weekly Routine == */
	/* ======= Note that case IS significant */

			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
	
	/* ======= 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
	
	/* ======== Logging Routine == */
			if lg = log then do
		       	if event.i.time = clock2 & event.i.date = date then do
					if ~exists('s:cronlog') then do
						open(log, 's:cronlog', 'W')
					end
				else
					open(log, 's:cronlog', 'A')
					writeln(log, event.i.command "was executed at" event.i.time "on" event.i.date)
					close(log)
				end
			end
	
	/* ======= Final Routine == */
			if lg = log then delay(25) /* This delay is to allow for the log file
	        		                      to be deleted automatically if so desired */
	       	if event.i.time = clock2 & event.i.date = date then
			address command 'run >NIL:' event.i.command event.i.pargs1,
			event.i.pargs2 event.i.pargs3 event.i.pargs4
	
			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)
				end
				address command 'run >nil:' sfxplayer event.i.sfx
			end
	
			if event.i.time = clock2 & event.i.date = date & event.i.txt ~= "" then
			address command 'run >nil: rx >nil: ezcron:rexx/Reminder.rexx' event.i.txt
	
			if event.i.time = clock2 & event.i.date = date
			then event.i.date = 'Finished with Event'
	
			say LF ''
			say blue'======================================================' norm
			say bold 'UPCOMING EVENT:    ' norm white event.i.command norm
			say bold 'ARGUMENTS:         ' norm white event.i.pargs1 event.i.pargs2 event.i.pargs3 event.i.pargs4 norm
			say bold 'EVENT TIME:        ' norm white event.i.time norm
			say bold 'EVENT DATE:        ' norm white event.i.date norm
			say bold 'EVENT SOUND FX:    ' norm white event.i.sfx norm
			say bold 'EVENT REMINDER:    ' norm white event.i.txt norm
			say bold 'LOOP EVENT TIME:   ' norm white ltime 'seconds' norm
	
		end
	end

listrtn:
	address command 'c:type s:cron.config'
	if showlist('P', 'ACRON_REXX') then do
		say white ital'ACron is currently running' norm
	end
	else
	say white ital'ACron is NOT currently running.' norm
	exit
	end

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

/* ======== Arexx Port Message Check == */
aport:
	Cmd = getarg(Pkt)
	if Cmd = 'STOP' then do
        call reply(Pkt, rc)
	exit
	end
